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

3

我创建了多个带有不同文本的通知。但是,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);
2个回答

3

使用不同的requestCode为不同的带有标志FLAG_UPDATE_CURRENTPendingIntent

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()方法中,从Intent获取通知idtitleTextbigText

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

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

希望这能有所帮助~

哦,太感谢你的回答了!我现在会更深入地学习它。顺便问一下,下一个更新中可以提到你的名字作为感激之情吗? :) - Cakeee

0

你的问题在于这个PendingIntent.FLAG_CANCEL_CURRENT。 根据你想要做什么,在代码中使用不同的标志(flag),它们可以按照你的预期工作!

PendingIntent contentIntent = PendingIntent.getActivity(context,
                0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);

例如:FLAG_ACTIVITY_SINGLE_TOP、FLAG_ACTIVITY_CLEAR_TOP、FLAG_ACTIVITY_NEW_TASK,或者根本不使用任何标志(0)。

PendingIntent.FLAG_ONE_SHOT 强制你的程序仅使用一次 pendingintent。请注意,使用不同的 putString 调用 setAlarm 可能不会改变结果。

编辑: 将这些行放入 Schedule.java 的第 33 和 34 行。这将每次更改通知,但这不是一个好的解决方案,你应该用不同的字符串变量来替换 "something different" + bigText

String titleText = mPrefs.getString("titleText", "");
String bigText = mPrefs.getString("bigText", "");
SharedPreferences.Editor mPrefsTextsEditor = getSharedPreferences("notifications", 0).edit();
bigText = "something different" + bigText;
titleText = "something different" + titleText;
mPrefsTextsEditor .putString("bigText", bigText).apply();
mPrefsTextsEditor .putString("titleText", titleText).apply();

非常感谢您的回答。但是,无论是FLAG_CANCEL_CURRENT还是0,它们的工作方式都是相同的。太遗憾了。 - Cakeee
挂起意图标志如何? - Mehran Zamani
PendingIntent标志?我设置了PendingIntent.FLAG_CANCEL_CURRENT并以同样的方式工作。我设置0并以同样的方式工作。 - Cakeee
请将您设置不同标题和正文的通知消息的所有代码发送到这里。 - Mehran Zamani
该项目是开源的。我不想在这里粘贴一堆代码。这是链接:https://github.com/NapoleonTheCake/notificatorro 通知是在MainActivity类中的onClick_Notify方法中创建的。闹钟设置在Schedule活动中。包含.java文件的文件夹:https://github.com/NapoleonTheCake/notificatorro/tree/master/source/app/src/main/java/com/cake/notificator - Cakeee
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接