在Android "N“中,Doze被扩展为"Doze on the Go”。
我正在寻找一种方法来检测设备何时进入和离开这些新的轻睡眠空闲和IDLE_MAINTENANCE状态。(基本上与常规Doze here问的问题相同。)
发布于 2017-06-17 04:58:39
TrevorWiley的答案中的实现是有效的,但可以简化一点。是的,牛油果的PowerManager有isLightDeviceIdleMode(),并且用@hide进行了注释。我们可以使用反射来调用它,这更加简洁,并且独立于PowerManager的内部实现细节。
public static boolean isLightDeviceIdleMode(final Context context) {
boolean result = false;
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (pm != null) {
try {
Method isLightDeviceIdleModeMethod = pm.getClass().getDeclaredMethod("isLightDeviceIdleMode");
result = (boolean)isLightDeviceIdleModeMethod.invoke(pm);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
Log.e(TAG, "Reflection failed for isLightDeviceIdleMode: " + e.toString(), e);
}
}
return result;
}主要同意TrevorWiley使用字符串注册广播。与上面的方法相同,您可以使用反射来获取字段ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED的值并回退到硬编码的字符串"android.os.action.LIGHT_DEVICE_IDLE_MODE_CHANGED"。
发布于 2016-09-16 02:49:48
PowerManager的在线文档没有提到这一点,但最新的源代码(API24修订版1)看起来应该是这个问题的解决方案:
String ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED
= "android.os.action.LIGHT_DEVICE_IDLE_MODE_CHANGED"
boolean isLightDeviceIdleMode()理论上,您可以简单地注册一些代码作为意图的接收者,并检查函数的当前值。对dumpsys activity broadcasts的一些探索表明,意图确实是在轻微打瞌睡状态改变时发送的。
然而,最新的软件开发工具包平台(API24修订版2)中没有这些符号--我得到了编译错误(并且一些javap和jar显示它们确实不存在)。联系谷歌,我们被告知这是预期的设计。
有一个变通办法,那就是对上面提到的相同字符串进行硬编码,然后使用反射来调用在API中调用的相同函数。如下所示:
/**
* Check if the device is currently in the Light IDLE mode.
*
* @param context The application context.
* @return True if the device is in the Light IDLE mode.
*/
public static boolean isLightDeviceIdleMode(final Context context) {
boolean result = false;
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (pm != null) {
// result = pm.isLightDeviceIdleMode();
try {
Log.d(TAG, "Trying reflection for isLightDeviceIdleMode");
Field pmServiceField = pm.getClass().getDeclaredField("mService");
pmServiceField.setAccessible(true);
Object pmService = pmServiceField.get(pm);
Method isLightDeviceIdleMode = pmService.getClass().getDeclaredMethod("isLightDeviceIdleMode");
isLightDeviceIdleMode.setAccessible(true);
result = (Boolean) isLightDeviceIdleMode.invoke(pmService);
} catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
Log.e(TAG, "Reflection failed for isLightDeviceIdleMode: " + e.toString());
} catch (RemoteException re) {
Log.e(TAG, "Remote exception checking isLightDeviceIdleMode: " + e.toString());
}
}
return result;
}https://stackoverflow.com/questions/39478974
复制相似问题