Android:AlarmManager 一直显示相同的通知

标签 android notifications alarmmanager

我用不同的文本创建了多个通知。但是,AlarmManager 始终显示具有相同文本的通知,如果前一个通知没有被滑走,则会替换旧通知。 NOTIFY_ID 总是不同的(已调试)。我还发现,如果我在显示通知后在 onRecieve 方法中使应用程序崩溃,它工作正常......这是代码:

public class Schedule extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
        wakeLock.acquire();

        //next is notification code. //

        //get res.
        SharedPreferences mPrefs = context.getSharedPreferences("appsettings", 0);

        String titleText = mPrefs.getString("titleText", "");
        String bigText = mPrefs.getString("bigText", "");
        int NOTIFY_ID = mPrefs.getInt("id", 0);

        //create intent.
        Intent notificationIntent = new Intent(context, MainActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(context,
                0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);

        //get res.
        Resources res = context.getResources();

        //build notification.
        Notification.Builder builder = new Notification.Builder(context)
                .setContentIntent(contentIntent)
                .setSmallIcon(R.drawable.statusbaricon)
                .setAutoCancel(true)
                .setContentTitle(titleText)
                .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                .setContentText(bigText);


        //check vibration.
        if (mPrefs.getBoolean("vibration", true)) {
            builder.setVibrate(new long[] { 0, 50 });
        }

        //create default title if empty.
        if (titleText.length() == 0) {
            builder.setContentTitle(context.getString(R.string.notification_Title_Default));
        }

        //show notification. check for delay.
        builder.setWhen(System.currentTimeMillis());

        Notification notification = new Notification.BigTextStyle(builder)
                .bigText(bigText).build();

        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(NOTIFY_ID, notification);

        ////
        wakeLock.release();
    }

    public void setAlarm(Context context) {

        SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
        int delay = mPrefs.getInt("delay", 0);
        int id = mPrefs.getInt("id", 0);

        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, Schedule.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_ONE_SHOT);
        alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() /* + 1000 * 60 * delay */, pendingIntent);
    }
}

我是这样调用它的:

    //store stuff to revoke in Schedule.
    mPrefsEditor.putString("bigText", bigText).apply();
    mPrefsEditor.putString("titleText", titleText).apply();

    Schedule schedule = new Schedule();
    schedule.setAlarm(context);

最佳答案

对带有标志 FLAG_UPDATE_CURRENT 的不同 PendingIntent 使用不同的 requestCode

PendingIntent contentIntent = PendingIntent.getActivity(context, requestCode, 
                              notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

1.setAlarm()方法发送通知idtitleTextbigText 通过 intent 广播 receiver 并使用标志 FLAG_UPDATE_CURRENT 而不是 FLAG_ONE_SHOT

更新 setAlarm() 方法如下:

public void setAlarm(Context context) {

    SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
    int delay = mPrefs.getInt("delay", 0);
    int id = mPrefs.getInt("id", 0);
    String titleText = mPrefs.getString("titleText", "");
    String bigText = mPrefs.getString("bigText", "");

    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

    // send notification id, titleText and bigText with intent 
    // to use later when alarm triggers
    Intent intent = new Intent(context, Schedule.class);
    intent.putExtra("NOTIFICATION_ID", id);
    intent.putExtra("TITLE_TEXT", titleText);
    intent.putExtra("BIG_TEXT", bigText);

    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() /* + 1000 * 60 * delay */, pendingIntent);
}

2. 在您的onReceive() 方法中,获取通知idtitleTextbigText 来自 Intent

3. 使用通知 id 作为 contentIntentrequestCode 并使用 titleTextbigText 用于通知 text

更新 onReceive() 方法如下:

public class Schedule extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
        wakeLock.acquire();

        // get id, titleText and bigText from intent
        int NOTIFY_ID = intent.getIntExtra("NOTIFICATION_ID", 0);
        String titleText = intent.getStringExtra("TITLE_TEXT");
        String bigText = intent.getStringExtra("BIG_TEXT");

        // Create intent.
        Intent notificationIntent = new Intent(context, MainActivity.class);

        // use NOTIFY_ID as requestCode
        PendingIntent contentIntent = PendingIntent.getActivity(context,
                NOTIFY_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        // get res.
        Resources res = context.getResources();

        // build notification.
        Notification.Builder builder = new Notification.Builder(context)
                .setContentIntent(contentIntent)
                .setSmallIcon(R.drawable.statusbaricon)
                .setAutoCancel(true)
                .setContentTitle(titleText)
                .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                .setContentText(bigText);


        // check vibration.
        if (mPrefs.getBoolean("vibration", true)) {
            builder.setVibrate(new long[] { 0, 50 });
        }

        // create default title if empty.
        if (titleText.length() == 0) {
            builder.setContentTitle(context.getString(R.string.notification_Title_Default));
        }

        // show notification. check for delay.
        builder.setWhen(System.currentTimeMillis());

        Notification notification = new Notification.BigTextStyle(builder)
                .bigText(bigText).build();

        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(NOTIFY_ID, notification);

        ////
        wakeLock.release();
    }

    ....................
    .......................... 
}

希望对你有帮助~

关于Android:AlarmManager 一直显示相同的通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43706053/

相关文章:

java - RecyclerView 装饰无法正确滚动

android - Android 6.0 Doze 模式下的 Alarm Manager 问题

java - 使用 AlarmManager 设置不同时区的闹钟

ios - 闹钟锁屏通知

c# - 对 sspi 的调用失败,看到内部异常。收到的消息是意外的或在 Windows 7 中格式错误]

android-如何触发通知onclick事件?或者如何仅在用户点击时获取数据

iphone - 在多种设备(手机,平板电脑,游戏机等)上进行自动质量检查

android - android 中的 java.lang.NoClassDefFoundError : java. lang.ClassNotFoundException

android - 如何更改android中导航内容的颜色