3

Ok so I've built an app that uses a remote service to do some real time GPS tracking. I am using the below code to start and bind to the service.

The remote service uses aidl, sets up a notification icon, runs the GPS and locationListener. In onLocationChanged, a handler sends data back to the caller via the callback. Pretty much straight out of the examples and resources online.

I want to allow the service to continue running even if the app closes. When the app is restarted, I want the app to again bind to the service (using the existing service if running) and again receive data from the tracker.

I currently have the app mode set to singleTask and cannot use singleinstance due to another issue.

My problem is that quit often even after the app and service are shut down either from the app itself, or from AdvancedTaskKiller, or a Forceclose, the service will restart and initialize the GPS. touching on the notification will open the app. I again stop the tracking which removes the notification and turns off the GPS Close the app, and again after a few seconds the service restarts. The only way to stop it is to power off the phone.

What can I do to stop this from happening. Does it have to do with the mode of operation? START_NOT_STICKY or START_REDELIVER_INTENT? Or do I need to use stopSelf()?

My understanding is that if the service is not running when I use bindService() that the service will be created...so do I really need to use start/stopService also? I thought I would need to use it if I want the service to run even after the app is closed. That is why i do not unbind/stop the service in onDestroy(). Is this correct?

I've not seen any other info an this, so I,m not sure where to look.

Please Help! Thanks Patrick

 //Remote Service Startup       
 try{
startService();    
 }catch (Exception e) {
Toast.makeText(ctx, e.getMessage().toString(), Toast.LENGTH_SHORT).show();                      }
 }

try{
bindService();     
}catch (Exception e) {
Toast.makeText(ctx, e.getMessage().toString(), Toast.LENGTH_SHORT).show();
}

//Remote service shutdown           
 try {
      unbindService();
 }catch(Exception e) {
     Toast.makeText(ctx, e.getMessage().toString(), Toast.LENGTH_SHORT).show();
 }
 try{
stopService();
 }catch(Exception e) {
Toast.makeText(ctx, e.getMessage().toString(), Toast.LENGTH_SHORT).show();
 }


private void startService() {
  if( myAdapter.trackServiceStarted() ) {
    if(SETTING_DEBUG_MODE)
      Toast.makeText(this, "Service already started", Toast.LENGTH_SHORT).show();

      started = true;
      if(!myAdapter.trackDataExists())
          insertTrackData();

      updateServiceStatus();
  } else {
         startService( new Intent ( "com.codebase.TRACKING_SERVICE" )  );

    Log.d( "startService()", "startService()" );
    started = true;


    updateServiceStatus();
  }
}

  private void stopService() {

    stopService( new Intent ( "com.codebase.TRACKING_SERVICE" )  );
      Log.d( "stopService()", "stopService()" );
      started = false;
      updateServiceStatus();

  }
  private void bindService() {
  bindService(new Intent(ITrackingService.class.getName()),
          mConnection, Context.BIND_AUTO_CREATE);

  bindService(new Intent(ITrackingSecondary.class.getName()),
           mTrackingSecondaryConnection, Context.BIND_AUTO_CREATE);


    started = true;



  }

  private void unbindService() {

  try {
      mTrackingService.unregisterCallback(mCallback);
  } catch (RemoteException e) {
      // There is nothing special we need to do if the service
      // has crashed.
      e.getMessage();
  }

  try {
      unbindService(mTrackingSecondaryConnection);
      unbindService(mConnection);
  } catch (Exception e) {
      // There is nothing special we need to do if the service
      // has crashed.
      e.getMessage();
  }


    started = false;


  }


   private ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {

        // This is called when the connection with the service has been
        // established, giving us the service object we can use to
        // interact with the service.  We are communicating with our
        // service through an IDL interface, so get a client-side
        // representation of that from the raw service object.
        mTrackingService = ITrackingService.Stub.asInterface(service);


        // We want to monitor the service for as long as we are
        // connected to it.
        try {
            mTrackingService.registerCallback(mCallback);
        } catch (RemoteException e) {
            // In this case the service has crashed before we could even
            // do anything with it; we can count on soon being
            // disconnected (and then reconnected if it can be restarted)
            // so there is no need to do anything here.
        }

    }

    public void onServiceDisconnected(ComponentName className) {
        // This is called when the connection with the service has been
        // unexpectedly disconnected -- that is, its process crashed.
        mTrackingService = null;

    }
  };


  private ServiceConnection mTrackingSecondaryConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className,
            IBinder service) {
        // Connecting to a secondary interface is the same as any
        // other interface.
        mTrackingSecondaryService = ITrackingSecondary.Stub.asInterface(service);

        try{
        mTrackingSecondaryService.setTimePrecision(SETTING_TIME_PRECISION);
        mTrackingSecondaryService.setDistancePrecision(SETTING_DISTANCE_PRECISION);
        } catch (RemoteException e) {
            // In this case the service has crashed before we could even
            // do anything with it; we can count on soon being
            // disconnected (and then reconnected if it can be restarted)
            // so there is no need to do anything here.
        }
    }

    public void onServiceDisconnected(ComponentName className) {
        mTrackingSecondaryService = null;

    }
   };

    //TrackService onDestry()
public void onDestroy() {


try{
  if(lm != null) {
    lm.removeUpdates(this);
  }
  if(mNotificationManager != null) {
    mNotificationManager.cancel(R.string.local_service_started);
  }
  Toast.makeText(this, "Service stopped", Toast.LENGTH_SHORT).show();
}catch (Exception e){
    Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}

    // Unregister all callbacks.
    mCallbacks.kill();


    // Remove the next pending message to increment the counter, stopping
    // the increment loop.
    mHandler.removeMessages(REPORT_MSG);


  super.onDestroy();
}

ServiceConnectionLeaked: I'm seeing a lot of these:

04-21 09:25:23.347: ERROR/ActivityThread(3246): Activity com.codebase.GPSTest has leaked ServiceConnection com.codebase.GPSTest$6@4482d428 that was originally bound here
 04-21 09:25:23.347: ERROR/ActivityThread(3246): android.app.ServiceConnectionLeaked: Activity com.codebase.GPSTest has leaked ServiceConnection com.codebase.GPSTest$6@4482d428 that was originally bound here
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.app.ActivityThread$PackageInfo$ServiceDispatcher.<init>(ActivityThread.java:977)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.app.ActivityThread$PackageInfo.getServiceDispatcher(ActivityThread.java:872)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.app.ApplicationContext.bindService(ApplicationContext.java:796)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.content.ContextWrapper.bindService(ContextWrapper.java:337)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at com.codebase.GPSTest.bindService(GPSTest.java:2206)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at com.codebase.GPSTest.onStartStopClick(GPSTest.java:1589)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at com.codebase.GPSTest.onResume(GPSTest.java:1210)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1149)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.app.Activity.performResume(Activity.java:3763)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2937)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2965)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2516)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3625)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.app.ActivityThread.access$2300(ActivityThread.java:119)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1867)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.os.Handler.dispatchMessage(Handler.java:99)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.os.Looper.loop(Looper.java:123)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at android.app.ActivityThread.main(ActivityThread.java:4363)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at java.lang.reflect.Method.invokeNative(Native Method)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at java.lang.reflect.Method.invoke(Method.java:521)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
 04-21 09:25:23.347: ERROR/ActivityThread(3246):     at dalvik.system.NativeStart.main(Native Method)

And These: Is this ok, or do I need to make sure i deactivate/close

     04-21 09:58:55.487: INFO/dalvikvm(3440): Uncaught exception thrown by finalizer (will be discarded):
 04-21 09:58:55.487: INFO/dalvikvm(3440): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@447ef258 on gps_data that has not been deactivated or closed
 04-21 09:58:55.487: INFO/dalvikvm(3440):     at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
 04-21 09:58:55.487: INFO/dalvikvm(3440):     at dalvik.system.NativeStart.run(Native Method)
bugzy
  • 6,946
  • 9
  • 40
  • 44
  • Is there anything "interesting" in the logcat output at the point of the restart? – fadden Apr 20 '10 at 21:28
  • Unfortunately I do do not have any logcat output yet. I can't get it to happen in the emulator, and have not had it happen on my device while usb debuging. I will try to see if I can get anything today. – bugzy Apr 21 '10 at 12:07
  • Ok, well I guess no one else has seen this. Or maybe no one wants to read this whole long question. Or maybe its my lack of understanding of the API. Anyway I decided to run it as a LocalService. See if that works any better. At least until I can work this out. – bugzy Apr 23 '10 at 17:14
  • check this solution :D [broadcastreceiver-auto-run-service-after-reboot-of-device](http://stackoverflow.com/questions/14385231/android-broadcastreceiver-auto-run-service-after-reboot-of-device) – rChavz Nov 12 '14 at 00:23

0 Answers0