如何在打盹模式的白名单应用程序Android 6.0

这个问题与Android 6.0 Preview 3有关,它将在本月底最终发布。

我在Nexus 5的“hammerhead”上的Google预览版3中testing了Android 6.0中的一些内容。

新function是“打盹模式” – 当networking被禁用和电话睡眠时,深度睡眠模式就像是深度睡眠模式,只有短信,通话或高优先级的GCM消息才能唤醒。 但是就像WhatsApp一样 – 在打盹模式下,接收到2小时以上的消息取决于定时器。 但是有一个名为“白名单”的“未优化”应用程序列表,您可以手动添加应用程序。

好吧,我想find一种方法来添加我的应用程序没有用户交互的程序在电池设置中的设备中存在的“白名单应用程序列表”。

试图用reflection进入它我发现:

android.os.IDeviceIdleController中有一个方法:

public abstract void addPowerSaveWhitelistApp(String packageNameOfApp)

但这是一个接口…所以我们不能做一个接口的实例。

还没有关于这个接口的文档,关于方法,或者任何inheritance树。

也许你有一些想法,我应该寻找一个可能性,以编程方式添加我的应用程序?

还有一个方法

公共抽象布尔isPowerSaveWhitelistApp(String packageName)

我认为应该有可能以某种方式访问​​?! 检查应用程序是否存在于白名单上,也可能在最后希望ASK用户将其添加到白名单。

所以我的问题是,有没有人试图做出更好的结果? 因为我卡住了,我认为它是一个死胡同。

更多信息: https : //newcircle.com/s/post/1739/2015/06/12/diving-into-android-m-doze

Solutions Collecting From Web of "如何在打盹模式的白名单应用程序Android 6.0"

在Android M预览版3上无法进行用户交互,禁用电池优化(=打盹模式的白名单应用程序)是不可能的。

这可以通过用户交互来完成:

Intent intent = new Intent(); String packageName = context.getPackageName(); PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); if (pm.isIgnoringBatteryOptimizations(packageName)) intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS); else { intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); intent.setData(Uri.parse("package:" + packageName)); } context.startActivity(intent); 

添加权限

 <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/> 

请求将您的应用列入白名单

  if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { Intent intent = new Intent(); String packageName = getPackageName(); PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); if (!pm.isIgnoringBatteryOptimizations(packageName)) { intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); intent.setData(Uri.parse("package:" + packageName)); startActivity(intent); } } 

据我所知,你不能从打瞌睡白名单。 忽略电池优化不会禁用打盹。 看到这里: https : //code.google.com/p/android-developer-preview/issues/detail? id = 2225更新:在M的发布版本,你可以请求忽略电池优化,这将至less让你正常在打盹模式下访问互联网。

我认为这个帮手类应该涵盖你所有的需求。

要使用它来请求操作系统白名单您的应用程序,您可以使用prepareIntentForWhiteListingOfBatteryOptimization。 如果你得到空,这意味着你不需要它,或者你不能使用它。 您可以使用其他function来查询您所处的状态。

 public class PowerSaverHelper { public enum PowerSaveState { ON, OFF, ERROR_GETTING_STATE, IRRELEVANT_OLD_ANDROID_API } public enum WhiteListedInBatteryOptimizations { WHITE_LISTED, NOT_WHITE_LISTED, ERROR_GETTING_STATE, UNKNOWN_TOO_OLD_ANDROID_API_FOR_CHECKING, IRRELEVANT_OLD_ANDROID_API } public enum DozeState { NORMAL_INTERACTIVE, DOZE_TURNED_ON_IDLE, NORMAL_NON_INTERACTIVE, ERROR_GETTING_STATE, IRRELEVANT_OLD_ANDROID_API, UNKNOWN_TOO_OLD_ANDROID_API_FOR_CHECKING } @NonNull public static DozeState getDozeState(@NonNull Context context) { if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) return DozeState.IRRELEVANT_OLD_ANDROID_API; if (VERSION.SDK_INT < VERSION_CODES.M) { return DozeState.UNKNOWN_TOO_OLD_ANDROID_API_FOR_CHECKING; } final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); if (pm == null) return DozeState.ERROR_GETTING_STATE; return pm.isDeviceIdleMode() ? DozeState.DOZE_TURNED_ON_IDLE : pm.isInteractive() ? DozeState.NORMAL_INTERACTIVE : DozeState.NORMAL_NON_INTERACTIVE; } @NonNull public static PowerSaveState getPowerSaveState(@NonNull Context context) { if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) return PowerSaveState.IRRELEVANT_OLD_ANDROID_API; final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); if (pm == null) return PowerSaveState.ERROR_GETTING_STATE; return pm.isPowerSaveMode() ? PowerSaveState.ON : PowerSaveState.OFF; } @NonNull public static WhiteListedInBatteryOptimizations getIfAppIsWhiteListedFromBatteryOptimizations(@NonNull Context context, @NonNull String packageName) { if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) return WhiteListedInBatteryOptimizations.IRRELEVANT_OLD_ANDROID_API; if (VERSION.SDK_INT < VERSION_CODES.M) return WhiteListedInBatteryOptimizations.UNKNOWN_TOO_OLD_ANDROID_API_FOR_CHECKING; final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); if (pm == null) return WhiteListedInBatteryOptimizations.ERROR_GETTING_STATE; return pm.isIgnoringBatteryOptimizations(packageName) ? WhiteListedInBatteryOptimizations.WHITE_LISTED : WhiteListedInBatteryOptimizations.NOT_WHITE_LISTED; } @TargetApi(VERSION_CODES.M) @RequiresPermission(permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) @Nullable public static Intent prepareIntentForWhiteListingOfBatteryOptimization(@NonNull Context context, @NonNull String packageName, boolean alsoWhenWhiteListed) { if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) return null; if (ContextCompat.checkSelfPermission(context, permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) == PackageManager.PERMISSION_DENIED) return null; final WhiteListedInBatteryOptimizations appIsWhiteListedFromPowerSave = getIfAppIsWhiteListedFromBatteryOptimizations(context, packageName); Intent intent = null; switch (appIsWhiteListedFromPowerSave) { case WHITE_LISTED: if (alsoWhenWhiteListed) intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS); break; case NOT_WHITE_LISTED: intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).setData(Uri.parse("package:" + packageName)); break; case ERROR_GETTING_STATE: case UNKNOWN_TOO_OLD_ANDROID_API_FOR_CHECKING: case IRRELEVANT_OLD_ANDROID_API: default: break; } return intent; } /** * registers a receiver to listen to power-save events. returns true iff succeeded to register the broadcastReceiver. */ @TargetApi(VERSION_CODES.M) public static boolean registerPowerSaveReceiver(@NonNull Context context, @NonNull BroadcastReceiver receiver) { if (VERSION.SDK_INT < VERSION_CODES.M) return false; IntentFilter filter = new IntentFilter(); filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); context.registerReceiver(receiver, filter); return true; } } 

UPDATE

当设备再次静止时,屏幕closures并接通电池一段时间,Doze会应用PowerManager.WakeLock,AlarmManager警报和GPS / Wi-Fi扫描的完整CPU和networking限制。

请访问使用案例以获取更多详细信息。

下表列出了请求或正在使用电池优化例外白名单的可接受用例。 一般来说,您的应用程序不应该在白名单上,除非打盹或应用程序待机中断应用程序的核心function,或者您的应用程序无法使用GCM高优先级消息的技术原因。

android n开发人员说

打瞌睡特别可能影响AlarmManager 报警计时器pipe理的活动 ,因为当系统处于打盹状态时Android 5.1(API等级22)或更低的报警不会触发

Android 6.0(API级别23)引入了两个新的AlarmManager方法: setAndAllowWhileIdle()setExactAndAllowWhileIdle() 。 使用这些方法,即使设备处于打盹状态,您也可以设置即将触发的警报。

注意setAndAllowWhileIdle()setExactAndAllowWhileIdle()都不能每个应用程序每15分钟触发一次警报。

testing与打盹和应用程序待机

如果我们拥有root权限,则可以通过编程方式完成白名单。 要在列入白名单的应用程序中添加设备,请运行以下命令:

 adb shell dumpsys deviceidle whitelist +<package_name> 

要从列入白名单的应用程序中删除设备,请运行以下命令

 adb shell dumpsys deviceidle whitelist -<package_name>