I am writing a music player app with Cordova and using the official Media Plugin. On the success callback, I want to fetch the next track and start playing it. However, after being a few minutes in the background, the android app hangs on fetching the next track.

After investigating, I found out that it only happens when using async code in the callback, or in other words, that any immediate code is executed normally but no macro tasks that follow. Once I open the app again, the execution continues.

I do have a running foreground service through this music-controls plugin.

I also tried wake locks, wifi locks, web workers as well as disabling battery optimizations, however, none of these did solve the problem.

I created a small example to demonstrate the problem:

document.addEventListener('deviceready', onDeviceReady, false);

function onDeviceReady() {
    // Starts the foreground service
    MusicControls.create({
        track:     'The track',
        artist:    'The artist',
        album:     'The album',
        isPlaying: true,
    });

    startNextTrack();
}

let media = null;

async function startNextTrack() {
    console.log('Starting next track');

    // simulate asynchronously fetching the next track
    await new Promise(resolve => setTimeout(resolve, 5000));
    console.log('Promise is resolved');
    
    media = new Media(
        'file:///android_asset/www/test.mp3',
        () => {
            console.log('Media: Success callback');
            if (media) {
                media.release();
            }
            startNextTrack();
        },
    );
    
    media.play();
}

At the beginning when putting the app in the backgroud, it works as expected and logs this everytime a track is played:

Starting next track
Promise is resolved
Media: success callback

However, after a few minutes in the background, when the track is finished, it only prints this and then hangs indefinitely:

Starting next track
0

There are 0 answers