The problem with moving to the next track

Issue

I’m making a music player, and there was a problem when switching to the next song. When the phone is in working condition (the screen is on) the tracks switch smoothly, when the screen is off there is a long pause, the song starts only after a long time (very long!!!) or when the screen is turned on. Also, everything works well with a headset (Bluetooth), songs switch smoothly even when the screen is turned off. I use MediaPlayer.prepare to prepare the track (music files are taken from the SD card, so I don’t see any point in using MediaPlayer.prepareAsync()). Songs are played using Service. Since the player works fine when the screen is turned on and poorly when it is turned off, then this is the problem. I tried everything, searched all the articles about media player in Russian and English, reviewed YouTube. Help is also accepted on Kotlin. (here is the same question. but there is no answer. How to use wake lock for android mediaplayer?) Below is the code:

public class MusicService extends Service implements MediaPlayer.OnCompletionListener,
        MediaPlayer.OnPreparedListener {

    IBinder mBinder  new MyBinder();
    private MediaPlayer mediaPlayer  null;
    private Uri uri;
    private int position  POSITION_PLAY;
    public static AudioManager audioManager;
    int result;
    private NotificationReceiver notificationReceiver;

    @Override
    public void onCreate() {
        super.onCreate();

        notificationReceiver  new NotificationReceiver();
        audioManager  (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        result  audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
                AudioManager.AUDIOFOCUS_GAIN);
        if (result ! AudioManager.AUDIOFOCUS_REQUEST_GRANTED)
            return;

        IntentFilter intentFilter  new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
        registerReceiver(notificationReceiver, intentFilter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        releaseMP();
        unregisterReceiver(notificationReceiver);
        audioManager.abandonAudioFocus(this);
        Log.e(TAG, "onDestroy()");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    public class MyBinder extends Binder {
        MusicService getService() {
            return MusicService.this;
        }

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(myPosition ! -1){
            playMedia(myPosition);
        }
        return START_STICKY;
    }

    public void createMediaPlayer(int positionInner) {
        position  positionInner;
        uri  Uri.parse(musicFiles.get(position).getPath());
        mediaPlayer  null;
        mediaPlayer  new MediaPlayer();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        try {
            mediaPlayer.setDataSource(getApplicationContext(), uri);
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
        prepare();
    }

    private void playMedia(int position) {
        if(mediaPlayer ! null) {
            mediaPlayer.stop();
            releaseMP();
        }
        createMediaPlayer(position);
        mediaPlayer.start();
    }

    public void prepare() {
        try {
            mediaPlayer.prepare();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }

    void showNotification(int playPauseBtn){
        ...
        startForeground(2, notification);
        if(!isGoing && IS_LIVE) {
            stopForeground(false);
        }
    }


    void OnCompleted(){
        mediaPlayer.setOnCompletionListener(this);
    }

    void OnPrepared() { mediaPlayer.setOnPreparedListener(this);}

    @Override
    public void onCompletion(MediaPlayer mp) {
        if(actionPlaying ! null){
            actionPlaying.nextBtnClicked();
            if(mediaPlayer ! null){
                mediaPlayer.start();
                OnCompleted();
            }
        }
    }

    private void releaseMP() {
        if (mediaPlayer ! null) {
            try {
                mediaPlayer.release();
                mediaPlayer  null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.start();
    }



public void start() {
    mediaPlayer.start();
}
public boolean isPlaying() {
    return mediaPlayer.isPlaying();
}
public void stop() {
    mediaPlayer.stop();
}
public void pause() {
    mediaPlayer.pause();
}
public void release() {
    releaseMP();
}
public int getDuration() {
    return mediaPlayer.getDuration();
}
public void seekTo(int position) {
    mediaPlayer.seekTo(position);
}
public int getCurrentPosition() {
    return mediaPlayer.getCurrentPosition();
}
}

Code for the method:

public void nextBtnClicked() {
        if(musicService.isPlaying()) {
            musicService.stop();
            musicService.release();
            if(SHUFFLE && !REPEAT){
                POSITION_PLAY  getRandom(ListSongs.size() - 1);
            }
            else if(!SHUFFLE && !REPEAT){
                POSITION_PLAY  ((POSITION_PLAY + 1) % ListSongs.size());
            }
            uri  Uri.parse(ListSongs.get(POSITION_PLAY).getPath());
            musicService.createMediaPlayer(POSITION_PLAY);
            if(is_live_player_activity) {
                metaData(uri);
            }
            musicService.OnCompleted();
            musicService.showNotification(R.drawable.ic_pause);
            playPauseBtn.setBackgroundResource(R.drawable.ic_pause);
            musicService.start();
        }
        else {
            musicService.stop();
            musicService.release();
            if(SHUFFLE && !REPEAT){
                POSITION_PLAY  getRandom(ListSongs.size() - 1);
            }
            else if(!SHUFFLE && !REPEAT){
                POSITION_PLAY  ((POSITION_PLAY + 1) % ListSongs.size());
            }
            uri  Uri.parse(ListSongs.get(POSITION_PLAY).getPath());
            musicService.createMediaPlayer(POSITION_PLAY);
            if(is_live_player_activity) {
                metaData(uri);
            }
            musicService.OnCompleted();
            if(FLAG){
                musicService.showNotification(R.drawable.ic_pause);
                playPauseBtn.setBackgroundResource(R.drawable.ic_pause);
            } else {
                musicService.showNotification(R.drawable.ic_play);
                playPauseBtn.setBackgroundResource(R.drawable.ic_play);
            }
        }
    }

Manifest:

<manifest xmlns:android"http://schemas.android.com/apk/res/android"
    xmlns:tools"http://schemas.android.com/tools"
    package"com.example.music">

    <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name"android.permission.RECORD_AUDIO" />
    <uses-permission android:name"android.permission.FOREGROUND_SERVICE" />

    <application
        android:allowBackup"true"
        android:icon"@mipmap/ic_launcher"
        android:label"@string/app_name"
        android:roundIcon"@mipmap/ic_launcher_round"
        android:supportsRtl"true"
        android:name".ApplicationClass"
        android:screenOrientation"portrait"
        android:theme"@style/Theme.Music">

        <activity android:name".MusicActivity"
            android:screenOrientation"portrait"
            android:launchMode"singleTask">
            <intent-filter>
                <action android:name"android.intent.action.MAIN" />

                <category android:name"android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        ...
        <service android:name".MusicService" android:enabled"true"/>
        <receiver android:name".NotificationReceiver" android:enabled"true">
            <intent-filter>
                <action android:name"android.intent.action.MEDIA_BUTTON" />
                <action android:name"android.media.AUDIO_BECOMING_NOISY" />
                <action android:name"actionprevious" />
                <action android:name"actionnext" />
                <action android:name"actionplay" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

Solution

I found a problem. It was necessary to call MediaPlayer.setwakemode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);

Answered By – Alex Goodman

Leave a Comment