У меня есть приложение для музыкального плеера с MusicPlayingService (расширение MediaBrowserServiceCompat
) и виджет для управления сервисом. MusicPlayingService также ссылка на MusicStateManager
(создать в MusicServices OnCreate), который реализует «MediaSessionCompat.Callback
» и обрабатывает все обратные вызовы из текущего MediaSession: mSession.setCallback(MusicStateManager);
PendingIntent от Widget потерян, когда служба остановлена
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;
}
My Widget тогда имеет кучу Pending намерений, которые посылаются к 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();
}
}
Дело есть. Если я заблокирую приложение, музыкальный сервис отключится (очевидно). Если я затем нажму кнопку на моем виджете, он снова запустит мой сервис (я вижу это из различных Log.d (...) в LogCat. Однако 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, я заметил, что я использовал applicationContext в качестве контекста. Это оказалось проблемой! Причина, по которой мне было сложно отлаживать, было то, что когда приложение было запущено, оно также запустило MusicService, и из LogCat было похоже, что MusicService запускался правильно. –
Хорошо, я до сих пор не уверен, что «PendingIntent» вы используете с помощью «RemoteViews» вашего виджета. Я ожидал, что код, который включает [setOnClickPendingIntent] (https://developer.android.com/reference/android/widget/RemoteViews .html # setOnClickPendingIntent (интермедиат,% 20android.app.PendingIntent)). – ianhanniballake