From 9fbd399c6598bc4aa3472aeb14f15570e713dc5a Mon Sep 17 00:00:00 2001 From: Joris de Groot Date: Tue, 24 Mar 2020 17:29:56 +0100 Subject: [PATCH 1/4] Added battery not low and storage not low as download requirements to Requirements Added monitoring battery and storage levels in RequirementsWatcher Added dependency on extension-workmanager to the demo app to be able to test with WorkManagerScheduler --- demos/main/build.gradle | 1 + .../ext/workmanager/WorkManagerScheduler.java | 8 ++ .../exoplayer2/offline/DownloadService.java | 26 +++++++ .../scheduler/PlatformScheduler.java | 7 ++ .../exoplayer2/scheduler/Requirements.java | 74 ++++++++++++++++++- .../scheduler/RequirementsWatcher.java | 8 ++ 6 files changed, 123 insertions(+), 1 deletion(-) diff --git a/demos/main/build.gradle b/demos/main/build.gradle index ab47b6de811..046e6df3302 100644 --- a/demos/main/build.gradle +++ b/demos/main/build.gradle @@ -70,6 +70,7 @@ dependencies { implementation project(modulePrefix + 'library-hls') implementation project(modulePrefix + 'library-smoothstreaming') implementation project(modulePrefix + 'library-ui') + withExtensionsImplementation project(path: modulePrefix + 'extension-workmanager') withExtensionsImplementation project(path: modulePrefix + 'extension-av1') withExtensionsImplementation project(path: modulePrefix + 'extension-ffmpeg') withExtensionsImplementation project(path: modulePrefix + 'extension-flac') diff --git a/extensions/workmanager/src/main/java/com/google/android/exoplayer2/ext/workmanager/WorkManagerScheduler.java b/extensions/workmanager/src/main/java/com/google/android/exoplayer2/ext/workmanager/WorkManagerScheduler.java index 97b132980d7..1162322432a 100644 --- a/extensions/workmanager/src/main/java/com/google/android/exoplayer2/ext/workmanager/WorkManagerScheduler.java +++ b/extensions/workmanager/src/main/java/com/google/android/exoplayer2/ext/workmanager/WorkManagerScheduler.java @@ -89,6 +89,14 @@ private static Constraints buildConstraints(Requirements requirements) { setRequiresDeviceIdle(builder); } + if (requirements.isBatteryNotLowRequired()) { + builder.setRequiresBatteryNotLow(true); + } + + if (requirements.isStorageNotLowRequired()) { + builder.setRequiresStorageNotLow(true); + } + return builder.build(); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java index 51f7fa3765d..63972b9a33a 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java @@ -26,6 +26,7 @@ import android.os.Looper; import androidx.annotation.Nullable; import androidx.annotation.StringRes; +import com.google.android.exoplayer2.scheduler.PlatformScheduler; import com.google.android.exoplayer2.scheduler.Requirements; import com.google.android.exoplayer2.scheduler.Scheduler; import com.google.android.exoplayer2.util.Assertions; @@ -658,6 +659,7 @@ public int onStartCommand(@Nullable Intent intent, int flags, int startId) { if (requirements == null) { Log.e(TAG, "Ignored SET_REQUIREMENTS: Missing " + KEY_REQUIREMENTS + " extra"); } else { + requirements = validateRequirements(requirements); downloadManager.setRequirements(requirements); } break; @@ -835,6 +837,30 @@ private static boolean needsStartedService(@Download.State int state) { || state == Download.STATE_RESTARTING; } + private Requirements validateRequirements(Requirements requirements) { + Requirements finalRequirements = requirements; + + if (Util.SDK_INT < 26 && getScheduler() instanceof PlatformScheduler) { + if (requirements.isBatteryNotLowRequired()) { + Log.w(TAG, "Can't set requirement for battery not low on the PlatformScheduler" + + "on API below 26. Requirement removed. Consider using the WorkManagerScheduler"); + int newRequirements = + finalRequirements.getRequirements() ^ Requirements.DEVICE_BATTERY_NOT_LOW; + finalRequirements = new Requirements(newRequirements); + } + + if (requirements.isStorageNotLowRequired()) { + Log.w(TAG, "Can't set requirement for storage not low on the PlatformScheduler" + + "on API below 26. Requirement removed. Consider using the WorkManagerScheduler"); + int newRequirements = + finalRequirements.getRequirements() ^ Requirements.DEVICE_STORAGE_NOT_LOW; + finalRequirements = new Requirements(newRequirements); + } + } + + return finalRequirements; + } + private static Intent getIntent( Context context, Class clazz, String action, boolean foreground) { return getIntent(context, clazz, action).putExtra(KEY_FOREGROUND, foreground); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/PlatformScheduler.java b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/PlatformScheduler.java index c4861abdf34..64699e130f1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/PlatformScheduler.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/PlatformScheduler.java @@ -103,6 +103,13 @@ private static JobInfo buildJobInfo( } builder.setRequiresDeviceIdle(requirements.isIdleRequired()); builder.setRequiresCharging(requirements.isChargingRequired()); + if (Util.SDK_INT >= 26) { + builder.setRequiresStorageNotLow(requirements.isStorageNotLowRequired()); + builder.setRequiresBatteryNotLow(requirements.isBatteryNotLowRequired()); + } else if (requirements.isStorageNotLowRequired() || requirements.isBatteryNotLowRequired()) { + Log.w(TAG, "Storage not low and battery not low requirements are only available on " + + "API 26 and up. Consider using the WorkManagerScheduler."); + } builder.setPersisted(true); PersistableBundle extras = new PersistableBundle(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java index 8919a26720c..33fc4a9cdff 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java @@ -45,7 +45,7 @@ public final class Requirements implements Parcelable { @Retention(RetentionPolicy.SOURCE) @IntDef( flag = true, - value = {NETWORK, NETWORK_UNMETERED, DEVICE_IDLE, DEVICE_CHARGING}) + value = {NETWORK, NETWORK_UNMETERED, DEVICE_IDLE, DEVICE_CHARGING, DEVICE_BATTERY_NOT_LOW, DEVICE_STORAGE_NOT_LOW}) public @interface RequirementFlags {} /** Requirement that the device has network connectivity. */ @@ -56,6 +56,16 @@ public final class Requirements implements Parcelable { public static final int DEVICE_IDLE = 1 << 2; /** Requirement that the device is charging. */ public static final int DEVICE_CHARGING = 1 << 3; + /** Requirement that the storage is not low. */ + public static final int DEVICE_STORAGE_NOT_LOW = 1 << 4; + /** Requirement that the battery is not low. */ + public static final int DEVICE_BATTERY_NOT_LOW = 1 << 5; + + /** Constant indicating the battery is not plugged in a power source */ + private static final int BATTERY_PLUGGED_NONE = 0; + /** Constant when the battery is considered low (in percentage) */ + private static final float BATTERY_LOW_PERCENTAGE = 0.15f; + @RequirementFlags private final int requirements; @@ -94,6 +104,14 @@ public boolean isIdleRequired() { return (requirements & DEVICE_IDLE) != 0; } + public boolean isStorageNotLowRequired() { + return (requirements & DEVICE_STORAGE_NOT_LOW) != 0; + } + + public boolean isBatteryNotLowRequired() { + return (requirements & DEVICE_BATTERY_NOT_LOW) != 0; + } + /** * Returns whether the requirements are met. * @@ -119,6 +137,12 @@ public int getNotMetRequirements(Context context) { if (isIdleRequired() && !isDeviceIdle(context)) { notMetRequirements |= DEVICE_IDLE; } + if (isBatteryNotLowRequired() && !isBatteryNotLow(context)) { + notMetRequirements |= DEVICE_BATTERY_NOT_LOW; + } + if (isStorageNotLowRequired() && !isStorageNotLow(context)) { + notMetRequirements |= DEVICE_STORAGE_NOT_LOW; + } return notMetRequirements; } @@ -162,6 +186,54 @@ private boolean isDeviceIdle(Context context) { : Util.SDK_INT >= 20 ? !powerManager.isInteractive() : !powerManager.isScreenOn(); } + /** + * Implementation taken from the the WorkManager source. + * @see StorageNotLowTracker + */ + private boolean isBatteryNotLow(Context context) { + IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); + Intent intent = context.registerReceiver(null, intentFilter); + if (intent == null) { + return true; + } + int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, BATTERY_PLUGGED_NONE); + int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); + int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); + int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); + float batteryPercentage = level / (float) scale; + return (plugged != BATTERY_PLUGGED_NONE + || status == BatteryManager.BATTERY_STATUS_UNKNOWN + || batteryPercentage > BATTERY_LOW_PERCENTAGE); + } + + /** + * Implementation taken from the the WorkManager source. + * @see BatteryNotLowTracker + */ + private boolean isStorageNotLow(Context context) { + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); + intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW); + Intent intent = context.registerReceiver(null, intentFilter); + if (intent == null || intent.getAction() == null) { + // ACTION_DEVICE_STORAGE_LOW is a sticky broadcast that is removed when sufficient + // storage is available again. ACTION_DEVICE_STORAGE_OK is not sticky. So if we + // don't receive anything here, we can assume that the storage state is okay. + return true; + } else { + switch (intent.getAction()) { + case Intent.ACTION_DEVICE_STORAGE_OK: + return true; + case Intent.ACTION_DEVICE_STORAGE_LOW: + return false; + default: + // This should never happen because the intent filter is configured + // correctly. + return true; + } + } + } + private static boolean isInternetConnectivityValidated(ConnectivityManager connectivityManager) { // It's possible to query NetworkCapabilities from API level 23, but RequirementsWatcher only // fires an event to update its Requirements when NetworkCapabilities change from API level 24. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java index 797b7f71709..84093191c37 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java @@ -104,6 +104,14 @@ public int start() { filter.addAction(Intent.ACTION_SCREEN_OFF); } } + if (requirements.isStorageNotLowRequired()) { + filter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW); + filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); + } + if (requirements.isBatteryNotLowRequired()) { + filter.addAction(Intent.ACTION_BATTERY_LOW); + filter.addAction(Intent.ACTION_BATTERY_OKAY); + } receiver = new DeviceStatusChangeReceiver(); context.registerReceiver(receiver, filter, null, handler); return notMetRequirements; From 36d11e518f3afed1be3b0862795f7064a6f6d71c Mon Sep 17 00:00:00 2001 From: Joris de Groot Date: Tue, 31 Mar 2020 10:03:18 +0200 Subject: [PATCH 2/4] Fixed linking to sources in battery and storage monitoring --- .../com/google/android/exoplayer2/scheduler/Requirements.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java index 33fc4a9cdff..7b9e3f38e93 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java @@ -188,7 +188,7 @@ private boolean isDeviceIdle(Context context) { /** * Implementation taken from the the WorkManager source. - * @see StorageNotLowTracker + * @see BatteryNotLowTracker */ private boolean isBatteryNotLow(Context context) { IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); @@ -208,7 +208,7 @@ private boolean isBatteryNotLow(Context context) { /** * Implementation taken from the the WorkManager source. - * @see BatteryNotLowTracker + * @see StorageNotLowTracker */ private boolean isStorageNotLow(Context context) { IntentFilter intentFilter = new IntentFilter(); From 6ddd9046337d3449fe4651bcbb324c5ecbfa9c51 Mon Sep 17 00:00:00 2001 From: Joris de Groot Date: Tue, 28 Apr 2020 13:36:15 +0200 Subject: [PATCH 3/4] Added getSupportedRequirements method to Scheduler interface Implemented getSupportedRequirements for schedulers --- .../jobdispatcher/JobDispatcherScheduler.java | 29 +++++++++++++++++++ .../ext/workmanager/WorkManagerScheduler.java | 15 ++++++++++ .../exoplayer2/offline/DownloadService.java | 29 +++---------------- .../scheduler/PlatformScheduler.java | 27 +++++++++++++++-- .../exoplayer2/scheduler/Scheduler.java | 9 ++++++ 5 files changed, 82 insertions(+), 27 deletions(-) diff --git a/extensions/jobdispatcher/src/main/java/com/google/android/exoplayer2/ext/jobdispatcher/JobDispatcherScheduler.java b/extensions/jobdispatcher/src/main/java/com/google/android/exoplayer2/ext/jobdispatcher/JobDispatcherScheduler.java index 8841f8355fc..a10f03f5e21 100644 --- a/extensions/jobdispatcher/src/main/java/com/google/android/exoplayer2/ext/jobdispatcher/JobDispatcherScheduler.java +++ b/extensions/jobdispatcher/src/main/java/com/google/android/exoplayer2/ext/jobdispatcher/JobDispatcherScheduler.java @@ -96,6 +96,27 @@ public boolean cancel() { return result == FirebaseJobDispatcher.CANCEL_RESULT_SUCCESS; } + @Override + public Requirements getSupportedRequirements(Requirements requirements) { + Requirements supportedRequirements = requirements; + if (requirements.isBatteryNotLowRequired()) { + Log.w(TAG, "Battery not low requirement not supported on the JobDispatcherScheduler " + + "Requirement removed."); + int newRequirements = + supportedRequirements.getRequirements() ^ Requirements.DEVICE_BATTERY_NOT_LOW; + supportedRequirements = new Requirements(newRequirements); + } + + if (requirements.isStorageNotLowRequired()) { + Log.w(TAG, "Storage not low requirement not supported on the JobDispatcherScheduler " + + "Requirement removed."); + int newRequirements = + supportedRequirements.getRequirements() ^ Requirements.DEVICE_STORAGE_NOT_LOW; + supportedRequirements = new Requirements(newRequirements); + } + return supportedRequirements; + } + private static Job buildJob( FirebaseJobDispatcher dispatcher, Requirements requirements, @@ -120,6 +141,14 @@ private static Job buildJob( if (requirements.isChargingRequired()) { builder.addConstraint(Constraint.DEVICE_CHARGING); } + + if (requirements.isBatteryNotLowRequired()) { + Log.w(TAG, "Battery not low requirement is not supported on the JobDispatcherScheduler"); + } + if (requirements.isStorageNotLowRequired()) { + Log.w(TAG, "Storage not low requirement is not supported on the JobDispatcherScheduler"); + } + builder.setLifetime(Lifetime.FOREVER).setReplaceCurrent(true); Bundle extras = new Bundle(); diff --git a/extensions/workmanager/src/main/java/com/google/android/exoplayer2/ext/workmanager/WorkManagerScheduler.java b/extensions/workmanager/src/main/java/com/google/android/exoplayer2/ext/workmanager/WorkManagerScheduler.java index 1162322432a..5e03534d3ca 100644 --- a/extensions/workmanager/src/main/java/com/google/android/exoplayer2/ext/workmanager/WorkManagerScheduler.java +++ b/extensions/workmanager/src/main/java/com/google/android/exoplayer2/ext/workmanager/WorkManagerScheduler.java @@ -87,6 +87,8 @@ private static Constraints buildConstraints(Requirements requirements) { if (requirements.isIdleRequired() && Util.SDK_INT >= 23) { setRequiresDeviceIdle(builder); + } else if (requirements.isIdleRequired()) { + Log.w(TAG, "Is idle requirements is only available on API 23 and up."); } if (requirements.isBatteryNotLowRequired()) { @@ -116,6 +118,19 @@ private static Data buildInputData( return builder.build(); } + @Override + public Requirements getSupportedRequirements(Requirements requirements) { + Requirements supportedRequirements = requirements; + if (requirements.isIdleRequired() && Util.SDK_INT < 23) { + Log.w(TAG, "Is idle requirement not supported on the WorkManagerScheduler on API below 23. " + + "Requirement removed."); + int newRequirements = + supportedRequirements.getRequirements() ^ Requirements.DEVICE_IDLE; + supportedRequirements = new Requirements(newRequirements); + } + return supportedRequirements; + } + private static OneTimeWorkRequest buildWorkRequest(Constraints constraints, Data inputData) { OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(SchedulerWorker.class); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java index 63972b9a33a..5d8983a1d8f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java @@ -659,7 +659,10 @@ public int onStartCommand(@Nullable Intent intent, int flags, int startId) { if (requirements == null) { Log.e(TAG, "Ignored SET_REQUIREMENTS: Missing " + KEY_REQUIREMENTS + " extra"); } else { - requirements = validateRequirements(requirements); + @Nullable Scheduler scheduler = getScheduler(); + if (scheduler != null) { + requirements = scheduler.getSupportedRequirements(requirements); + } downloadManager.setRequirements(requirements); } break; @@ -837,30 +840,6 @@ private static boolean needsStartedService(@Download.State int state) { || state == Download.STATE_RESTARTING; } - private Requirements validateRequirements(Requirements requirements) { - Requirements finalRequirements = requirements; - - if (Util.SDK_INT < 26 && getScheduler() instanceof PlatformScheduler) { - if (requirements.isBatteryNotLowRequired()) { - Log.w(TAG, "Can't set requirement for battery not low on the PlatformScheduler" - + "on API below 26. Requirement removed. Consider using the WorkManagerScheduler"); - int newRequirements = - finalRequirements.getRequirements() ^ Requirements.DEVICE_BATTERY_NOT_LOW; - finalRequirements = new Requirements(newRequirements); - } - - if (requirements.isStorageNotLowRequired()) { - Log.w(TAG, "Can't set requirement for storage not low on the PlatformScheduler" - + "on API below 26. Requirement removed. Consider using the WorkManagerScheduler"); - int newRequirements = - finalRequirements.getRequirements() ^ Requirements.DEVICE_STORAGE_NOT_LOW; - finalRequirements = new Requirements(newRequirements); - } - } - - return finalRequirements; - } - private static Intent getIntent( Context context, Class clazz, String action, boolean foreground) { return getIntent(context, clazz, action).putExtra(KEY_FOREGROUND, foreground); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/PlatformScheduler.java b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/PlatformScheduler.java index 64699e130f1..7415021802c 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/PlatformScheduler.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/PlatformScheduler.java @@ -86,6 +86,29 @@ public boolean cancel() { return true; } + @Override + public Requirements getSupportedRequirements(Requirements requirements) { + Requirements supportedRequirements = requirements; + if (Util.SDK_INT < 26) { + if (requirements.isBatteryNotLowRequired()) { + Log.w(TAG, "Battery not low requirement not supported on the PlatformScheduler" + + "on API below 26. Requirement removed."); + int newRequirements = + supportedRequirements.getRequirements() ^ Requirements.DEVICE_BATTERY_NOT_LOW; + supportedRequirements = new Requirements(newRequirements); + } + + if (requirements.isStorageNotLowRequired()) { + Log.w(TAG, "Storage not low requirement not supported on the PlatformScheduler" + + "on API below 26. Requirement removed."); + int newRequirements = + supportedRequirements.getRequirements() ^ Requirements.DEVICE_STORAGE_NOT_LOW; + supportedRequirements = new Requirements(newRequirements); + } + } + return supportedRequirements; + } + // @RequiresPermission constructor annotation should ensure the permission is present. @SuppressWarnings("MissingPermission") private static JobInfo buildJobInfo( @@ -107,8 +130,8 @@ private static JobInfo buildJobInfo( builder.setRequiresStorageNotLow(requirements.isStorageNotLowRequired()); builder.setRequiresBatteryNotLow(requirements.isBatteryNotLowRequired()); } else if (requirements.isStorageNotLowRequired() || requirements.isBatteryNotLowRequired()) { - Log.w(TAG, "Storage not low and battery not low requirements are only available on " - + "API 26 and up. Consider using the WorkManagerScheduler."); + Log.w(TAG, "Storage not low and battery not low requirements are only available on API 26" + + " and up."); } builder.setPersisted(true); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Scheduler.java b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Scheduler.java index b5a6f404247..bcbd7420b0e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Scheduler.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Scheduler.java @@ -45,4 +45,13 @@ public interface Scheduler { * @return Whether cancellation was successful. */ boolean cancel(); + + /** + * Checks if this {@link Scheduler} supports the provided {@link Requirements}. If all + * requirements are supported the same object is returned. If not all requirements are + * supported a new {@code Requirements} object is returned containing the supported requirements. + * @param requirements The requirements to check. + * @return The requirements supported by this scheduler. + */ + Requirements getSupportedRequirements(Requirements requirements); } From 4299342895a244e339145d4ed33ec8a6a5659d89 Mon Sep 17 00:00:00 2001 From: Joris de Groot Date: Wed, 29 Apr 2020 11:05:32 +0200 Subject: [PATCH 4/4] Changed intent filter for battery not low to listen to the ACTION_BATTERY_CHANGED action --- .../android/exoplayer2/scheduler/RequirementsWatcher.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java index 84093191c37..07401e7b9a9 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java @@ -109,8 +109,7 @@ public int start() { filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); } if (requirements.isBatteryNotLowRequired()) { - filter.addAction(Intent.ACTION_BATTERY_LOW); - filter.addAction(Intent.ACTION_BATTERY_OKAY); + filter.addAction(Intent.ACTION_BATTERY_CHANGED); } receiver = new DeviceStatusChangeReceiver(); context.registerReceiver(receiver, filter, null, handler);