![github-actions[bot]](/assets/img/avatar_default.png)
Co-authored-by: Irina Batinic <irina.batinic@sonarsource.com> Co-authored-by: Angelo Buono <angelo.buono@sonarsource.com>
130 lines
4.7 KiB
Plaintext
130 lines
4.7 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Optimizing resource usage and preventing unnecessary battery drain are critical considerations in Android development.
|
|
Failing to release sensor resources when they are no longer needed can lead to prolonged device activity, negatively impacting battery life.
|
|
Common Android sensors, such as cameras, GPS, and microphones, provide a method to release resources after they are not in use anymore.
|
|
|
|
This rule identifies situations where a sensor is not released after being utilized, helping developers maintain efficient and battery-friendly applications.
|
|
|
|
* Missing call to `release()` method:
|
|
- `android.os.PowerManager.WakeLock`
|
|
- `android.net.wifi.WifiManager$MulticastLock`
|
|
- `android.hardware.Camera`
|
|
- `android.media.MediaPlayer`
|
|
- `android.media.MediaRecorder`
|
|
- `android.media.SoundPool`
|
|
- `android.media.audiofx.Visualizer`
|
|
- `android.hardware.display.VirtualDisplay`
|
|
* Missing call to `close()` method
|
|
- `android.hardware.camera2.CameraDevice`
|
|
* Missing call to `removeUpdates()` method:
|
|
- `android.location.LocationManager`
|
|
* Missing call to `unregisterListener()` method:
|
|
- `android.hardware.SensorManager`
|
|
|
|
== How to fix it
|
|
|
|
Ensure that resources are released when they are no longer needed.
|
|
This can be done by calling the appropriate release method, such as `release()`, `removeUpdates()`, `unregisterListener()`, or `stop()`.
|
|
|
|
=== Code examples
|
|
|
|
* `android.os.PowerManager.WakeLock`
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,java,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
public void method() {
|
|
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
|
|
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Wake Lock");
|
|
wakeLock.acquire(); // Noncompliant
|
|
// do some work...
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,java,diff-id=1,diff-type=compliant]
|
|
----
|
|
public void method() {
|
|
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
|
|
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Wake Lock");
|
|
wakeLock.acquire(); // Compliant
|
|
// do some work...
|
|
wakeLock.release();
|
|
}
|
|
----
|
|
|
|
* `android.media.MediaPlayer`
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,java,diff-id=2,diff-type=noncompliant]
|
|
----
|
|
public void method() {
|
|
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
|
|
mediaPlayer.start(); // Noncompliant
|
|
// do some work...
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,java,diff-id=2,diff-type=compliant]
|
|
----
|
|
public void onCreate() {
|
|
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
|
|
mediaPlayer.start(); // Compliant
|
|
// do some work...
|
|
wakeLock.release();
|
|
}
|
|
----
|
|
|
|
* `android.hardware.SensorManager`
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,java,diff-id=3,diff-type=noncompliant]
|
|
----
|
|
public void method() {
|
|
SensorManager sensorManager = getSystemService(SENSOR_SERVICE);
|
|
Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
|
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL); // Noncompliant
|
|
// do some work...
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,java,diff-id=3,diff-type=compliant]
|
|
----
|
|
public void method() {
|
|
SensorManager sensorManager = getSystemService(SENSOR_SERVICE);
|
|
Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
|
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL); // Compliant
|
|
// do some work...
|
|
sensorManager.unregisterListener(this);
|
|
}
|
|
----
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* https://developer.android.com/reference/android/location/LocationManager[Android - LocationManager]
|
|
* https://developer.android.com/reference/android/os/PowerManager.WakeLock[Android - PowerManager.WakeLock]
|
|
* https://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock[Android - WifiManager.MulticastLock]
|
|
* https://developer.android.com/reference/android/media/projection/MediaProjection[Android - MediaProjection]
|
|
* https://developer.android.com/reference/android/media/MediaPlayer[Android - MediaPlayer]
|
|
* https://developer.android.com/reference/android/media/MediaRecorder[Android - MediaRecorder]
|
|
* https://developer.android.com/reference/android/media/SoundPool[Android - SoundPool]
|
|
* https://developer.android.com/reference/android/media/audiofx/Visualizer[Android - Visualizer]
|
|
* https://developer.android.com/reference/android/hardware/SensorManager[Android - SensorManager]
|
|
|
|
* https://developer.android.com/develop/background-work/background-tasks/scheduling/wakelock[Android - Keep the device awake]
|
|
* https://developer.android.com/media/platform/mediaplayer[Android - MediaPlayer Overview]
|
|
* https://developer.android.com/develop/sensors-and-location/sensors/sensors_overview[Android - Sensors Overview]
|
|
|
|
|