Я в настоящее время разрабатываю приложение, которое использует аудио.
Когда устройство заблокировано, пользователь должен иметь возможность управлять звуком на экране блокировки. Это должно работать на API 19 (4.4 KitKat) до API28 (круговой, с каналом уведомлений oreo) (и выше). Приложение должно иметь возможность принимать входные данные (прослушиватели кнопок / щелчки по кнопкам), и приложение должно иметь возможность передавать нужную песню службе для воспроизведения.
Я пытаюсь сделать что-то вроде этого или экрана блокировки альбома, например Android 4.4 в качестве запасного варианта.
Мне удалось отправить уведомление в ящик уведомлений с помощью элементов управления MediaPlayer.
Сейчас я пытаюсь сделать что-то подобное, но на этот раз я хочу управлять звуком на экране блокировки.
Мне уже удалось это сделать, но работает только с API21 по API25 .
Он должен работать по API 19 до 26 (и более новый / перспективный вариант).
![Lockscreen media control](https://i.stack.imgur.com/bfz6a.png)
А вот мой код:
Открытый класс LockscreenService расширяет Сервис {
private MediaSession mSession;
public static final String ACTION_PLAY = "ACTION_PLAY";
public static final String ACTION_PAUSE = "ACTION_PAUSE";
public static final String ACTION_REWIND = "ACTION_REWIND";
public static final String ACTION_FAST_FORWARD = "ACTION_FAST_FORWARD";
public static final String ACTION_NEXT = "ACTION_NEXT";
public static final String ACTION_PREVIOUS = "ACTION_PREVIOUS";
public static final String ACTION_STOP = "ACTION_STOP";
private MediaPlayer mMediaplayer;
private MediaSessionManager mediaSessionManager;
private MediaController mController;
//region EXTENDS
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public boolean onUnbind(Intent intent) {
// mSession.release();
return super.onUnbind(intent);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mediaSessionManager == null) {
initMediaSession();
}
handleIntent(intent);
return super.onStartCommand(intent, flags, startId);
}
//endregion
//region
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void initMediaSession() {
mSession = new MediaSession(getApplicationContext(), "example session");
mController = new MediaController(getApplicationContext(), mSession.getSessionToken());
mSession.setCallback(new MediaSession.Callback() {
@Override
public void onPlay() {
super.onPlay();
playMusic();
buildNotification(generateAction(android.R.drawable.ic_media_pause, "pause", ACTION_PAUSE));
}
@Override
public void onPause() {
super.onPause();
pauseMusic();
buildNotification(generateAction(android.R.drawable.ic_media_play, "pause", ACTION_PLAY));
}
@Override
public void onSkipToNext() {
super.onSkipToNext();
buildNotification(generateAction(android.R.drawable.ic_media_pause, "pause", ACTION_PAUSE));
}
@Override
public void onFastForward() {
pauseMusic();
super.onSkipToNext();
}
@Override
public void onRewind() {
pauseMusic();
super.onSkipToNext();
}
@Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
pauseMusic();
}
@Override
public void onStop() {
super.onStop();
NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(1);
Intent intent = new Intent(getApplicationContext(), LockscreenService.class);
stopService(intent);
}
});
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void handleIntent(Intent intent) {
if (intent == null || intent.getAction() == null) {
// STOP
}
String action = Objects.requireNonNull(intent).getAction();
assert action != null;
if (action.equalsIgnoreCase(ACTION_PLAY)) {
Toast.makeText(this, "Clicked Play", Toast.LENGTH_SHORT).show();
mController.getTransportControls().play();
} else if (action.equalsIgnoreCase(ACTION_PAUSE)) {
Toast.makeText(this, "Clicked pause", Toast.LENGTH_SHORT).show();
mController.getTransportControls().pause();
} else if (action.equalsIgnoreCase(ACTION_FAST_FORWARD)) {
Toast.makeText(this, "Clicked fast forward", Toast.LENGTH_SHORT).show();
mController.getTransportControls().fastForward();
} else if (action.equalsIgnoreCase(ACTION_REWIND)) {
Toast.makeText(this, "Clicked rewind", Toast.LENGTH_SHORT).show();
mController.getTransportControls().rewind();
} else if (action.equalsIgnoreCase(ACTION_PREVIOUS)) {
Toast.makeText(this, "Clicked previous", Toast.LENGTH_SHORT).show();
pauseMusic();
mController.getTransportControls().skipToPrevious();
} else if (action.equalsIgnoreCase(ACTION_NEXT)) {
Toast.makeText(this, "Clicked next", Toast.LENGTH_SHORT).show();
mController.getTransportControls().skipToNext();
} else if (action.equalsIgnoreCase(ACTION_STOP)) {
Toast.makeText(this, "Clicked stop", Toast.LENGTH_SHORT).show();
mController.getTransportControls().stop();
}
}
@TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
private Notification.Action generateAction(int icon, String title, String intentAction) {
Intent intent = new Intent(getApplicationContext(), LockscreenService.class);
intent.setAction(intentAction);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0);
return new Notification.Action.Builder(icon, title, pendingIntent).build();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void buildNotification(Notification.Action action) {
Notification.MediaStyle style = new Notification.MediaStyle();
Intent intent = new Intent(getApplicationContext(), LockscreenService.class);
intent.setAction(ACTION_STOP);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0);
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle("Lockscreen Book Example")
.setContentText("Title of the book")
.setDeleteIntent(pendingIntent)
.setStyle(style);
builder.addAction(generateAction(android.R.drawable.ic_media_previous, "previous", ACTION_PREVIOUS));
builder.addAction(generateAction(android.R.drawable.ic_media_rew, "previous", ACTION_PREVIOUS));
builder.addAction(action);
builder.addAction(generateAction(android.R.drawable.ic_media_previous, "fast forward", ACTION_FAST_FORWARD));
builder.addAction(generateAction(android.R.drawable.ic_media_rew, "Next", ACTION_NEXT));
style.setShowActionsInCompactView(0, 1, 2, 3, 4);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, builder.build());
}
//region music controls
public void initMusic() {
//getting systems default ringtone
mMediaplayer = MediaPlayer.create(this,
Settings.System.DEFAULT_RINGTONE_URI);
}
public void playMusic() {
if (mMediaplayer != null) {
mMediaplayer.start();
} else {
initMusic();
//staring the player
mMediaplayer.start();
}
}
public void pauseMusic() {
if (mMediaplayer != null)
mMediaplayer.pause();
}
//endregion
//endregion
Когда я пытаюсь использовать NotificationCompat, я не могу позволить MediaStyle работать, поэтому я не могу сгенерировать элементы управления.
Может кто-нибудь помочь мне, как я могу настроить управление звуком на экране блокировки, который работает на KitKat до Pie (и новее) ?