移动到下一个轨道的问题
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);
我正在制作音乐播放器,切换到下一首歌曲时出现问题。 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);