MusicPlayingService(拡張MediaBrowserServiceCompat
)とサービスを制御するウィジェットを持つ音楽プレーヤーアプリがあります。 MusicPlayingServiceも「MediaSessionCompat.Callback
」を実装し、現在のMediaSessionからのすべてのコールバックを処理MusicStateManager
への参照(MusicServicesのonCreateに作成)している:私のウィジェットは、送信された保留中のインテントの束をmSession.setCallback(MusicStateManager);
サービスが停止するとWidgetのPendingIntentが失われる
public class MusicPlayingService extends MediaBrowserServiceCompat implements
AudioManager.OnAudioFocusChangeListener {
@RequiresPermission(Manifest.permission.READ_PHONE_STATE)
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "MusicPlayingService started");
.....
mPlayerStateManager = new MusicStateManager(this);
.....
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
MediaButtonReceiver.handleIntent(mPlayerStateManager.getSession(), intent);
return START_STICKY;
}
を持っていますMusicPlayingService
に送信し、MusicStateManager
で処理します。すべて素晴らしいです。
public class MusicStateManager extends MediaSessionCompat.Callback {
....
public MusicStateManager(@NonNull MusicStateManager argService) {
Log.d(TAG, "setting service");
mPlayerService = argService;
ComponentName mediaButtonReceiver = new ComponentName(mPlayerService, HeadsetReceiver.class);
mSession = new MediaSessionCompat(mPlayerService, SESSION_TAG, mediaButtonReceiver, null);
mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
PendingIntent pendingMediaButtonIntent = PendingIntent.getBroadcast(mPlayerService, 0, mediaButtonIntent, 0);
mSession.setMediaButtonReceiver(pendingMediaButtonIntent);
Intent toggleIntent = new Intent(NotificationPlayer.toggleAction);
PendingIntent pendingToggleIntent = PendingIntent.getBroadcast(mPlayerService, 0, toggleIntent, 0);
mSession.setMediaButtonReceiver(pendingToggleIntent);
mSession.setCallback(this);
mSession.setActive(true);
}
/**
* Callback method called from MusicStateManager whenever the music is about to play.
*/
public void onPlay() {
Log.d(TAG, "onPlay");
.......
}
@Override
public void onCustomAction(String action, Bundle extras) {
Log.d(TAG, "received action: " + action); // NoI18N
if (ACTION_TOGGLE.equals(action)) {
mPlayerService.toggle();
}
}
物がございます。私が強制的にアプリケーションを停止すると、音楽サービスがシャットダウンします(明らかに)。ウィジェットのボタンを押すとサービスが再開します(LogCatのさまざまなLog.d(...)から見ることができます)。しかし、ウィジェットのPendingIntentは失われ、決して処理されません。
これはユーザには奇妙な意味を持ちますが、ほとんどの場合、ウィジェットのボタンは機能します(サービスが実行されているとき)。しかし、私はこの問題をデバッグし、私のPendingIntentに何が起こるか見ることができますどのように任意のアイデアあなたがそれらを再度押すと、彼らが動作する場合(初回のサービスを始めたが、意図を処理するために失敗したため。
?
コードには、ウィジェットのPendingIntentsを設定する場所は含まれません。また、 'setMediaButtonReceiver'を複数回呼び出すと、以前に設定した値が上書きされ、[メディアボタンからの再生を再開]するだけです(https://developer.android.com/reference/android/support/v4/)。 media/session/MediaSessionCompat.html#setMediaButtonReceiver(android.app.PendingIntent))。これは呼び出されず、ウィジェットの動作もまったく変更されません。ウィジェットコードと、起動された 'BroadcastReceiver.onReceive()'や 'Service.onStartCommand()'を含めることができますか? – ianhanniballake
私はあなたが求めたものすべてを追加していました。しかし、私がPendingIntentsをコピー/ペーストしようとしていたとき、私はcontextとしてapplicationContextを使用していることに気付きました。これは問題であることが判明しました!私がデバッグするのが難しい理由は、アプリケーションが起動されたときにMusicServiceも起動し、LogCatからMusicServiceが正しく起動したように見えたためです。 –
さて、あなたのウィジェットの 'RemoteViews'で' PendingIntent'が何を使用しているのかまだわかりません - 私は[setOnClickPendingIntent](https://developer.android.com/reference/android/widget/RemoteViews .html#setOnClickPendingIntent(int、%20android.app.PendingIntent))。 – ianhanniballake