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

相关文章

SpringBoot整合 Quartz实现定时推送实战指南

《SpringBoot整合Quartz实现定时推送实战指南》文章介绍了SpringBoot中使用Quartz动态定时任务和任务持久化实现多条不确定结束时间并提前N分钟推送的方案,本文结合实例代码给大... 目录前言一、Quartz 是什么?1、核心定位:解决什么问题?2、Quartz 核心组件二、使用步骤1

springboot3.x使用@NacosValue无法获取配置信息的解决过程

《springboot3.x使用@NacosValue无法获取配置信息的解决过程》在SpringBoot3.x中升级Nacos依赖后,使用@NacosValue无法动态获取配置,通过引入SpringC... 目录一、python问题描述二、解决方案总结一、问题描述springboot从2android.x

idea粘贴空格时显示NBSP的问题及解决方案

《idea粘贴空格时显示NBSP的问题及解决方案》在IDEA中粘贴代码时出现大量空格占位符NBSP,可以通过取消勾选AdvancedSettings中的相应选项来解决... 目录1、背景介绍2、解决办法3、处理完成总结1、背景介绍python在idehttp://www.chinasem.cna粘贴代码,出

Go语言实现桥接模式

《Go语言实现桥接模式》桥接模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立地变化,本文就来介绍一下了Go语言实现桥接模式,感兴趣的可以了解一下... 目录简介核心概念为什么使用桥接模式?应用场景案例分析步骤一:定义实现接口步骤二:创建具体实现类步骤三:定义抽象类步骤四:创建扩展抽象类步

nacos服务无法注册到nacos服务中心问题及解决

《nacos服务无法注册到nacos服务中心问题及解决》本文详细描述了在Linux服务器上使用Tomcat启动Java程序时,服务无法注册到Nacos的排查过程,通过一系列排查步骤,发现问题出在Tom... 目录简介依赖异常情况排查断点调试原因解决NacosRegisterOnWar结果总结简介1、程序在

Apache服务器IP自动跳转域名的问题及解决方案

《Apache服务器IP自动跳转域名的问题及解决方案》本教程将详细介绍如何通过Apache虚拟主机配置实现这一功能,并解决常见问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录​​问题背景​​解决方案​​方法 1:修改 httpd-vhosts.conf(推荐)​​步骤

SpringBoot中使用定时任务schedule详解

《SpringBoot中使用定时任务schedule详解》文章介绍了如何在Spring应用中使用@EnableScheduling注解启用定时任务,并创建一个配置类来定义定时任务的执行,文章还详细解释... 目录1、在spring启动类上添加注解@EnableScheduling2、创建定时任务配置类3、执

Linux(centos7)虚拟机没有IP问题及解决方案

《Linux(centos7)虚拟机没有IP问题及解决方案》文章介绍了在CentOS7中配置虚拟机网络并使用Xshell连接虚拟机的步骤,首先,检查并配置网卡ens33的ONBOOT属性为yes,然后... 目录输入查看ZFhrxIP命令:ip addr查看,没有虚拟机IP修改ens33配置文件重启网络Xh

Java编译错误java.lang.NoSuchFieldError的解决方案详析

《Java编译错误java.lang.NoSuchFieldError的解决方案详析》java.lang.NoSuchFieldError是Java中的一种运行时错误,:本文主要介绍Java编译错... 目录前言解决方案1. 统一JDK版本环境2. 优化maven-compiler-plugin配置3. 清

C++中的解释器模式实例详解

《C++中的解释器模式实例详解》这篇文章总结了C++标准库中的算法分类,还介绍了sort和stable_sort的区别,以及remove和erase的结合使用,结合实例代码给大家介绍的非常详细,感兴趣... 目录1、非修改序列算法1.1 find 和 find_if1.2 count 和 count_if1