====== Building Battery-Conscious Apps ====== Das ist mein Konspekt von dem Online-Kurs [[https://www.linkedin.com/learning/android-development-building-battery-conscious-apps|Android Development: Building Battery-Conscious Apps]]\\ ===== Introduction ===== ==== Why be battery conscious? ==== ... ===== 1. Basics of Battery Usage ===== ==== Principles of battery-concious apps ==== https://www.linkedin.com/learning/android-development-building-battery-conscious-apps/principles-of-battery-conscious-apps Wake-Up has costs: * CPU on * Screen on * Data (Wi-Fi or cellular) on Official documentation: http://developer.android.com/topic/performance/power/#lazy Smart Design (aka Lazy First design) - Reduce (e.g. resolution of photos for upload/download) - Defer - Coalesce (combining transactions to a "batch") - Rethink ===== 2. Battery Drain and Workarounds ===== ==== Considerations for using AlarmManager ==== https://www.linkedin.com/learning/android-development-building-battery-conscious-apps/considerations-for-using-alarmmanager * Schedule asynchronous operations * Time-based * Single or repetitive * Perfect for exact time-based scheduling * Periodic background tasks * Combined effects cause battery drain * Wake up has a cost ==== Pitfalls of poor AlarmManager usage ==== https://www.linkedin.com/learning/android-development-building-battery-conscious-apps/pitfalls-of-poor-alarmmanager-usage - Background network operations (AlarmManager does not have intelligent dispatch logic) - Alarms does not survive reboots (Extra logic required, e.g. BroadcastReceiver) - Exact Alarm may not be exact * Since Kitkat * setExactAndAllowWhileIdle -> is affected by Doze Mode - Doze Mode introduces complexity (e.g. ''setExact'' can drift) Takeaways: * Avoid network operations * Doze Mode affects AlarmManager * Maybe better would be to switch to JobScheduler (because it is not time driven, but event driven) ==== Considerations for using background-started services ==== https://www.linkedin.com/learning/android-development-building-battery-conscious-apps/considerations-for-using-background-started-services * Background Started Services * typically long running operations with no UI (e.g. music player) * started via an API call * contract: * client calls **Context.startService()** * system calls **Service.onStartCommand()** * Service stops * service stops itself with **Service.stopSelf()** * OR: * client calls **Service.stopService()** * System requires service to remain running until stopped explicitly * Note: in production **IntentService** would be better as simple **Service** * When to Use Background Started Service * intense, low-priority tasks not noticed by user * irregular, user-driven background tasks * stateless reentrant operations (e.g. refreshing news content) * work queue processor pattern (IntentService) * Note: if task is periodic scheduled job may be a better choice ==== Pitfalls of poor background-started service usage ==== https://www.linkedin.com/learning/android-development-building-battery-conscious-apps/pitfalls-of-poor-background-started-service-usage * Pitfall 1: Android * Google is tightening restrictions * Pitfall 2: No Rules or Policy Support * Connectivity checks * Active connection * Airplane mode * Remote server availability * Appropriateness checks * Battery level * Roaming status * Metered connection * Back off and retry policy * Retry when? * Retry how often? * Pitfall 3: No intelligent batching * No batching unlike AlarmManager * Cannot differentiate between services and different apps * Pitfall 4: Other reasons * Idle processes are wasteful * Fragmentation is a problem * Takeaway * Use job scheduler for most cases * Use started services for simple one-shot background tasks ==== A review of broadcast receivers ==== https://www.linkedin.com/learning/android-development-building-battery-conscious-apps/a-review-of-broadcast-receivers * Introduction to Broadcast Receivers * support event-driven programming * used for many system events * Interprocess communication (IPC) * delivered via Intent * Intents specify actions and optional extras * should extend **BroadcastReceiver** * should implement **onReceive()** ==== Registering a broadcast receiver ==== https://www.linkedin.com/learning/android-development-building-battery-conscious-apps/registering-a-broadcast-receiver * Statically registered (AndroidManifest.xml) * Dynamically registered (through the Java code) ==== Triggering a broadcast receiver ==== https://www.linkedin.com/learning/android-development-building-battery-conscious-apps/triggering-a-broadcast-receiver Two posibilities to trigger a broadcast receiver: - Call implicit trigger * Candidates matched via filter * Recipients unknown until match * Recipients may change - Explicit trigger * Invocation via code * Recipients known * Recipients never change * Any app can define its own intent Example of triggering explicitly: Intent i = new Intent("my.action.name") .setComponent(new ComponentName(context.getPackageName(), className)); context.setBroadcast(i); ==== Considerations of static implicit broadcast receivers ==== https://www.linkedin.com/learning/android-development-building-battery-conscious-apps/considerations-of-static-implicit-broadcast-receivers ===== Post Scriptum ===== This post scriptum is not based on the online course, but on other articles. ==== Intent to the settings, where you can move your app to the whitelist ==== From [[https://proandroiddev.com/android-battery-optimization-for-avoiding-doze-mode-and-app-standby-83cd379ee75b|Android Battery Optimization for Avoiding Doze Mode and App Standby]] 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); } }