Doze 模式下 Alram 无法定时唤醒的解决方案

2024-02-09 20:32

本文主要是介绍Doze 模式下 Alram 无法定时唤醒的解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. adb 命令模拟进入doze模式

  1. 设置未充电状态

方便连接logcat查看实时日志,正常情况下如果连接 USB 是无法进入doze模式,这个步骤是欺骗系统当前没有连接USB,虽然实际连接得好好的

adb shell dumpsys battery unplug
  1. 设置开启 alarm 日志

并不是每台机器都开启 alarm 的日志,所以我们可以命令强制开启

adb shell dumpsys alarm log on
  1. 强制进入Doze模块

要调试就进入深度休眠模式,即 deep idle mode

adb shell dumpsys deviceidle force-idle deep

2. 复现现象

2.1 Alarm的参考代码
    starAlarmTaskByService(this, 5);public static void starAlarmTaskByService(Context context, int intervalMinute) {AlarmManager mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);long triggerAtMillis = System.currentTimeMillis() + (intervalMinute * 60 * 1000);Log.d(TAG, "starAlarmTaskByService action = " + ACTION_RTC_WAKEUP_ALRTM_TYPE_0_SERVIE  + ", 下次唤醒时刻 = " + DateTimeUtil.getSysDate(triggerAtMillis));Intent intent = new Intent(context, MyService.class);intent.setAction(ACTION_RTC_WAKEUP_ALRTM_TYPE_0_SERVIE);PendingIntent operation = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, operation);} else {mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, operation);}}
2.2 异常日志

注意这里的 flags

2018-08-23 14:25:07.989 934-24435/? V/AlarmManager: set(PendingIntent{c4c0513: PendingIntentRecord{59c2350 test.demo.alarm.zui.com.alarmtest startService}}) : type=0 triggerAtTime=1535005807985 win=0 tElapsed=70204635 maxElapsed=70204635 interval=0 flags=0x1(非DeviceIdleUserWhitelist白名单)
2.3 正常日志

注意这里的 flags

2018-08-23 14:18:29.063 934-945/? V/AlarmManager: set(PendingIntent{c6e22ba: PendingIntentRecord{f55a56b test.demo.alarm.zui.com.alarmtest startService}}) : type=0 triggerAtTime=1535005409060 win=0 tElapsed=69805710 maxElapsed=69805710 interval=0 flags=0x9(DeviceIdleUserWhitelist白名单正常)
2.4 查看对应doze模式白名单

使用命令 adb shell dumpsys deviceidle whitelist 查看

2.4.1 异常现象白名单 1

这个是在系统源码路径 frameworks\base\data\etc\platform.xml,可以手机系统用 adb shell cat “/etc/permissions/platform.xml”查看

D:\AndroidStudioProjects>adb shell dumpsys deviceidle whitelist
system-excidle,com.android.providers.downloads,10020
system-excidle,com.android.shell,2000
system,com.android.providers.downloads,10020
system,com.android.shell,2000
system,test.demo.alarm.zui.com.alarmtest,10090
2.4.2 异常现象白名单 2

这里是没有任何设置白名单

D:\AndroidStudioProjects>adb shell dumpsys deviceidle whitelist
system-excidle,com.android.providers.downloads,10020
system-excidle,com.android.shell,2000
system,com.android.providers.downloads,10020
system,com.android.shell,2000
2.4.3 正常现象的白名单

这里是使用软件接口进行配置 mDeviceIdleService.addPowerSaveWhitelistApp(pkg);

D:\AndroidStudioProjects>adb shell dumpsys deviceidle whitelist
system-excidle,com.android.providers.downloads,10020
system-excidle,com.android.shell,2000
system,com.android.providers.downloads,10020
system,com.android.shell,2000
user,test.demo.alarm.zui.com.alarmtest,10090

3. 相关源码

根据 mDeviceIdleUserWhitelist 进行对应的 flags 的重新设置,这个mDeviceIdleUserWhitelist是使用接口进行加入

    private final IBinder mService = new IAlarmManager.Stub() {@Overridepublic void set(String callingPackage,int type, long triggerAtTime, long windowLength, long interval, int flags,PendingIntent operation, IAlarmListener directReceiver, String listenerTag,WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock) {...省略// If the caller is a core system component or on the user's whitelist, and not calling// to do work on behalf of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED.// This means we will allow these alarms to go off as normal even while idle, with no// timing restrictions.} else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID|| callingUid == mSystemUiUid|| Arrays.binarySearch(mDeviceIdleUserWhitelist,UserHandle.getAppId(callingUid)) >= 0)) {flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE;}setImpl(type, triggerAtTime, windowLength, interval, operation, directReceiver,listenerTag, flags, workSource, alarmClock, callingUid, callingPackage);}

4.解决方案

使用软件接口设置doze模式白名单,解决即可,这样就可以开心的准时接收消息了

  • 核心接口 mDeviceIdleService.addPowerSaveWhitelistApp(pkg);
/** Copyright (C) 2015 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/
package com.android.sufadi.powersave.util;import android.os.IDeviceIdleController;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.ArraySet;
import android.util.Log;/*** Handles getting/changing the whitelist for the exceptions to battery saving features.*/
public class PowerWhitelistBackend {private static final String TAG = "LavaPowerWhitelistBackend";private static final String DEVICE_IDLE_SERVICE = "deviceidle";private static final PowerWhitelistBackend INSTANCE = new PowerWhitelistBackend();private final IDeviceIdleController mDeviceIdleService;private final ArraySet<String> mWhitelistedApps = new ArraySet<>();private final ArraySet<String> mSysWhitelistedApps = new ArraySet<>();public PowerWhitelistBackend() {mDeviceIdleService = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(DEVICE_IDLE_SERVICE));refreshList();}public int getWhitelistSize() {return mWhitelistedApps.size();}public boolean isSysWhitelisted(String pkg) {return mSysWhitelistedApps.contains(pkg);}public boolean isWhitelisted(String pkg) {return mWhitelistedApps.contains(pkg);}public void addApp(String pkg) {try {mDeviceIdleService.addPowerSaveWhitelistApp(pkg);mWhitelistedApps.add(pkg);} catch (RemoteException e) {Log.w(TAG, "Unable to reach IDeviceIdleController", e);}}public void removeApp(String pkg) {try {mDeviceIdleService.removePowerSaveWhitelistApp(pkg);mWhitelistedApps.remove(pkg);} catch (RemoteException e) {Log.w(TAG, "Unable to reach IDeviceIdleController", e);}}private void refreshList() {mSysWhitelistedApps.clear();mWhitelistedApps.clear();try {String[] whitelistedApps = mDeviceIdleService.getFullPowerWhitelist();for (String app : whitelistedApps) {mWhitelistedApps.add(app);}String[] sysWhitelistedApps = mDeviceIdleService.getSystemPowerWhitelist();for (String app : sysWhitelistedApps) {mSysWhitelistedApps.add(app);}} catch (RemoteException e) {Log.w(TAG, "Unable to reach IDeviceIdleController", e);}}public static PowerWhitelistBackend getInstance() {return INSTANCE;}}

这篇关于Doze 模式下 Alram 无法定时唤醒的解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/695208

相关文章

如何解决mmcv无法安装或安装之后报错问题

《如何解决mmcv无法安装或安装之后报错问题》:本文主要介绍如何解决mmcv无法安装或安装之后报错问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mmcv无法安装或安装之后报错问题1.当我们运行YOwww.chinasem.cnLO时遇到2.找到下图所示这里3.

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

Linux samba共享慢的原因及解决方案

《Linuxsamba共享慢的原因及解决方案》:本文主要介绍Linuxsamba共享慢的原因及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux samba共享慢原因及解决问题表现原因解决办法总结Linandroidux samba共享慢原因及解决

找不到Anaconda prompt终端的原因分析及解决方案

《找不到Anacondaprompt终端的原因分析及解决方案》因为anaconda还没有初始化,在安装anaconda的过程中,有一行是否要添加anaconda到菜单目录中,由于没有勾选,导致没有菜... 目录问题原因问http://www.chinasem.cn题解决安装了 Anaconda 却找不到 An

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M

电脑win32spl.dll文件丢失咋办? win32spl.dll丢失无法连接打印机修复技巧

《电脑win32spl.dll文件丢失咋办?win32spl.dll丢失无法连接打印机修复技巧》电脑突然提示win32spl.dll文件丢失,打印机死活连不上,今天就来给大家详细讲解一下这个问题的解... 不知道大家在使用电脑的时候是否遇到过关于win32spl.dll文件丢失的问题,win32spl.dl

java常见报错及解决方案总结

《java常见报错及解决方案总结》:本文主要介绍Java编程中常见错误类型及示例,包括语法错误、空指针异常、数组下标越界、类型转换异常、文件未找到异常、除以零异常、非法线程操作异常、方法未定义异常... 目录1. 语法错误 (Syntax Errors)示例 1:解决方案:2. 空指针异常 (NullPoi

pip无法安装osgeo失败的问题解决

《pip无法安装osgeo失败的问题解决》本文主要介绍了pip无法安装osgeo失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 进入官方提供的扩展包下载网站寻找版本适配的whl文件注意:要选择cp(python版本)和你py