Why contributing?
ecoCode core relies on the number and quality of its rules. That's why the procurement of an exhaustive list of sustainable rules cannot occur without the external contribution from a skilled and passionate community. We need your know-how! Each submitted rule is in-depth evaluated and qualified to boost the ecoCode project!
Wish to be a first-class actor in "Green IT" by bringing out ethics in IT business? > Propose your "own" rules, this way...
All rules
11 December 2020
Olivier Le Goaer
android
java
kotlin
Thrifty Motion Sensor
The rotation vector sensor is the most frequently used sensor for motion detection and monitoring. When using SensorManager#getDefaultSensor(int type), always prefer the constant TYPE_GEOMAGNETIC_ROTATION_VECTOR which is similar to TYPE_ROTATION_VECTOR, but using a magnetometer instead of using a gyroscope. This sensor uses lower power than the other rotation vectors, because it doesn't use the gyroscope. However, it is more noisy and will work best outdoors.
11 December 2020
Olivier Le Goaer
android
java
Uncompressed Data Transmission
Transmitting a file over a network infrastructure without compressing it consumes more energy than with compression. More precisely, energy efficiency is improved in case the data is compressed at least by 10%, transmitted and decompressed at the other network node. From the Android client side, it means making a post HTTP request using a GZIPOutputStream instead of the classical OutputStream, along with the HttpURLConnection object.
11 December 2020
Olivier Le Goaer
android
java
Internet In The Loop
Opening and closing internet connection continuously is extremely battery-inefficient since HTTP exchange is the most consuming operation of the network. This bug typically occurs when one obtain a new HttpURLConnection by calling URL#openConnection() within a loop control structure (while, for, do-while, for-each). Also, this bad practice must be early prevented because it is the root of another evil that consists in polling data at regular intervals, instead of using push notifications to save a lot of battery power.
11 December 2020
Olivier Le Goaer
android
java
Everlasting Service
If someone calls Context#startService() then the system will retrieve the service (creating it and calling its onCreate() method if needed) and then call its onStartCommand(Intent, int, int) method with the arguments supplied by the client. The service will at this point continue running until Context#stopService() or Service#stopSelf() is called. Failing to call any of these methods can lead to uncontrolled energy leakage.
11 December 2020
Olivier Le Goaer
android
java
Sensor Leak
Most Android-powered devices have built-in sensors that measure motion, orientation, and various environmental conditions. In addition to these are the image sensor (a.k.a Camera) and the geopositioning sensor (a.k.a GPS). The common point of all these sensors is that they are expensive while in use. Their common bug is to let the sensor unnecessarily process data when the app enters an idle state, typically when paused or stopped. Consequently, calls must be carefully pairwised: SensorManager#registerListener()/unregisterListener() for regular sensors, Camera#open()/Camera#release() for the camera and LocationManager#requestLocationUpdates()/removeUpdates() for the GPS. Failing to do so can drain the battery in just a few hours.
11 December 2020
Olivier Le Goaer
android
java
Media Leak
Creation of a Media Recorder object with new MediaRecorder() is used to record audio and video, while creation of a Media Player object with new MediaPlayer() can be used to control playback of audio/video files and streams. Both classes own a release() method. In addition to unnecessary resources (such as memory and instances of codecs) being held, failure to call this method immediately if a media object is no longer needed may also lead to continuous battery consumption for mobile devices.
11 December 2020
Olivier Le Goaer
android
java
Bluetooth Low-Energy
In contrast to classic Bluetooth, Bluetooth Low Energy (BLE) is designed to provide significantly lower power consumption. Its purpose is to save energy on both paired devices but very few developers are aware of this alternative API. From the Android client side, it means append android.bluetooth.le.* imports to android.bluetooth.* imports in order to benefits from low-energy features.
11 December 2020
Olivier Le Goaer
android
java
Wifi Multicast Lock
Normally the Wifi stack filters out packets not explicitly addressed to the device. Acquiring a Multicast Lock with WifiManager.MulticastLock#acquire() will cause the stack to receive packets addressed to multicast addresses. Processing these extra packets can cause a noticeable battery drain and must be disabled when not needed with to a call to WifiManager.MulticastLock#release().
11 December 2020
Olivier Le Goaer
android
java
Uncached Data Reception
Caching all of the application's HTTP responses to the filesystem (application-specific cache directory) so they may be reused, allow to save energy. To that purpose the class HttpResponseCachesupports HttpURLConnection and HttpsURLConnection; there is no platform-provided cache for further clients. Installing the cache at application startup is done with the static method HttpResponseCache.install(File directory, long maxSize).
11 December 2020
Olivier Le Goaer
android
java
kotlin
Dark UI
Developers are allowed to apply native themes for their app, or derive new ones throught inheritence. This decision has a significant impact on energy consumption since displaying dark colors is particularly beneficial for mobile devices with (AM)OLED screens. By default Android will set Holo to the Dark theme (parent style Theme.Holo) and hence switching to the light theme (parent style Theme.Holo.Light) within the manifest should be avoided. To a lesser extent, use of bitmap images with too high luminance should be avoided. In order to support Dark theme (Android 9 and later), you must set your app's theme to inherit from a DayNight theme (parent style Theme.AppCompat.DayNight).
11 December 2020
Olivier Le Goaer
android
java
kotlin
Thrifty Geolocation
Location awareness is one of the most popular features used by apps. The first thing is to try to get the best possible provider (LocationManager#getBestProvider()) based on an energy criteria thanks to Criteria#setPowerRequirement(int level), using constant POWER_LOW instead of POWER_HIGH or POWER_MEDIUM. Next, with a call to LocationManager#requestLocationUpdates (long minTime, float minDistance, Criteria criteria, PendingIntent intent), the provider will only send your application an update when the location has changed by at least minDistance meters, AND at least minTime milliseconds have passed. So minTime should be the primary tool to conserving battery life, and, to a lesser extent, minDistance, these two must be imperatively greater than 0.
11 December 2020
Olivier Le Goaer
android
java
kotlin
Thrifty BLE
With Bluetooth Low Energy technology (see BLE API bugs), a Bluetooth Smart Ready device (the master) will establish a link with a Bluetooth Smart device (the slave). Most often, the slave is a GATT server and the master is a GATT client. GATT capable devices can be discovered using BLE scan process. So you should always use BluetoothLeScanner#startScan() with the scan settings set to SCAN_MODE_LOW_POWER (Default scan mode). In addition, invoke BluetoothGatt#requestConnectionPriority(int connectionPriority) with the value CONNECTION_PRIORITY_LOW_POWER. Lastly, the default and preferred advertising mode is ADVERTISE_MODE_LOW_POWER when calling AdvertiseSettings.Builder#setAdvertiseMode(int advertiseMode).
11 December 2020
Olivier Le Goaer
android
java
kotlin
Keep Screen On
To avoid draining the battery, an Android device that is left idle quickly falls asleep. Hence, keeping the screen on should be avoided, unless it is absolutely necessary. If so, developers typically use a Power Manager system service feature called wake locks by invoking PowerManager.WakeLock#newWakeLock(int levelAndFlags, String tag), along with the specific permission WAKE_LOCK in their manifest.
11 December 2020
Olivier Le Goaer
android
java
kotlin
Durable Wake Lock
A wake lock is a mechanism to indicate that your application needs to have the device stay on. The general principle is to obtain a wake lock, acquire it and finally release it. Hence, the challenge here is to release the lock as soon as possible to avoid running down the device's battery excessively. Missing call to PowerManager#release() is a built-in check of Android lint (Wakelock check) but that does not prevent abuse of the lock over too long a period of time. This can be avoided by a call to PowerManager#acquire(long timeout) instead of PowerManager#acquire(), because the lock will be released for sure after the given timeout expires.
11 December 2020
Olivier Le Goaer
android
java
kotlin
Rigid Alarm
Applications are strongly discouraged from using exact alarms unnecessarily as they reduce the OS's ability to minimize battery use (i.e. Doze Mode). For most apps prior to API 19, setInexactRepeating() is preferable over setRepeating(). When you use this method, Android synchronizes multiple inexact repeating alarms and fires them at the same time, thus reducing the battery drain. Similarly, setExact() and setExactAndAllowWhileIdle() can significantly impact the power use of the device when idle, so they should be used with care. High-frequency alarms are also bad for battery life but this is already checked by Android lint (ShortAlarm built-in check).
11 December 2020
Olivier Le Goaer
android
java
kotlin
Continous Rendering
For developers wishing to display OpenGL rendering, when choosing the rendering mode with GLSurfaceView#setRenderMode(int renderMode), using RENDERMODE_WHEN_DIRTY instead of RENDERMODE_CONTINUOUSLY (By default) can improve battery life and overall system performance by allowing the GPU and CPU to idle when the view does not need to be updated.
11 December 2020
Olivier Le Goaer
android
java
kotlin
Keep Voice Awake
During a voice interaction session, VoiceInteractionSession#setKeepAwake(boolean keepAwake) allows to decide whether it will keep the device awake while it is running a voice activity. By default, the system holds a wake lock for it while in this state, so that it can work even if the screen is off. Setting this to false removes that wake lock, allowing the CPU to go to sleep and hence does not let this continue to drain the battery.
11 December 2020
Olivier Le Goaer
android
java
kotlin
Companion in background
A negative effect on the device's battery is when an app is paired with a companion device (over Bluetooth, BLE, or Wi-Fi) and that it has been excluded from battery optimizations (run in the background) using the declaration Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND.
11 December 2020
Olivier Le Goaer
android
java
kotlin
Ignore Battery Optimizations
An app holding the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS ask the user to allow it to ignore battery optimizations (that is, put them on the whitelist of apps). Most applications should not use this; there are many facilities provided by the platform for applications to operate correctly in the various power saving modes.
11 December 2020
Olivier Le Goaer
android
java
kotlin
Power Awareness
It's always good that an app has different behavior when device is connected/disconnected to a power station, or has different battery levels. Therefore, their absence in the code gives hints on the fact that the app is not energy optimized. The first situation requires a broadcast receiver registered on the actions ACTION_POWER_CONNECTED, ACTION_POWER_DISCONNECTED or just ACTION_POWER_SAVE_MODE_CHANGED. The second situation simply requires calls to PowerManager#isPowerSaveMode().
11 December 2020
Olivier Le Goaer
android
java
kotlin
Keep CPU On
To avoid draining the battery, an Android device that is left idle quickly falls asleep. Hence, keeping the CPU on should be avoided, unless it is absolutely necessary. If so, developers typically use the FLAG_KEEP_SCREEN_ON in their activity. Another way to implement this is in their application's layout XML file, by using the android:keepScreenOn attribute.
11 December 2020
Olivier Le Goaer
android
java
kotlin
Service@Boot-time
Services are long-living operations, as components of the apps. However, they can be started in isolation each time the device is next started, without the user's acknowledgement. This technique should be discouraged because the accumulation of these silent services results in excessive battery depletion that remains unexplained from the end-user's point of view. In addition, end-users know how to kill applications, but more rarely how to kill services. Thus, any developer should avoid having a call to Context#startService() from a Broadcast Receiver component that has specified an intent-filter for the BOOT_COMPLETED action in the manifest.
11 December 2020
Olivier Le Goaer
android
java
kotlin
Sensor Coalesce
With SensorManager#registerListener(SensorEventListener, Sensor, int) the events are delivered as soon as possible. Instead, SensorManager#registerListener(SensorEventListener, Sensor, int, int maxReportLatencyUs) allows events to stay temporarily in the hardware FIFO (queue) before being delivered. The events can be stored in the hardware FIFO up to maxReportLatencyUs microseconds. Once one of the events in the FIFO needs to be reported, all of the events in the FIFO are reported sequentially. Setting maxReportLatencyUs to a positive value allows to reduce the number of interrupts the AP (Application Processor) receives, hence reducing power consumption, as the AP can switch to a lower power state while the sensor is capturing the data.
11 December 2020
Olivier Le Goaer
android
java
kotlin
Job Coalesce
The Android 5.0 Lollipop (API 21) release introduces a job scheduler API via the JobScheduler class. Compared to a custom Sync Adapter or the alarm manager, the Job Scheduler supports batch scheduling of jobs. The Android system can combine jobs so that battery consumption is reduced. It means that it exist at least one job sheduled through a call to the method JobScheduler#shedule(JobInfo job).
11 December 2020
Olivier Le Goaer
android
java
kotlin
Disable Obfuscation
The Proguard tool secure the app for production, including shrinking, code optimization and obfuscation. However, obfucated code will have a sligthly negative impact on power consumption. The good news is, Proguard has the setting -dontobfuscate that you could set in your proguard-rules.pro file. Using that you will get your code optimized but not obfuscated. Then, it could be set in your debug buildTypes > release section of your build.gradle.
01 December 2020
Olivier Le Goaër
android
java
Fused Location
The fused location provider is one of the location APIs in Google Play services which combines signals from GPS, Wi-Fi, and cell networks, as well as accelerometer, gyroscope, magnetometer and other sensors. It is officially recommended to maximize battery life. Thus, developer has to set up Google Play Service in her gradle file with a dependency to com.google.android.gms:play-services-location:x.y.z, and then to import from com.google.android.gms.location instead of the android.location package of the SDK