我有一个应用程序,可以收听电话通知,并通过以下方式向Android Wear手表发送消息MessageApi.一些设备运行良好,除了Android 6的一些设备,特别是华为Mate 8(看起来像所有华为Android 6的这样做).
华为有自己的冻结应用程序后台处理(受保护的应用程序)的实现.从用户报告中我已经确认我的应用程序在华为的受保护应用程序和Android 6的打盹模式中都有例外.该应用程序工作正常,但在显示关闭15分钟后,我的应用程序停止向连接的Android Wear手表发送消息.我的应用程序还可以记录收到的通知历史记录,15分钟后没有任何内容...直到手机的显示屏打开并且我的应用程序打开.之后,在手机显示屏关闭时应该收到的所有通知都会进入我的NotificationListenerService实施并立即发送到手表.记录的历史也证实了这一点.
任何想法如何为这些手机解决这个问题,尤其是带有Doze模式的Android 6的华为Mate 8?
NotificationListenerService设备处于打盹模式和/或应用程序处于待机模式时的正确行为是什么?
编辑
用户还确认他们的手机未处于省电模式,这也会影响后台应用及其服务.这个bug看起来像华为独家,因为没有Nexus用户报告这个,我的OnePlus One和M也没有这样做.N预览也适用于Nexus设备.
编辑2
我添加了一个可选的前台服务(startForeground()),因此我的应用程序在通知中心有一个永久通知,因此我的应用程序应该从每个电池优化中排除.对于前台服务通知,我使用了优先级,NotificationCompat.PRIORITY_MIN并添加了Notification.FLAG_ONGOING_EVENT标志.这对华为手机有点帮助但不多,现在NotificationListenerService在打开我的应用程序后打开屏幕后,延迟通知就会到达我的右边.我不使用startForeground()in NotificationListenerService而是使用另一个Service因为我无法控制它的生命周期.
android android-notifications android-appstandby android-doze wear-os
我需要每隔X小时设置一次重复警报,甚至会在打盹模式下触发.但是,AlarmManager for Android 23中唯一可用的Apis是setExactAndAllowWhileIdle和setAndAllowWhileIdle,它们不用于重复警报.
我想知道每次发射时我是否应该重新安排闹铃?或者有更好的解决方案吗?
android android-alarms android-6.0-marshmallow android-doze-and-standby android-doze
我正在创建一个应用程序,它将在设备锁定时运行Activity#setShowWhenLocked(true).我不想阻止设备进入低功耗状态.我知道系统会这样做Always-On Display,并且显示器具有相关的电源模式:
/frameworks/base/core/java/android/view/Display.java
286 /**
287 * Display state: The display is dozing in a low power state; it is still
288 * on but is optimized for showing system-provided content while the
289 * device is non-interactive.
290 *
291 * @see #getState
292 * @see android.os.PowerManager#isInteractive
293 */
294 public static final int STATE_DOZE = ViewProtoEnums.DISPLAY_STATE_DOZE; // 3
295
296 /**
297 * Display state: The display is dozing in a suspended low power …Run Code Online (Sandbox Code Playgroud) android android-source android-doze-and-standby android-doze android-9.0-pie
Marshmallow API 与之前的安卓操作系统有很大不同。屏幕关闭时,设备处于休眠模式且无法同步网络。因此,为了使用网络进行后台操作,我们必须防止打瞌睡模式。
android android-6.0-marshmallow android-appstandby android-doze
应用程序正在运行SDK 23及更高版本.我在完成任务并使用AlaramManager(setExactAndAllowWhileIdle)安排下一个任务后使用Service运行一些任务.这工作正常.如果手机连续闲置2或3天,则进入打盹模式.打盹模式后,应用程序丢失网络和唤醒锁也无法正常工作.
是否有办法即使手机是Doze我们可以运行任何网络插入问题的应用程序.我试图保持应用程序witelist但我需要设备根植.
adb shell dumpsys deviceidle whitelist +<Package Name>
Run Code Online (Sandbox Code Playgroud)
任何人都可以建议我不间断地运行应用程序的最佳方法?
我正在努力使我的Android应用程序成为后Android M世界的好公民,这对设备进入打瞌睡时应用程序可以/不能做什么施加了严格限制.我对所涉问题的理解仍然相当零碎,所以我希望这里有人可以填补空白.
打瞌睡的持续时间
我在这里的实证研究结果
这些是官方的Android打瞌睡时期还是仅仅是一个经验观察.
以上所有在Android N设备上.
在打盹模式下测试应用程序
adb shell dumpsys battery unplugadb shell dumpsys battery reset 进入/退出打盹
屏幕关闭且设备未移动时发生
据推测,这会使用手机中的运动传感器,因此静静地坐在非常平稳行驶的火车上的电话仍会进入打瞌睡状态?
如果我拿起一个打瞌睡的电话并开始随意走动而没有与之交互,它会自动退出打瞌睡吗?
假设我的应用程序在其主机设备进入打盹时不在前台.然后我再次开始使用该设备,但没有访问该应用程序.它会自动重新开始"工作",即
它的广播接收器将成为功能?
它的处理程序将开始工作?
它的预定工作setRequiresDeviceIdle(true)将停止被调用?
打盹和作业调度的各种模式
根据我的理解,有两种打盹模式LIGHT&DEEP.它们都有子模式
LIGHT:活动,空闲,空闲_维护,覆盖.我不明白各种模式的作用.从亚行我发布step light了屏幕并看到了返回值ACTIVE.随着屏幕关闭step light返回IDLE.
DEEP:活动,IDLE_PENDING,SENSING,LOCATING,IDLE,IDLE_MAINTENANCE,屏幕也会返回,ACTIVE但屏幕关闭则返回IDLE_PENDING.那么当其他子模式完全正确时,IDLE,SENSING ......会发生吗?
我认为IDLE_MAINTENANCE当设备从DOZE进入维护窗口并尝试从各种应用程序运行挂起的作业请求时会发生这种情况.
但是,如果是这样的话,当我在我的应用程序中的计划作业运行时检查它们时,为什么会这样,PowerManager.isDeviceIdleMode()并且PowerManger.isPowerSaveMode() 总是返回false …
一切似乎都指向这两个命令:
adb shell dumpsys battery unplug
adb shell dumpsys deviceidle step
Run Code Online (Sandbox Code Playgroud)
我按照运行Marshmallow正式版的Nexus 6上的说明进行操作.我将手机插入我的测试机器.我设置了我的应用程序来测试我想用打瞌睡测试的作品.我关掉了我的屏幕.在battery unplug上面运行后我没有输出所以我认为它有效,但每次我运行deviceidle step输出总是Stepped to: ACTIVE.
我不确定它是否重要,但我正在尝试测试的应用程序的特殊功能是我设置的警报应该将手机从Doze中唤醒.我希望我的设备能够在我的PendingIntent计划AlarmManager.setAlarmClock中断时打瞌睡.这会阻止我的设备进入Doze吗?
android adb android-6.0-marshmallow android-doze-and-standby android-doze
目前我向用户询问有关节省电池电量的应用程序功能:
public void startSessionClick(View view) {
String token = MyApp.getInstance().getPrefToken();
if (!TextUtils.isEmpty(token)) {
throw new RuntimeException("Token is not empty");
}
//todo hot-fix
if (checkBatteryOptimization()) {
Intent intent = new Intent(this, AuthEnterPhoneActivity.class);
startActivityForResult(intent, REQUEST_CODE_ENTER_PHONE);
} else {
String packageName = getApplicationContext().getPackageName();
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
getApplicationContext().startActivity(intent);
//handleAnswer();
startSessionClick(null);
}
}
Run Code Online (Sandbox Code Playgroud)
如何追踪同意或拒绝对话?
在协议的那一刻,我只是打开下一个活动(在此之前检查库存设置),如果用户拒绝,则再次显示此对话框。
我需要的跟踪是在无法显示带有解释的对话框的情况下。
我有一个里程日志应用程序,可以进行GPS跟踪,并能够在后台建立与汽车的OBDII连接.
现在我想显示一个Popup,告诉用户我的应用程序是否在打盹中没有列入白名单,因为这可能会停止我的后台(实际上是前景)服务...
我做:
String PACKAGE_NAME = getApplicationContext().getPackageName();
PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
boolean status = false;
status = pm.isIgnoringBatteryOptimizations(PACKAGE_NAME);
if (!status) {
// show popup
}
Run Code Online (Sandbox Code Playgroud)
但是PowerManager.isIgnoringBatteryOptimizations总是返回'true',即使它再次从'Not optimized apps'中删除.只有当我卸载应用程序'false'时才会再次返回...在Galaxy Note 8(Android 8.0)和Emulator 8.1上测试
问题很简单:这是一个错误吗?或者如何从白名单中删除应用程序,以便PowerManager.isIgnoringBatteryOptimizations再次返回'false'?