移动到下一个轨道的问题

The problem with moving to the next track

我正在制作音乐播放器,切换到下一首歌曲时出现问题。 phone在工作状态下(屏幕亮着)曲目切换流畅,熄屏时有很长的停顿,很长一段时间(很长!!!)或者当屏幕打开。此外,耳机(蓝牙)一切正常,即使屏幕关闭,歌曲也能流畅切换。我使用 MediaPlayer.prepare 来准备曲目(音乐文件是从 SD 卡中取出的,所以我认为使用 MediaPlayer.prepareAsync() 没有任何意义)。使用服务播放歌曲。由于播放器在屏幕打开时工作正常,而在屏幕关闭时播放器工作不佳,因此这就是问题所在。我尝试了一切,搜索了所有关于俄语和英语媒体播放器的文章,评论了 YouTube。 Kotlin 也接受帮助。 (这里是同样的问题。但是没有答案。How to use wake lock for android mediaplayer?) 下面是代码:

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();
}
}

方法代码:

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 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>

我发现了一个问题。有必要打电话给 MediaPlayer.setwakemode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);