0

I want to stop my WakefulService when I close a special Activity AND when I close the whole app. Therefore I wrote this into onDestroy() and in the function which is called in onBackPressed()

stopService(new Intent(getApplicationContext(), GcmIntentService.class));

But the service is still running. Can anyone help me?

Service:

<service android:name="com.flipflopdev.epvp_aj1987_chat.GcmIntentService" />

Phil
  • 583
  • 4
  • 7
  • 19
  • "when I close the whole app" -- there is no concept in Android of closing an app. "I want to stop my WakefulService" -- if your service is indeed an `IntentService`, as its name suggests, then it will only run long enough to process `onHandleIntent()` and then will stop on its own... unless you did something to prevent that. What is your evidence that the service is still running? – CommonsWare Jun 15 '14 at 16:39
  • `startWakefulService(context, (intent.setComponent(comp)));` It's WakefulIntentService of Google Cloud Messaging – Phil Jun 15 '14 at 16:41
  • Let me try again: what is your evidence that the service is still running? – CommonsWare Jun 15 '14 at 16:47
  • Ah sorry my fault, It's GCM and everytime when I send a message from my server I recieve notification through this service, so it is still running. – Phil Jun 15 '14 at 17:08
  • I will try one last time: what is your **evidence** that the service is still **running**? GCM messages are delivered to a `BroadcastReceiver`. That `BroadcastReceiver` will respond to such broadcasts until you disable that component. If you have that `BroadcastReceiver` delegate work to an `IntentService`, that `IntentService` will run until `onHandleIntent()` returns. Hence, the fact that your `IntentService` still does work in response to GCM messages does not mean that the `IntentService` is continually running. – CommonsWare Jun 15 '14 at 17:12
  • Okay now I understood. Sorry again. So I need to stop the BroadcastReceiver. – Phil Jun 15 '14 at 17:14

2 Answers2

1

If you want your app to stop responding to GCM messages, you will need to disable the BroadcastReceiver that is set up to receive the GCM broadcast. You can disable it via setComponentEnabledSetting() on PackageManager. Just remember that you will need to re-enable it again later to receive GCM messages again.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
0

You should wait for the task to finish, look here:

Proper way to stop IntentService

to make task abort, set some global variable (ie. in sharedpreferences) which will indicate that task should be cancelled/aborted. Then IntentService will close on its own. Another possibility is to implement Abort as a task:

// Pseudocode for example cancellable WakefulIntentService 
public class MyService extends WakefulIntentService {

    AtomicBoolean isCanceled = new AtomicBoolean(false);

    public static void cancelTasks(Context context) {
        Intent intent = new Intent(context, SynchronizationService.class);
        intent.putExtra("action", "cancel");
        context.startService(intent);
    }

    public MyService () {
        super("MyService");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent.hasExtra("action")) {
            // Set the canceling flag
            if ( intent.getStringExtra("action").equals("cancel") ) {
                isCanceled.set(true);
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

@Override
    protected void doWakefulWork(Intent intent) {
        // Clean up the possible queue
        if (intent.hasExtra("action")) {
            boolean cancel = intent.getStringExtra("action").equals("cancel");
            if (cancel) {
                return;
            }
        }

        // here do some job
        while ( true ) {
          /// do some job in iterations

          // check if service was cancelled/aborted
          if ( isCanceled.get() )
             break;
        }

    }
}

and if you want to abort your service, you call:

MyService.cancelTasks(getActivity());

You could put all this cancelling code into base class to make it look more clean.

Community
  • 1
  • 1
marcinj
  • 48,511
  • 9
  • 79
  • 100
  • IMHO, `IntentService` is not designed for `while(true)` scenarios. `WakefulIntentService` is very much not designed for `while(true)` scenarios. In either case, roll your own service, one that has a threading model that fits your needs (and its own `WakeLock` as needed). – CommonsWare Jun 15 '14 at 16:46
  • This is an example, `do some job in iterations` should call break once job is finished. Job should be short, otherwise regular service will be better. – marcinj Jun 15 '14 at 16:53