2012-02-09 84 views
0

我有一個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); 
    } 
} 
+0

後,你爲什麼不嘗試啓動父活動從您的活動應該關閉的時刻導航活動何時結束? Intent intent = new Intent(getActivity(),ParentActivity.class); – R4j 2012-02-09 18:11:47

+0

父活動已經在兒童活動下面運行,如果我開始在頂部,那麼它會運行兩次,這似乎不是一個好主意...... – Justin 2012-02-09 18:31:27

+0

@Justin您可以在啓動意圖時傳入FLAG_ACTIVITY_CLEAR_TOP獲取當前正在運行的Activity並將其帶到堆棧的前面。更多關於如何在這裏工作的細節:http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP – onit 2012-02-09 18:57:45

回答

2

您必須引用父活動,而不是隻調用finish();

YourActivityClassName.this.finish();

會導致您的活動來完成,確保添加在DriveEvent.EVENT_APP_EXIT此調用和Sygic已退出