이 글은 기존 운영했던 WordPress 블로그인 PyxisPub: Development Life (pyxispub.uzuki.live) 에서 가져온 글 입니다. 모든 글을 가져오지는 않으며, 작성 시점과 현재 시점에는 차이가 많이 존재합니다.
작성 시점: 2018-10-26
최근에 알람 앱을 개발할 일이 있었는데, Doze 모드로 들어가면 알람이 잘 안울리는 일이 있었다. 이 때 사용자에게 '배터리 최적화 예외'로 추가해달라고 요청을 해야되는데, 이 글에서는 간단하게 해당 방법을 알아보려 한다.
필요한 권한은 <uses-permission "android:name"="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
로 위험하지 않은 권한이니 AndroidManifest.xml에만 적어주면 된다.
Doze mode는 6.0 이상에서 구현되었으므로 그 이하에서는 체크할 필요가 없고, 그 전에 이미 배터리 예외 모드에 추가되어 있으면 요청할 필요가 없어진다.
이를 반영한 코드는 다음과 같다.
@SuppressLint({"BatteryLife", "InlinedApi"})
private void checkBatteryOptimization(Consumer<Boolean> callback) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // 버전 체크
Log.d(TAG, "checkBatteryOptimization: The version is too low to be checked.");
callback.accept(true);
return;
}
String packageName = getApplication().getPackageName();
// since REQUEST_IGNORE_BATTERY_OPTIMIZATIONS is **not** dangerous permission,
// but we need to check that app has \`REQUEST_IGNORE_BATTERY_OPTIMIZATIONS\` permission.
if (PackageManager.PERMISSION_GRANTED != getApplication().getPackageManager()
.checkPermission(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
getApplication().getPackageName())) { // 권한 체크
Log.d(TAG, "checkBatteryOptimization: application hasn't REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission");
return;
}
PowerManager powerManager = (PowerManager) getApplication().getSystemService(Context.POWER_SERVICE);
boolean ignoringBatteryOptimizations = powerManager.isIgnoringBatteryOptimizations(packageName);
if (ignoringBatteryOptimizations) { // 예외사항에 이미 추가되었는지 확인
Log.d(TAG, "checkBatteryOptimization: Already ignored Battery Optimizations.");
callback.accept(true);
return;
}
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse(String.format("package:%s", packageName)));
startActivity(intent);
}
마지막으로 사용하는 곳에서 체크하면 된다.
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume() {
checkBatteryOptimization(result -> DailyAlarmAnalyze.schedule());
}