Skip to content Skip to sidebar Skip to footer

Stopping A Background Service From Notification

I have a background service in which I want to show a notification which allows the user to stop it. In the android SDK docs it says an activity is used to normally launch an Activ

Solution 1:

So I am wondering if I need to create an activity to stop the service or can I directly stop the service when user selects the notification,

You cannot directly stop the service from a Notification. You can start the service, using an Intent that has an action string or extra or something that the service sees in onStartCommand() and triggers it to call stopSelf().

Solution 2:

The question is already old, but since there is still no solution with code, I simply share my code as an example for solving the problem:

You cannot directly stop the service from a Notification. You can start the service, using an Intent that has an action string or extra or something that the service sees in onStartCommand() and triggers it to call stopSelf().

That's the right solution so let's jump in code (this code is all in your ExampleService class):

@RequiresApi(Build.VERSION_CODES.O)privatevoidstartForegroundService() {
    // create PendingIntend to open MainActivity (this is when the notification gets clicked) //IntenttabIntent=newIntent(this, MainActivity.class);
    tabIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    PendingIntenttabPendingIntent= PendingIntent.getActivity(this, 0, tabIntent, 0);

    // create PendingIntend to open ExampleService (this is when the notification BUTTON gets clicked) //IntentcloseIntent=newIntent(this, ExampleService.class);
    closeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    closeIntent.putExtra("destroyCode", 666); // this is the important line //PendingIntentclosePendingIntent= PendingIntent.getService(this, 0, closeIntent, 0);

    createNotificationChannel(); // this is only the default code to create notification channel. I just outsourced? it //

Now the Intent has additional data (the "destroy code" -> 666). Notice that we have created 2 pendingIntents: closePendingIntent (stop Service) and tabPendingIntent (start Activity)

@OverridepublicintonStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    // get extras to know if Intent has destroyCode (666)Bundleextras= intent.getExtras();
    if (extras == null) {  
         // extras is null which means there is no destroyCode (666)
         exampleMethod();

    } else {
        // Intent has destroyCode (666) -> Intent comes from notification -> stop the service and close notification

        stopSelf();          
    }
    return START_STICKY;
}

Now we have the code to check if there is a destroyCode or not. The last step is to create a notification with a button:

// set attributes for notification //final NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channelID_2");
            Notification notification = builder.setOngoing(true)
                    .setSmallIcon(R.drawable.example)
                    .setContentTitle(getText(R.string.notificationTitle))
                    .setContentText(getText(R.string.notificationText))
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setCategory(NotificationCompat.CATEGORY_MESSAGE)
                    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                    .setContentIntent(tabPendingIntent) //this is when notification is clicked which only opens ExampleActivity
                    .addAction(R.drawable.example, getString(R.string.notificationButtonText), closePendingIntent) // here is our closePendingIntent with the destroyCode .addAction is "the onClickListener for the notification button"//
                        .build();
                startForeground(2, notification);

In onCreate you start your service

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
        startForegroundService();
    else
        startForeground(1, new Notification());

    // Toast Message that service has started
    Toast.makeText(this, R.string.serviceStarted, Toast.LENGTH_SHORT).show();

That's it

Solution 3:

You can't start an Acitivty from a Service just like that. What you can do is create a callback to an Activity in the Service and let the callback start new activities. But having a notification means you don't have to go through the Service. When the notification is clicked, you can start an activity that's specified in the Intent you supply to the notification. It's really very simple.

Do read the reference docs on notifications for examples.

Post a Comment for "Stopping A Background Service From Notification"