Android Как реализовать MediaPlayer на экране блокировки API19 <= API28 - PullRequest
0 голосов
/ 14 ноября 2018

Я в настоящее время разрабатываю приложение, которое использует аудио. Когда устройство заблокировано, пользователь должен иметь возможность управлять звуком на экране блокировки. Это должно работать на API 19 (4.4 KitKat) до API28 (круговой, с каналом уведомлений oreo) (и выше). Приложение должно иметь возможность принимать входные данные (прослушиватели кнопок / щелчки по кнопкам), и приложение должно иметь возможность передавать нужную песню службе для воспроизведения.

Я пытаюсь сделать что-то вроде этого или экрана блокировки альбома, например Android 4.4 в качестве запасного варианта.

Мне удалось отправить уведомление в ящик уведомлений с помощью элементов управления MediaPlayer.

Сейчас я пытаюсь сделать что-то подобное, но на этот раз я хочу управлять звуком на экране блокировки.

Мне уже удалось это сделать, но работает только с API21 по API25 . Он должен работать по API 19 до 26 (и более новый / перспективный вариант). Lockscreen media control

А вот мой код: Открытый класс 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 (и новее) ?

...