MusicPlayingService (확장자 : MediaBrowserServiceCompat
)가있는 뮤직 플레이어 앱과 서비스를 제어하는 위젯이 있습니다. MusicPlayingService는 "MediaSessionCompat.Callback
"을 구현하고 현재 MediaSession에서 모든 콜백을 처리하는 MusicStateManager
에 대한 참조합니다 (MusicServices에서 onCreate에서 만든)가 : mSession.setCallback(MusicStateManager);
위젯의 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;
}
내 위젯은 전송 보류 텐트의 무리가 있습니다 으로 이동하여 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를 복사/붙여 넣으 려 할 때 applicationContext를 컨텍스트로 사용하고있는 것으로 나타났습니다. 이것은 문제로 밝혀졌습니다! 내가 디버깅하기가 어려웠던 이유는 응용 프로그램이 시작될 때 MusicService도 시작했기 때문이며 LogCat에서 MusicService가 올바르게 시작된 것처럼 보였기 때문입니다. –
좋아요, 당신의 위젯의'RemoteViews'에서'PendingIntent'가 무엇인지 잘 모르겠습니다 - [setOnClickPendingIntent] (https://developer.android.com/reference/android/widget/RemoteViews .html # setOnClickPendingIntent (int, % 20android.app.PendingIntent)). – ianhanniballake