ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

在Android中设备处于睡眠状态时,AlarmManager警报无法正常工作

2019-06-22 14:12:09  阅读:421  来源: 互联网

标签:android alarmmanager


我需要在每个时间段运行一段代码,即使应用程序被终止或设备休眠.

我使用AlarmManager实现这一点,它有点工作,但当设备休眠大约五分钟时,服务不再被调用…有谁知道我做错了什么?

这是我的代码:

public class Profiler extends IntentService {

    public static final int ALARM_MANAGER_ID = 21436587;

    public Profiler() {
        super("Profiler");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        JodaTimeAndroid.init(getApplicationContext());
        System.out.println("Testing profiles");
        List<Profile> profiles = MainActivity.getStoredProfiles(getApplicationContext());

        if (profiles != null) {
            for (Profile profile : profiles) {
                if(profile.check()) {
                    profile.set(getApplicationContext());
                }
            }
        }

        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        Intent intent2 = new Intent(getApplicationContext(), Profiler.class);
        PendingIntent pIntent = PendingIntent.getService(getApplicationContext(), ALARM_MANAGER_ID, intent2, PendingIntent.FLAG_CANCEL_CURRENT);
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, DateTime.now().plusSeconds(10).getMillis(), pIntent);
    }
}

还有一个问题.这种调用服务的方法是否可靠?

这是日志

07-24 11:31:24.654 17689-19078/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":0,"minute":0}
07-24 11:31:34.671 17689-20364/cz.fjerabek.soundprofiler I/System.out: Testing profiles
07-24 11:31:34.673 17689-20364/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":11,"minute":15}
07-24 11:31:34.674 17689-20364/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":0,"minute":0}
07-24 11:31:44.692 17689-21571/cz.fjerabek.soundprofiler I/System.out: Testing profiles
07-24 11:31:44.693 17689-21571/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":11,"minute":15}
07-24 11:31:44.694 17689-21571/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":0,"minute":0}
07-24 11:31:54.704 17689-22753/cz.fjerabek.soundprofiler I/System.out: Testing profiles
07-24 11:31:54.705 17689-22753/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":11,"minute":15}
07-24 11:31:54.706 17689-22753/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":0,"minute":0}
07-24 11:32:04.717 17689-24015/cz.fjerabek.soundprofiler I/System.out: Testing profiles
07-24 11:32:04.718 17689-24015/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":11,"minute":15}
07-24 11:32:04.718 17689-24015/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":0,"minute":0}
07-24 11:35:29.032 17689-17475/cz.fjerabek.soundprofiler I/System.out: Testing profiles
07-24 11:35:29.040 17689-17475/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":11,"minute":15}
07-24 11:35:29.050 17689-17475/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":0,"minute":0}

                                                                       [ 07-24 11:35:29.056 17476:17476 I/         ]
                                                                       power log dlsym ok

应用程序是在11:31开始的,现在是11:40,因为你可以看到代码的最后一次执行是在11:35而在那之前的11:32它的3分钟然后看起来它每5分钟被调用一次.

我正在启动服务:

Intent bgServiceIntent = new Intent(getApplicationContext(), Profiler.class);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        if(checkNotificationPolicy(getApplicationContext())) {
            startService(bgServiceIntent);
        }
    } else {
        startService(bgServiceIntent);
    }

我正在使用的设备:HUAWEI P9 lite(VNS-L21)

解决方法:

问题的原因很可能是Doze.

从其有关AlarmManager的文档:

To help with scheduling alarms, Android 6.0 (API level 23) introduces
two new AlarmManager methods: setAndAllowWhileIdle() and
setExactAndAllowWhileIdle(). With these methods, you can set alarms
that will fire even if the device is in Doze.

您应该根据API级别调用相应的AlarmManager方法,以确保即使设备处于休眠状态也会发出警报:

if (Build.VERSION.SDK_INT >= 23) {
    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
            alarmMillis, alarmIntent);
} else if (Build.VERSION.SDK_INT >= 19) {
    alarmManager.setExact(AlarmManager.RTC_WAKEUP,
            alarmMillis, alarmIntent);
} else {
    alarmManager.set(AlarmManager.RTC_WAKEUP,
            alarmMillis, alarmIntent);
}

考虑以下因素:

Neither setAndAllowWhileIdle() nor setExactAndAllowWhileIdle() can
fire alarms more than once per 9 minutes, per app.

正如您所说,您正在测试华为设备.

华为(以及其他制造商)已经实施了一些可以防止警报响起的电池保护功能.您必须将应用添加到“受保护”的应用中.

请查看以下问题:1& 2

建议不要以编程方式执行此操作,正确的解决方案可能是在启动时警告用户(例如使用AlertDialog),以便在电池管理器中手动使应用程序“受保护”.

标签:android,alarmmanager
来源: https://codeday.me/bug/20190622/1264532.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有