搜索:
几天来,我一直在研究如何控制MediaPlayer
中运行的Service
。
基本上,ForegroundService
/ NotificationCompat
我读了一个答案https://stackoverflow.com/questions/11270898/how-to-execute-a-method-by-clicking-a-notification
,说在同一个类中使用IntentService
。
我做了什么:
Service
开始时,MediaPlayer
已经在播放歌曲。因此,意味着MediaPlayer.isPlaying()
将返回true
然后我在音乐播放服务中实现了IntentService
,并在IntentService
中注册了AndroidManifest.xml
我创建了两个Action
,分别是暂停和恢复。因此,默认情况下,该通知的暂停按钮为Action
,当用户单击该通知时,它将使用Intent(MusicService.this, MusicNotificationService.class).setAction("test.pause")
PendingIntent
问题:
我可以连续播放歌曲,没有任何问题。另外,还会显示暂停按钮。
但是,每当我点击暂停按钮时,我都会收到以下错误消息。
我的代码:
public class MusicService extends Service {
private ArrayList<String> nameList, artistList, urlList;
private int position;
private MediaPlayer mediaPlayer;
private NotificationCompat.Builder builder;
private NotificationManager manager;
private PendingIntent pendingMain;
private NotificationCompat.Action actionPause, actionResume;
private static final String channelId = "Test", subtext = "Now Playing";
private static final String[] actions = {"test.pause", "test.resume"},
actionTitles = {"pause", "resume"};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
nameList = intent.getStringArrayListExtra("names");
artistList = intent.getStringArrayListExtra("artists");
urlList = intent.getStringArrayListExtra("urls");
position = intent.getIntExtra("position", 0);
builder = new NotificationCompat.Builder(this, channelId)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setSmallIcon(R.drawable.ic_music_note)
.setContentTitle(nameList.get(position))
.setContentText(artistList.get(position))
.setSubText(subtext)
.setContentIntent(pendingMain)
.addAction(actionPause)
.setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
.setShowActionsInCompactView(0)
.setShowCancelButton(true));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel();
startForeground(99, builder.build());
} else {
startForeground(99, builder.build());
}
play(urlList.get(position));
return START_NOT_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
manager = getSystemService(NotificationManager.class);
Intent mainIntent = new Intent(this, MainActivity.class);
pendingMain = PendingIntent.getActivity(this, 3, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent pause = new Intent(this, MusicNotificationService.class).setAction(actions[0]);
PendingIntent pendingPause = PendingIntent.getService(this, 4, pause, PendingIntent.FLAG_ONE_SHOT);
Intent resume = new Intent(this, MusicNotificationService.class).setAction(actions[1]);
PendingIntent pendingResume = PendingIntent.getService(this, 5, resume, PendingIntent.FLAG_ONE_SHOT);
actionPause = new NotificationCompat.Action(R.drawable.ic_pause, actionTitles[0], pendingPause);
actionResume = new NotificationCompat.Action(R.drawable.ic_play, actionTitles[1], pendingResume);
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
if (position + 1 < urlList.size()) {
position += 1;
builder.setContentTitle(nameList.get(position));
builder.setContentText(artistList.get(position));
manager.notify(99, builder.build());
play(urlList.get(position));
} else {
mp.stop();
}
}
});
}
public class MusicNotificationService extends IntentService {
public MusicNotificationService() {
super(MusicNotificationService.class.getSimpleName());
}
@SuppressLint("RestrictedApi")
@Override
protected void onHandleIntent(@Nullable Intent intent) {
String action = Objects.requireNonNull(intent).getAction();
if (action != null) {
if (mediaPlayer.isPlaying()) {
if (action.equalsIgnoreCase(actions[0])) {
mediaPlayer.pause();
builder.mActions.set(0, actionResume);
manager.notify(99, builder.build());
}
} else if (action.equalsIgnoreCase(actions[1])) {
mediaPlayer.start();
builder.mActions.set(0, actionPause);
manager.notify(99, builder.build());
}
}
}
}
}
错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: test.music, PID: 20335
java.lang.RuntimeException: Unable to instantiate service test.music.MusicService$MusicNotificationService:
java.lang.InstantiationException: java.lang.Class<test.music.MusicService$MusicNotificationService>
has no zero argument constructor
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3974)
at android.app.ActivityThread.access$1600(ActivityThread.java:220)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1899)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7520)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.lang.InstantiationException: java.lang.Class<test.music.MusicService$MusicNotificationService>
has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateService(AppComponentFactory.java:129)
at androidx.core.app.CoreComponentFactory.instantiateService(CoreComponentFactory.java:66)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3969)
at android.app.ActivityThread.access$1600(ActivityThread.java:220)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1899)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7520)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
我想要实现的目标:
目前,我希望能够暂停和恢复音乐。