Android 每日通知无法正常工作

Android daily notifications do not work properly

我想在每天早上 9 点从我的应用程序显示通知。

所以我正在使用 Notification Manager、Alarm Manager、BroadcastReciever 和 Service 来实现这一点。

但是我有一个问题,因为通知随机显示。当我第一次启动应用程序并设置时间时,它工作正常,但后来应用程序触发并随机显示通知。

我该如何解决?

这是我的代码:

MainActivity

@Override
protected void onStart() {
    super.onStart();
    setAlarm();
}

public void setAlarm(){


    Calendar calendar = Calendar.getInstance();
    Calendar now = Calendar.getInstance();


    calendar.set(Calendar.HOUR_OF_DAY, 15);
    calendar.set(Calendar.MINUTE, 43);
    calendar.set(Calendar.SECOND, 0);

    if(calendar.getTime().after(now.getTime())) {
        alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

        alarmIntent = new Intent(MainActivity.this, HoroscopeNotification.class);
        pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);


        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);        }

 }

HoroscopNotification (BroadcastReciever)

public class HoroscopeNotification extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent arg1) {
        showNotification(context);
    }

    private void showNotification(Context context) {
        Intent service1 = new Intent(context, AlarmService.class);
        context.startService(service1);
    }
}

报警服务

public class AlarmService extends Service {
    private static final int NOTIFICATION_ID = 1;
    private NotificationManager notificationManager;
    private PendingIntent pendingIntent;

    @Override
    public IBinder onBind(Intent arg0)
    {
         return null;
    }

    @SuppressWarnings("static-access")
    @Override
    public void onStart(Intent intent, int startId)
    {
        super.onStart(intent, startId);
        Context context = this.getApplicationContext();
        notificationManager = (NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE);
        Intent mIntent = new Intent(this, MainActivity.class);
        pendingIntent = PendingIntent.getActivity(context, 0, mIntent, PendingIntent.FLAG_CANCEL_CURRENT);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle("Horoskop");
        builder.setContentText("Pročitajte današnji horoskop");
        builder.setSmallIcon(R.drawable.ic_bik);
        builder.setAutoCancel(true);
        builder.setContentIntent(pendingIntent);

        notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        notificationManager.notify(NOTIFICATION_ID, builder.build());
    }
}

Alarm Manager Example

我认为你应该按照以上 link 进行操作。从我的角度来看,您的设计模式(在 Activity class 中设置警报不是一个好方法)。相反(如上面的答案所示),您应该通过服务设置闹钟。通知代码也进入 BroadcastReceiver class,方法 OnReceive(在示例中它被注释为 "Put here YOUR code")。

祝你好运

您会在 Android SDK 参考 material 中注意到 AlarmManager.setRepeating() 状态:

Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.

您需要在 APIv19+ 上使用 AlarmManager.set() on pre-APIv19 and AlarmManager.setExact()。当您的 PendingIntent 被触发并且您在 BroadcastReceiver.onReceive() 中收到广播时,您可以为第二天设置另一个确切的闹钟。