停止子活动以返回父活动

时间:2012-02-09 18:02:43

标签: android surfaceview android-activity

我有一个Android活动正在启动子活动,该活动在surfaceview上运行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 个答案:

答案 0 :(得分:2)

您必须引用父活动,而不是仅调用finish();

即。 YourActivityClassName.this.finish();

会导致您的活动完成,请务必在DriveEvent.EVENT_APP_EXIT上添加此调用,并且您的活动应在Sygic退出后关闭