Android如何在锁屏API19 <= API28上实现MediaPlayer

时间:2018-11-14 19:30:25

标签: java android android-intent android-service android-mediaplayer

我目前正在开发一个使用音频的应用程序。 锁定设备后,用户必须能够在锁定屏幕上控制音频。这必须在 API 19 (4.4 KitKat)直到API28 (具有oreo通知通道的饼)上(及更高版本)上运行。该应用程序必须能够接收输入(按钮侦听器/单击按钮),并且该应用程序必须能够将正确的歌曲移交给该服务才能播放。

我正在尝试制作诸如this之类的内容或诸如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(及更新版本)

0 个答案:

没有答案