Android: 如何修复 JobIntentService 中的 BroadcastReceiver?

Android: How to fix BroadcastReceiver in JobIntentService?

我有一个 Activity 带有触发 BroadcastReceiver 的 AlarmManager。 BroadcastReceiver 触发 JobIntentService 以向用户发送通知。

当用户点击 "CLEAR ALL" 或滑动以关闭通知时,我希望 setDeleteIntent() 将我在 SharedPreferences 文件中设置的计数器变量 "totalMessages" 重置为零。它不会重置为零。我在这里错过了什么?

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);
    }
}

问题是您的广播接收器清除通知的实现在作业的生命周期内。 JobIntentService 的任务是显示通知并离开广播接收器。但是当用户点击通知中的 CLEAR 时,未决的意图被广播但是没有人听它。

作为解决方案,我建议您创建一个单独的广播接收器并将其注册到您的 AndroidManifest.xml。届时您的广播将始终被收听,您可以在其中进行任何表演..