首页 > 解决方案 > Weird issue with local notification on Oreo

问题描述

I was trying to implement a feature where user can set a reminder that will be delivered with a local push notification.

I am using AlarmManager to throw a broadcast when the time is up. Then in the broadcast receiver, I am posting a local notification and then starting a foreground service which starts an activity so I can wake the device and turn on the screen.

If I do nothing after posting the notification (simply return and not starting foreground service) I can get the device to show the notification with no problem. However, if I start the service right after posting the notification, all I get is some vibration but I don't see the notification anywhere. Even stranger, from the notification manager, it says there is 1 notification from getActiveNotifications() although there is nothing.

Receiver:

@Override
public void onReceive(Context context, Intent intent) {
    final String action = intent.getAction();
    if (!action.equals(context.getString(R.string.reminder_action_string))) {
        // fail safe check
        return;
    }

    // create the channel for android 8
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(
                CHANNEL_ID,
                context.getString(R.string.reminder_notification_channel),
                NotificationManager.IMPORTANCE_HIGH);

        channel.setDescription(context.getString(R.string.reminder_notification_channel_desc));

        final AudioAttributes attributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build();
        channel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), attributes);

        NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }

    NotificationCompat.Builder builder = new NotificationCompat.Builder(context, ReceiverReminder.CHANNEL_ID)
            .setChannelId(ReceiverReminder.CHANNEL_ID)
            .setContentTitle(context.getString(R.string.reminder_title))
            .setContentText(intent.getStringExtra(ActivityReminderCreate.TEXT_STRING))
            .setSmallIcon(R.drawable.ic_mic)
            .setStyle(new NotificationCompat.BigTextStyle()
                    .bigText(intent.getStringExtra(ActivityReminderCreate.TEXT_STRING)))
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setCategory(NotificationCompat.CATEGORY_ALARM)
            .setVisibility(NotificationCompat.VISIBILITY_SECRET)
            .setContentIntent(PendingIntent.getActivity(context, 0, new Intent(context, ActivityReminderList.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK), PendingIntent.FLAG_ONE_SHOT))
            .setAutoCancel(true);

    NotificationManagerCompat manager = NotificationManagerCompat.from(context);
    Notification notification = builder.build();
    final int id = mSecureRandom.nextInt();
    manager.notify(id, notification);

    Intent serviceIntent = new Intent(context, ServiceReminder.class);
    serviceIntent.putExtras(intent);
    serviceIntent.putExtra(KEY_ID, id);
    serviceIntent.putExtra(KEY_NOTIFICATION, notification);
    ContextCompat.startForegroundService(context, serviceIntent);
}

IntentService:

@Override
protected void onHandleIntent(@Nullable Intent intent) {
    // construct notification object
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        // start self in foreground
        NotificationManager manager = getSystemService(NotificationManager.class);
        Log.e(TAG, "notification count: " + manager.getActiveNotifications().length);


        Notification notification = intent.getExtras().getParcelable(ReceiverReminder.KEY_NOTIFICATION);
        int id = intent.getExtras().getInt(ReceiverReminder.KEY_ID);
        startForeground(id, notification);

        Log.e(TAG, "notification count: " + manager.getActiveNotifications().length);
    }

    // start an activity so device can be waken up
    Intent activityIntent = new Intent(ServiceReminder.this, ActivityReminderList.class);
    activityIntent.putExtra(ActivityReminderList.KEY_FROM_SERVICE, true);
    startActivity(activityIntent);
}

标签: androidnotificationsandroid-8.0-oreo

解决方案


我明白了为什么...

我使用了一个IntentService当它当前的工作完成时会自杀的。并且在前台服务的情况下,当服务停止时,相关的通知将被解除。

我已改用 a Service,通知将保留在那里。


推荐阅读