Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Starting JobIntentService from PendingIntent (Notification button)?

In my app, I have a notification button that fires off a short network request in the background using an IntentService. It does not make sense to show a GUI here, which is why I use the service instead of an Activity. See the code below.

// Build the Intent used to start the NotifActionService
Intent buttonActionIntent = new Intent(this, NotifActionService.class);
buttonActionIntent.setAction(NotifActionService.ACTION_SEND_CONFIRM);
buttonActionIntent.putExtra(NotifActionService.EXTRA_CONFIRM_ID, confirmId);
buttonActionIntent.putExtra(NotifActionService.EXTRA_NOTIF_ID, notifId);

// Build the PendingIntent used to trigger the action
PendingIntent pendingIntentConfirm = PendingIntent.getService(this, 0, buttonActionIntent, PendingIntent.FLAG_UPDATE_CURRENT);

This works reliably but with the new background restrictions in Android 8.0 made me want to move to a JobIntentService instead. Updating service code itself seems very straight forward but I don't know how to launch it via a PendingIntent, which is what Notification Actions require.

How could I accomplish this?

Would it be better move to a normal service and use PendingIntent.getForegroundService(...) on API levels 26+ and the current code on API level 25 and below? That would require me to manually handle wakelocks, threads and result in an ugly notification on Android 8.0+.

EDIT: Below is the code I ended up with besides the straight forward conversion of the IntentService to a JobIntentService.

The BroadcastReceiver which just changes the intent class to my JobIntentService and runs its enqueueWork method:

public class NotifiActionReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        intent.setClass(context, NotifActionService.class);
        NotifActionService.enqueueWork(context, intent);
    }
}

Modified version of the original code:

// Build the Intent used to start the NotifActionReceiver
Intent buttonActionIntent = new Intent(this, NotifActionReceiver.class);
buttonActionIntent.setAction(NotifActionService.ACTION_SEND_CONFIRM);
buttonActionIntent.putExtra(NotifActionService.EXTRA_CONFIRM_ID, confirmId);
buttonActionIntent.putExtra(NotifActionService.EXTRA_NOTIF_ID, notifId);

// Build the PendingIntent used to trigger the action
PendingIntent pendingIntentConfirm = PendingIntent.getBroadcast(this, 0, buttonActionIntent, PendingIntent.FLAG_UPDATE_CURRENT);
like image 823
blunden Avatar asked Sep 10 '17 10:09

blunden


1 Answers

How could I accomplish this?

Use a BroadcastReceiver and a getBroadcast() PendingIntent, then have the receiver call the JobIntentService enqueueWork() method from its onReceive() method. I'll admit that I haven't tried this, but AFAIK it should work.

like image 161
CommonsWare Avatar answered Oct 15 '22 15:10

CommonsWare