1

The documentation explains

Using wake locks

When designing applications that play media in the background, the device may go to sleep while your service is running. Because the Android system tries to conserve battery while the device is sleeping, the system tries to shut off any of the phone's features that are not necessary, including the CPU and the WiFi hardware. However, if your service is playing or streaming music, you want to prevent the system from interfering with your playback.

Why, then, does my audio continue playing when I turn the screen off?

Other answers reinforce my belief that

If you wish to continue the music whilst the activity is not in the foreground, you need to use a Service.

but my phone does not stop playing the audio.
Note that I ask this question in order to understand what is going on, not because I would like to know how I could pause the music when the screen goes dark.

I am not using a Service, have not added the "android.permission.WAKE_LOCK" permission to my Manifest and am working in the UI thread. (Whyever this does not cause an ANR in the first place, but the UI seems to stay responsive.)

Uri songUri = Uri.fromFile(new File(firstSong.getPath())); 
try {
    Timber.d("The following error messages regarding QCMediaPlayer can hopefully be safely ignored. See https://stackoverflow.com/questions/24501086/why-mediaplayer-throws-not-present-error-when-creating-instance-of-it");
    MediaPlayer mediaPlayer = new MediaPlayer();
    mediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .setLegacyStreamType(STREAM_MUSIC).build());
    mediaPlayer.setDataSource(getApplicationContext(), songUri);
    mediaPlayer.prepare(); // TODO: use prepareAsync instead
    mediaPlayer.start();
} catch (IllegalArgumentException | IOException e){
    Timber.w("File %s does not exist.", songUri);
}

The instanciation of the mediaPlayer actually causes an Error in the LogCat, but I doubt it is relevant. Here it is anyway:

E/ExtMediaPlayer-JNI: QCMediaPlayer could not be located....
E/MediaPlayer-JNI: JNIMediaPlayerFactory: bIsQCMediaPlayerPresent 0
E/ExtMediaPlayer-JNI: QCMediaPlayer could not be located....
E/MediaPlayer-JNI: JNIMediaPlayerFactory: bIsQCMediaPlayerPresent 0
lucidbrot
  • 5,378
  • 3
  • 39
  • 68

1 Answers1

2

Your app exists at the discretion of the OS. Just because it can shut down the app doesn't mean it will. Or it may choose to delay, waiting for resources to become more limited, before terminating your app. Different devices and OEM implementations will make these decisions at different times, and it depends on the dynamic state of the device.

Moreover, just because your last Activity has been destroyed doesn't mean your app will be terminated. The main thread is still there. It could be running a CountDownTimer, or waiting for an broadcast intent, etc. After all, if your app has something to do, why should the OS interfere (if it doesn't have to)?

Turning the screen off doesn't force the device to sleep (although turning the screen on prevents it from sleeping). With the screen off, the device will continue to stay awake for apps that have a valid WakeLock open, device maintenance periods, broadcasts, received packets, etc. And if the device isn't sleeping, your app will continue to execute (even if it's not your app that's keeping it awake).

Furthermore, Android can generally terminate any app, any time it wants. It can terminate Foreground services, even if they hold a WakeLock. Naturally you'd expect less important apps to be terminated first, but as resources become more and more limited, the OS has to become increasingly aggressive.

That is why you should describe your app's relative importance to the OS (using Services, Foreground services, Wakelocks, etc.).

greeble31
  • 4,894
  • 2
  • 16
  • 30