Cómo aplicación WhiteList en modo Doze Android 6.0

Esta pregunta está relacionada con la vista previa de Android 6.0 3, que se lanzará finalmente a fines de este mes.

Estoy probando algunas cosas en Android 6.0 en la vista previa 3 de Google en Nexus 5 ‘hammerhead’.

La nueva característica es el “modo dormido”: algo así como el modo de suspensión profunda cuando la red está desactivada y el teléfono duerme, solo los mensajes SMS, llamadas o GCM de alta prioridad pueden activarlo. Pero como WhatsApp, en el modo dormido recibe los mensajes después de 2 horas o más dependiendo de los temporizadores. Pero hay una lista de aplicaciones “no optimizadas” llamada “lista blanca” donde puede agregar aplicaciones manualmente.

Ok, me gustaría encontrar una forma de agregar mi aplicación programáticamente sin interacción del usuario a la “lista de aplicaciones de la lista blanca” que existe en el dispositivo en la configuración de la batería.

Tratando de usar el reflection para entrar, encontré:

Dentro del android.os.IDeviceIdleController hay un método:

public abstract void addPowerSaveWhitelistApp (String packageNameOfApp)

Pero esta es una interfaz … Entonces no podemos crear una instancia de interfaz.

Todavía no hay documentación sobre esta interfaz o sobre métodos, o sobre cualquier árbol de herencia.

¿Quizás tengas alguna idea de dónde debería buscar una posibilidad de agregar programáticamente mi aplicación?

También hay un método

public abstract boolean isPowerSaveWhitelistApp (String packageName)

¿Cuál creo que debería ser posible acceder de alguna manera? para verificar si la aplicación existe en la Lista blanca y tal vez al final esperemos que el usuario ASK la agregue a la Lista blanca.

Entonces mi pregunta es, ¿alguien de ustedes intentó hacer algo con un mejor resultado? porque estoy atascado y creo que es un callejón sin salida.

para más información: https://newcircle.com/s/post/1739/2015/06/12/diving-into-android-m-doze

No es posible deshabilitar las optimizaciones de la batería (= aplicación de la lista blanca para el modo doze) sin la interacción del usuario en la vista previa de Android M 3.

Se puede hacer con la interacción del usuario de esta manera:

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); 

Agregar permiso

  

solicitar una lista blanca de tu aplicación

  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); } } 

Creo que esta clase de ayuda debería cubrir todas tus necesidades.

Para usarlo para solicitar al sistema operativo que haga una lista blanca de su aplicación, puede usar prepareIntentForWhiteListingOfBatteryOptimization. Si obtienes nulo, significa que no lo necesitas o que no puedes usarlo. Puede usar la otra función para consultar un mejor estado de lo que se encuentra.

 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; } } 

Por lo que sé, no puedes incluirte en la lista blanca de Doze. Ignorar las optimizaciones de la batería no deshabilita el sopor. Consulte aquí: https://code.google.com/p/android-developer-preview/issues/detail?id=2225 ACTUALIZACIÓN: en la comstackción de lanzamiento de M, puede solicitar que se ignoren las optimizaciones de la batería que, al menos, le darán la normalidad acceso a internet mientras está en modo Doze.

ACTUALIZAR

Cuando el dispositivo está parado nuevamente, con la pantalla apagada y encendida la batería durante un período de tiempo, Doze aplica las restricciones de red y CPU completas en PowerManager.WakeLock, alarmas AlarmManager y escaneos de GPS / Wi-Fi .

Visite Casos de uso para la inclusión en listas blancas para obtener más detalles.

La siguiente tabla destaca los casos de uso aceptables para solicitar o estar en la lista blanca de excepciones de Optimizaciones de la batería. En general, su aplicación no debe estar en la lista blanca a menos que Doze o App Standby rompan la función central de la aplicación o que haya una razón técnica por la cual su aplicación no puede usar mensajes de alta prioridad de GCM.

android n desarrollador dice

Es muy probable que Doze afecte las actividades que las alarmas y los temporizadores de AlarmManager administran , ya que las alarmas en Android 5.1 (nivel API 22) o inferiores no se activan cuando el sistema está en Doze .

Android 6.0 (nivel de API 23) presenta dos nuevos métodos de setAndAllowWhileIdle() : setAndAllowWhileIdle() y setExactAndAllowWhileIdle() . Con estos métodos, puede configurar alarmas que se dispararán incluso si el dispositivo está en Doze.

Nota : ni setAndAllowWhileIdle() ni setExactAndAllowWhileIdle() pueden disparar alarmas más de una vez cada 15 minutos por aplicación.

Pruebas con Doze y App Standby

Si tenemos permisos de raíz, entonces la lista blanca se puede hacer programáticamente. Para agregar un dispositivo en aplicaciones incluidas en la lista blanca, ejecute el siguiente comando desde la aplicación:

 adb shell dumpsys deviceidle whitelist + 

Para eliminar el dispositivo de las aplicaciones incluidas en la lista blanca, ejecute el siguiente comando desde la aplicación:

 adb shell dumpsys deviceidle whitelist -