Поиск:
В течение нескольких дней я смотрел, как управлять 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
в моем сервисе воспроизведения музыки musi c, также зарегистрировал, что IntentService
в AndroidManifest.xml
Я создал два Action
с, Пауза и Возобновление . Поэтому по умолчанию уведомление будет иметь Кнопка паузы как Action
, и когда пользователь щелкнет по нему, оно отправит Intent(MusicService.this, MusicNotificationService.class).setAction("test.pause")
, используя PendingIntent
Проблема:
Я могу непрерывно воспроизводить песни без каких-либо проблем. Кроме того, отображается кнопка Пауза .
Но я получаю следующую ошибку всякий раз, когда я нажимаю кнопку паузы .
My Код:
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)
Чего я хочу достичь:
Для Теперь я хочу иметь возможность приостановить и возобновить музыку c.