Остановка дочерней активности для возврата к родительской активности - PullRequest
0 голосов
/ 09 февраля 2012

У меня есть операция Android, которая запускает дочернюю операцию, которая запускает навигацию Sygic в виде поверхности.

Запуск дочерней активности работает отлично, навигация запускается. Однако когда они выходят из приложения Sygic, я хочу закрыть дочернее действие и вернуться к отображению родительского действия. Как вы можете видеть, в методе Finish () я попытался вызвать оба this.finish (); и getParent (). finish (); однако ни один не работает. Все, что он делает, это показывает черный экран, который, я предполагаю, является видом поверхности. Любые идеи, как я могу заставить его успешно закрыть дочернее действие и снова показать родительское действие?

Вот код для запуска дочерней активности:

NavigationActivity.SygicModule = this;
        Log("Creating intent for navigation activity");
        Intent intent = new Intent(getActivity(), NavigationActivity.class);
        Log("Starting navigation activity");
        getActivity().startActivity(intent);

Вот XML-код для дочернего вида навигационной активности:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/layout">
    <SurfaceView android:id="@+id/surfaceView" android:layout_height="match_parent" android:layout_width="match_parent"></SurfaceView>
</LinearLayout>

А вот код для дочерней навигационной активности:

package ti.sygic;

public class NavigationActivity extends SygicDriveActivity {

    private static final String LCAT = "SygicModule";
    private static SError error = new SError();
    private static Activity currentActivity = null;
    public static SygicModule SygicModule;

    private Handler mHandler = new Handler();

    /** Called when the activity is first created. */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        currentActivity = this;
        super.onCreate(savedInstanceState);
        try {
            setContentView(TiRHelper.getApplicationResource("layout.sygicmain"));
            final ApiCallback apicallback = new ApiCallback() {
                public void onRunDrive() {
                    try {
                        final SurfaceView surface = (SurfaceView) findViewById(TiRHelper.getApplicationResource("id.surfaceView"));

                        mHandler.post(new Runnable() {
                            public void run() {
                                runDrive(surface, getPackageName()); // starts the drive app
                            }
                        });
                    } catch (ResourceNotFoundException e) {
                        // TODO Auto-generated catch block
                        Log("Failed to find id.surfaceView!");
                        e.printStackTrace();
                    } // surface

                }

                public void onInitApi() // gets called after runDrive();
                {
                    // code to make sure that gps is enabled before initializing
                    Log("Checking that gps is enabled");
                    String provider = "com.android.settings.widget.SettingsAppWidgetProvider";
                    Criteria criteria = new Criteria();
                    criteria.setAccuracy(Criteria.NO_REQUIREMENT);
                    criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
                    criteria.setCostAllowed(false);
                    ContentResolver contentResolver = getContentResolver();

                    if (!Settings.Secure.isLocationProviderEnabled(contentResolver, LocationManager.GPS_PROVIDER)) {
                        Log("Gps is not enabled, showing gps settings");
                        final Intent poke = new Intent();
                        poke.setClassName("com.android.settings", provider);
                        poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
                        poke.setData(Uri.parse("3"));
                        sendBroadcast(poke);
                    }

                    int status = ApplicationAPI.InitApi(getPackageName(), true, msgHandler); // api initialization
                    Log("Status = " + Integer.toString(status));

                    if (status != 1) {
                        Log("InitApi failed! " + status);
                    }
                    else {
                        //start checking every second if application is running. if it isn't then finish this and parent activities.
                        //note: we wouldn't have to do this if APP_EXIT event actually fired. :(
                        CheckIfRunning();
                    }
                }
            };

            ApplicationAPI.startDrive(apicallback);

        } catch (ResourceNotFoundException e1) {
            Log("Failed to find resource!");
            e1.printStackTrace();
        }
    }

    public static void navigateTo(Float latitude, Float longitude) {
        try
        {
            Log("navigateTo: " + latitude + " / " + longitude);

            Integer lat = (int)(latitude * 100000);
            Integer lon = (int)(longitude * 100000);

            //start navigation.
            Log("Starting navigation for " + lat + " / " + lon);
            SWayPoint wayPoint = new SWayPoint();
            wayPoint.SetLocation(lat, lon);
            ApplicationAPI.StartNavigation(error, wayPoint, 0, true, true, 0);//NavigationParams.NpMessageAvoidTollRoadsUnable
            Log("Start navigation result: " + error.nCode + " " + error.GetDescription());

            //if waiting for gps, call in a bit.
            if(error.nCode == -6)
            {
                Thread.sleep(5000);
                navigateTo(latitude, longitude);
            }
        }
        catch(Exception exc)
        {
            Log(exc.getMessage());
        }
    }

    final ApplicationHandler msgHandler = new ApplicationHandler() {
        @Override
        public void onApplicationEvent(int nEvent, String strData) {
            Log("Event No. " + Integer.toString(nEvent) + " detected."); // event handling
            switch (nEvent) {
                case ApplicationEvents.EVENT_APP_EXIT:
                    Log("In EVENT_APP_EXIT event");
                    Finish();
                    break;
                case ApplicationEvents.EVENT_WAIPOINT_VISITED:
                    Log("Waypoint visited.");
                    break;
                case ApplicationEvents.EVENT_ROUTE_COMPUTED:
                    Log("Route computed.");
                    break;
                case ApplicationEvents.EVENT_ROUTE_FINISH:
                    Log("Route finished.");
                    break;
                case ApplicationEvents.EVENT_POI_WARNING:
                    Log("Poi warning!.");
                    break;
                case ApplicationEvents.EVENT_CHANGE_LANGUAGE:
                    Log("Language changed.");
                    break;
                case ApplicationEvents.EVENT_EXIT_MENU:
                    Log("Menu exited.");
                    break;
                case ApplicationEvents.EVENT_MAIN_MENU:
                    Log("Entering main menu.");
                    break;
                case ApplicationEvents.EVENT_BORDER_CROSSING:
                    Log("Crossing border.");
            }
        }
    };

    private void CheckIfRunning()
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try
                {
                    int numTimesNotRunning = 0;
                    while(true)
                    {
                        boolean isRunning = ApplicationAPI.IsApplicationRunning(error, 0) == 1;
                        if(isRunning)
                        {
                            Log("App is running, will check again in 2 seconds");
                            numTimesNotRunning = 0;
                            Thread.sleep(2000);
                        }
                        else {
                            if(numTimesNotRunning < 3)
                            {
                                numTimesNotRunning++;
                                Log("App not running, num times " + numTimesNotRunning);
                                Thread.sleep(2000);
                            }
                            else
                                break;
                        }
                    }
                    Log("App is not running, calling sygicmodule finish!");
                    Finish();
                }
                catch(Exception exc)
                {
                    Log(exc.getMessage());
                }
            }
        }).start();
    }

    private void Finish()
    {
        Log("In NavigationActivity Finish");
        runOnUiThread(new Runnable() {
            public void run() {
                try
                {
                    //launch parent activity.
                    Log("Starting parent activity");
                    Intent intent = new Intent(currentActivity, SygicModule.getActivity().getClass());
                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    currentActivity.startActivity(intent);
                    //finish current activity.
                    Log("Finishing activity");
                    //setContentView(null);
                    currentActivity.finish();
                }
                catch(Exception exc)
                {
                    Log(exc.getMessage());
                }
            }
        });
    }

    private static void Log(String message) {
        //org.appcelerator.kroll.common.Log.i(LCAT, message);
        if(message != null && message.length() > 0)
            android.util.Log.i(LCAT, message);
    }
}

1 Ответ

2 голосов
/ 18 октября 2012

Вы должны будете ссылаться на родительскую активность, а не просто звонить finish();

т.е. YourActivityClassName.this.finish();

Если ваша деятельность завершится, обязательно добавьте этот вызов на DriveEvent.EVENT_APP_EXIT, и ваша активность должна закрыться через несколько секунд после выхода из Sygic

...