简体   繁体   English

Android AlarmManager晚上无法正常工作

[英]Android AlarmManager not working at night

I'm having a problem with the Android AlarmManager. 我的Android AlarmManager出现问题。 I want to show a notification everyday at 00:01 AM. 我想每天00:01显示通知。 When i test the notification during the day at something like 11:30 AM the notification does show up. 当我白天在上午11:30左右测试通知时,通知确实会显示。 But when i test it at 00:01 AM nothing shows up. 但是当我在00:01 AM对其进行测试时,没有任何显示。

I think this has something to do with my phone being asleep after a few hours of no activity at 00:01 AM, but I am not sure. 我认为这与我的手机在凌晨00:01几小时无活动后进入睡眠状态有关,但我不确定。 Does anybody have a solution for this? 有人对此有解决方案吗? Thanks in advance. 提前致谢。

MainActivity: 主要活动:

    Intent alarmIntent = new Intent(this, AlarmReceiver.class);

    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    AlarmManager manager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 1);

    Calendar now = Calendar.getInstance();
    now.setTimeInMillis(System.currentTimeMillis());

    if (calendar.before(now)) {
        calendar.add(Calendar.DAY_OF_MONTH, 1);

        manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                AlarmManager.INTERVAL_DAY, pendingIntent);
    } else {
        manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                AlarmManager.INTERVAL_DAY, pendingIntent);
    }

AlarmReceiver: AlarmReceiver:

    private static int NOTIFICATION_ID;
    private NotificationManager notificationManager;
    private PendingIntent pendingIntent;

    Intent mIntent;

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

    NOTIFICATION_ID = random.nextInt(9999 - 1000) + 1000;
    notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
    mIntent = new Intent(context, BirthdayActivity.class);

    pendingIntent = PendingIntent.getActivity(context, NOTIFICATION_ID, mIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.Builder builder = new NotificationCompat.Builder(context);

    builder.setContentTitle("Name");
    builder.setContentIntent(pendingIntent);

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

Manifest: 表现:

    <receiver android:name=".utils.AlarmReceiver" android:enabled="true">
    </receiver>

    <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>

I think everything is right with your code. 我认为您的代码一切正确。 You can check whether the alarm is set or not using this command on your android studio terminal. 您可以在Android Studio终端上使用此命令检查是否设置了警报。 adb shell dumpsys alarms >dump.txt and then search for your package name in that file. adb shell dumpsys alarms >dump.txt ,然后在该文件中搜索您的软件包名称。 This will confirm whether your alarm is set successfully or not. 这将确认您的警报是否设置成功。

Next you are using setRepeating which means system can adjust the delivery time. 接下来,您将使用setRepeating ,这意味着系统可以调整交付时间。 To deliver the alarm at the exact time use setExact here is a excerpt from the official android documentation: 要在准确的时间发出警报,请使用setExact此处摘录自官方的android文档:

Note: as of API 19, all repeating alarms are inexact. 注意:从API 19开始,所有重复警报都是不精确的。 If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. 如果您的应用程序需要精确的交付时间,则它必须使用一次性精确警报,并如上所述每次重新安排。

From the api docs: 从api文档中:

Note: as of API 19, all repeating alarms are inexact. 注意:从API 19开始,所有重复警报都是不精确的。 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. targetSdkVersion早于API 19的旧版应用程序将继续将其所有警报(包括重复警报)视为精确警报。

https://developer.android.com/reference/android/app/AlarmManager.html#setRepeating(int, long, long, android.app.PendingIntent) https://developer.android.com/reference/android/app/AlarmManager.html#setRepeating(int,long,long,android.app.PendingIntent)

There are a few questions you should answer. 您应该回答几个问题。

  • Does this really need to be exact? 这真的需要精确吗?

  • If the user is sleeping can this wait until they wake up their phone? 如果用户正在睡觉,可以等到他们唤醒手机后再进行吗?

Exact alarms are often discouraged as they disregard the state of the phone. 由于不考虑电话的状态,因此通常不建议使用确切的警报。 For example, its not "nice" to the user to sync your app when they aren't even looking at their phone. 例如,当用户甚至不看手机时,它对用户同步应用程序都不“好”。

If you are connecting to a server and updating some data, I'd recommend a 'push' approach rather than a 'pull' approach. 如果要连接到服务器并更新一些数据,则建议使用“推”方法而不是“拉”方法。

They system only holds a wakelock while delivering the alarm notification to the AlarmReceiver . 他们的系统仅在将警报通知传送到AlarmReceiver时才持有唤醒AlarmReceiver Unless there is some other reason for the device to stay awake, it is entirely possible that it will go back to sleep, before the Intent is delivered to the Activity. 除非有其他原因使设备保持清醒状态,否则在将Intent传递给Activity之前,它很有可能会重新进入睡眠状态。

Have a look at WakefulBroadcastReceiver 看看WakefulBroadcastReceiver

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM