Home > Software engineering >  The problem with moving to the next track
The problem with moving to the next track

Time:11-05

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>

CodePudding user response:

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

  • Related