Androidに通知プレーヤーを実装しようとしています。私はついていきますこの これを達成するためのガイド。ただし、私の要件として、バックグラウンド通知プレーヤーで「次へスキップ」と「前へスキップ」を実装する必要があります。
これまで、MediaSessionCompact.CallbackのonPlay()およびonPause()がトリガーされます。ただし、デバッグ中に、通知プレーヤーで次ボタンと前ボタンが押されたときにonSkipToNext()およびonSkipToPrevious()コールバックメソッドがトリガーされないことに気付きました。
入力に感謝します。以下に関連するコードを追加しました。
BackgroundAudioService
private void showPlayingNotification() {
NotificationCompat.Builder builder = MediaStyleHelper.from(BackgroundAudioService.this, mMediaSessionCompat);
if (builder == null) {
return;
}
builder.addAction(new NotificationCompat.Action(android.R.drawable.ic_media_previous, "Previous", MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS)));
builder.addAction(new NotificationCompat.Action(android.R.drawable.ic_media_pause, "Pause", MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_PLAY_PAUSE)));
builder.addAction(new NotificationCompat.Action(android.R.drawable.ic_media_next, "Next", MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_SKIP_TO_NEXT)));
builder.setStyle(new NotificationCompat.MediaStyle().setShowActionsInCompactView(0).setMediaSession(mMediaSessionCompat.getSessionToken()));
builder.setSmallIcon(R.mipmap.ic_launcher);
NotificationManagerCompat.from(BackgroundAudioService.this).notify(1, builder.build());
}
private void showPausedNotification() {
NotificationCompat.Builder builder = MediaStyleHelper.from(this, mMediaSessionCompat);
if (builder == null) {
return;
}
builder.addAction(new NotificationCompat.Action(android.R.drawable.ic_media_previous, "Previous", MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS)));
builder.addAction(new NotificationCompat.Action(android.R.drawable.ic_media_play, "Play", MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_PLAY_PAUSE)));
builder.addAction(new NotificationCompat.Action(android.R.drawable.ic_media_next, "Next", MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_SKIP_TO_NEXT)));
builder.setStyle(new NotificationCompat.MediaStyle().setShowActionsInCompactView(0).setMediaSession(mMediaSessionCompat.getSessionToken()));
builder.setSmallIcon(R.mipmap.ic_launcher);
NotificationManagerCompat.from(this).notify(1, builder.build());
}
private MediaSessionCompat.Callback mMediaSessionCallback = new MediaSessionCompat.Callback() {
@Override
public void onPlay() {
super.onPlay();
if (!successfullyRetrievedAudioFocus()) {
return;
}
mMediaSessionCompat.setActive(true);
setMediaPlaybackState(PlaybackStateCompat.STATE_PLAYING);
Log.d("MyLog", "STATE_PLAYING");
showPlayingNotification();
mMediaPlayer.start();
}
@Override
public void onPause() {
super.onPause();
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
setMediaPlaybackState(PlaybackStateCompat.STATE_PAUSED);
Log.d("MyLog", "STATE_PAUSED");
showPausedNotification();
}
}
@Override
public void onSkipToNext() {
super.onSkipToNext();
setMediaPlaybackState(PlaybackStateCompat.STATE_SKIPPING_TO_NEXT);
Log.d("MyLog", "STATE_SKIPPING_TO_NEXT");
}
@Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
setMediaPlaybackState(PlaybackStateCompat.STATE_SKIPPING_TO_PREVIOUS);
Log.d("MyLog", "STATE_SKIPPING_TO_PREVIOUS");
}
}
MediaStyleHelper
public static NotificationCompat.Builder from(
Context context, MediaSessionCompat mediaSession) {
MediaControllerCompat controller = mediaSession.getController();
MediaMetadataCompat mediaMetadata = controller.getMetadata();
MediaDescriptionCompat description = mediaMetadata.getDescription();
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder
.setContentTitle(description.getTitle())
.setContentText(description.getSubtitle())
.setSubText(description.getDescription())
.setLargeIcon(description.getIconBitmap())
.setContentIntent(controller.getSessionActivity())
.setDeleteIntent(
MediaButtonReceiver.buildMediaButtonPendingIntent(context, PlaybackStateCompat.ACTION_STOP))
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
return builder;
}
主な活動のonCreate
mMediaBrowserCompat = new MediaBrowserCompat(this, new ComponentName(this, BackgroundAudioService.class),
mMediaBrowserCompatConnectionCallback, getIntent().getExtras());
主な活動
private MediaBrowserCompat.ConnectionCallback mMediaBrowserCompatConnectionCallback = new MediaBrowserCompat.ConnectionCallback() {
@Override
public void onConnected() {
super.onConnected();
try {
mMediaControllerCompat = new MediaControllerCompat(MainActivity.this, mMediaBrowserCompat.getSessionToken());
mMediaControllerCompat.registerCallback(mMediaControllerCompatCallback);
setSupportMediaController(mMediaControllerCompat);
getSupportMediaController().getTransportControls().playFromMediaId(String.valueOf(R.raw.warner_tautz_off_broadway), null);
} catch( RemoteException e ) {
}
}
};
private MediaControllerCompat.Callback mMediaControllerCompatCallback = new MediaControllerCompat.Callback() {
@Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {
super.onPlaybackStateChanged(state);
if( state == null ) {
return;
}
switch( state.getState() ) {
case PlaybackStateCompat.STATE_PLAYING: {
mCurrentState = STATE_PLAYING;
break;
}
case PlaybackStateCompat.STATE_PAUSED: {
mCurrentState = STATE_PAUSED;
break;
}
case PlaybackStateCompat.STATE_SKIPPING_TO_NEXT: {
mCurrentState = STATE_SKIPPING_TO_NEXT;
break;
}
case PlaybackStateCompat.STATE_SKIPPING_TO_PREVIOUS: {
mCurrentState = STATE_SKIPPING_TO_PREVIOUS;
}
}
}
};
更新
onMediaButtonEvent()は、両方のボタンのアクション名「android.intent.action.MEDIA_BUTTON」を使用して、通知プレーヤーで次および前にトリガーされるようです。
@Override
public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
Log.d("MyLog", "executing onMediaButtonEvent: " + mediaButtonEvent.getAction());
return super.onMediaButtonEvent(mediaButtonEvent);
}
回答 1 件
関連した質問
- 電卓アプリでDecimalFormatのエラーを解決する方法
- GPIO制御にJavaクラスを使用して、AndroidOSで実行されるアプリケーションを作成する方法
- Android(Kotlin):オブザーバーのタイプの不一致
- Androidプロジェクトで使用されるJARからのロギング
- NordicThingy:52を使用したAndroid BluetoothGATTタイムアウト
- 応答を処理するKotlinRetrofit
- 作成中のスレッドがデーモンである場合に限り、Javaスレッドはデーモンですか?
- AlertDilogからMainActivtyにデータリターンを渡します
- RectFがCanvasの境界線から外れます
- (解決済み)デフォルトのandroid RecyclerView ViewHolder NPE shouldIgnore()
同じガイドに従った後、この問題に遭遇しました。
setMediaPlaybackState(int state)
というメソッドを探します BackgroundAudioServiceクラス内。ここで、PlaybackStateCompat.Builderを定義し、setActionsを使用してセッションで使用可能な現在の機能を定義します。OnSkipToNextおよびonSkipToPreviousは、ACTION_SKIP_TO_NEXTおよびACTION_SKIP_TO_PREVIOUSがサポートされているアクションとして渡されない限り呼び出されません。 setActionsを次のように更新した後、なんとか動作するようになりました...
これを行うための少しきれいな方法があればいいのですが、すべてのアクションを1回のヒットで設定する必要があり、複数の呼び出しに分割することはできないようです。