Android: How to fix BroadcastReceiver in JobIntent

2019-06-07 06:43发布

I have an Activity with an AlarmManager that fires a BroadcastReceiver. The BroadcastReceiver fires a JobIntentService to send a Notification to the user.

When the user taps "CLEAR ALL" or swipes to dismiss the Notification, I want the setDeleteIntent() to reset a counter variable "totalMessages" to zero that I set up in a SharedPreferences file. It is not resetting to zero. What am I missing here?

public class AlarmService extends JobIntentService {

    static final int JOB_ID = 9999;
    public static final String NOTIFICATIONS_COUNTER = "NotificationsCounter";
    private static final int REQUEST_CODE_DELETE_INTENT = 1;
    int totalMessages = 0;

    static void enqueueWork(Context context, Intent work) {
        enqueueWork(context, AlarmService.class, JOB_ID, work);
    }

    @Override
    protected void onHandleWork(@NonNull Intent intent) {

        IntentFilter filter = new IntentFilter();
        filter.addAction("notification_cleared");
        registerReceiver(receiver, filter);

        sendNotification();
    }

    private void sendNotification() {

        int notifyID = 1;

        NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

        SharedPreferences sp = getSharedPreferences(NOTIFICATIONS_COUNTER, Context.MODE_PRIVATE);
        totalMessages = sp.getInt("total-messages", 0); //initialize to 0 if it doesn't exist
        SharedPreferences.Editor editor = sp.edit();
        editor.putInt("total-messages", ++totalMessages);
        editor.apply();

        NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
            .setDefaults(Notification.DEFAULT_ALL)
            .setSmallIcon(R.drawable.ic_announcement_white_24dp)
            .setContentText("")
            Intent i = new Intent(this, AlarmService.class);
            i.setAction("notification_cleared");
            PendingIntent deleteIntent = PendingIntent.getBroadcast(this,REQUEST_CODE_DELETE_INTENT,i,PendingIntent.FLAG_CANCEL_CURRENT);
            mBuilder.setDeleteIntent(deleteIntent);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            mBuilder.setSubText(String.valueOf(totalMessages));
        }
        else {
            mBuilder.setNumber(totalMessages);
        }

        if (notificationManager != null) {
            notificationManager.notify(notifyID, mBuilder.build());
        }
    }

    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action != null) {
                if (action.equals("notification_cleared")) {

                // Reset the Notifications counter ("total-messages") to zero since the user
                // clicked on "CLEAR ALL" Notification or swiped to delete a Notification.
                SharedPreferences sp1 = getSharedPreferences(NOTIFICATIONS_COUNTER, Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = sp1.edit();
                editor.clear();
                editor.apply();
                totalMessages = sp1.getInt("total-messages", 0); //initialize to 0 if it doesn't exist
                editor.putInt("total-messages", totalMessages);
                editor.apply();
                }
            }
        }
    };

    @Override
    public void onDestroy() {
        super.onDestroy();

        unregisterReceiver(receiver);
    }
}

1条回答
啃猪蹄的小仙女
2楼-- · 2019-06-07 06:59

The problem is that your broadcast receiver's implementation to clear notifications is within the life-cycle of job. JobIntentService is tasked to show notification and go away thus the broadcast receiver. But when the user clicks on the CLEAR from notification, the pending intent is broadcasted but then there's no one to listen to it.

For a solution, I would suggest you to create a separate broadcast receiver and register it in your AndroidManifest.xml. By then your broadcast will always be listened and you can perform what ever within..

查看更多
登录 后发表回答