The situation is that in the application only one mode works properly, in which if a call comes in, the music stops playing. At the end of the call, the music continues.

Users complain that if you put the music on pause, and then (for example) some kind of warning will come to the device, the music spontaneously starts to play further. How can this be fixed? I spread the service code below:

public class PlaybackService extends Service implements AudioManager.OnAudioFocusChangeListener { private static final String TAG = Log.buildTag(PlaybackService.class); public static final String ACTION_TOGGLE_PLAYBACK = "com.pro.actions.TOGGLE_PLAYBACK"; public static final String ACTION_STOP_PLAYBACK = "com.pro.actions.STOP_PLAYBACK"; public static final String ACTION_PAUSE_PLAYBACK = "com.pro.actions.PAUSE_PLAYBACK"; private static final int NOTIFICATION_ID = 1231231; private final IBinder binder = new LocalBinder(); private PowerManager.WakeLock wakeLock; private WifiManager.WifiLock wifiLock; private RemoteControlClient remoteControlClient; private ComponentName remoteControlReceiver; private MediaSession mediaSession; @Override public void onCreate() { super.onCreate(); EventBus.getInstance().register(this); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mediaSession = new MediaSession(this, "com.pro"); mediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); final Intent intent = new Intent(this, MainActivity.class); mediaSession.setSessionActivity(PendingIntent.getActivity(this, 0, intent, 0)); } else { remoteControlReceiver = new ComponentName(getPackageName(), PlaybackReceiver.class.getName()); final Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); mediaButtonIntent.setComponent(remoteControlReceiver); final PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0); remoteControlClient = new RemoteControlClient(mediaPendingIntent); } } @Override public void onDestroy() { super.onDestroy(); EventBus.getInstance().unregister(this); Streamer.getInstance().destroy(); ensureUnlocked(); releaseAudioFocus(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mediaSession.release(); } } @Override public int onStartCommand(final Intent intent, final int flags, final int startId) { final String action = intent != null ? intent.getAction() : null; if (ACTION_TOGGLE_PLAYBACK.equals(action)) { togglePlayback(); } else if (ACTION_STOP_PLAYBACK.equals(action)) { stopPlayback(); stopSelf(); } else if (ACTION_PAUSE_PLAYBACK.equals(action)) { setPlaying(false); } else { return super.onStartCommand(intent, flags, startId); } return START_STICKY; } @Nullable @Override public IBinder onBind(final Intent intent) { return binder; } private boolean requestAudioFocus() { final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); final int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); return result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED; } private boolean releaseAudioFocus() { final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); final int result = audioManager.abandonAudioFocus(this); return result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED; } private void ensureLocked() { if (wakeLock == null) { PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "com.pro"); wakeLock.acquire(); } if (wifiLock == null) { wifiLock = ((WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE)).createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "com.pro"); wifiLock.acquire(); } } private void ensureUnlocked() { if (wakeLock != null) { wakeLock.release(); wakeLock = null; } if (wifiLock != null) { wifiLock.release(); wifiLock = null; } } private void buildNotification(final Bitmap bitmap) { final NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); final Notification notification = PlaybackNotification.getInstance(this, bitmap, mediaSession); nm.notify(NOTIFICATION_ID, notification); startForeground(NOTIFICATION_ID, notification); } private void updateNotification() { final NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); final Streamer streamer = Streamer.getInstance(); if (streamer.isStopped()) { nm.cancel(NOTIFICATION_ID); stopForeground(true); } else { Picasso.with(this).load(streamer.getStation().getIconUrl()).into(new Target() { @Override public void onBitmapLoaded(final Bitmap bitmap, final com.squareup.picasso.Picasso.LoadedFrom from) { buildNotification(bitmap); } @Override public void onBitmapFailed(final Drawable errorDrawable) { buildNotification(null); } @Override public void onPrepareLoad(final Drawable placeHolderDrawable) { buildNotification(null); } }); } } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void startMediaSession() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; mediaSession.setActive(true); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void stopMediaSession() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; mediaSession.setActive(false); } // FIXME support new api private void registerRemote() { final AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); if (remoteControlReceiver != null) { am.registerMediaButtonEventReceiver(remoteControlReceiver); } if (remoteControlClient != null) { am.registerRemoteControlClient(remoteControlClient); } } private void unregisterRemote() { final AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); if (remoteControlReceiver != null) { am.unregisterMediaButtonEventReceiver(remoteControlReceiver); } if (remoteControlClient != null) { am.unregisterRemoteControlClient(remoteControlClient); } } private void duck() { Streamer.getInstance().setVolume(.25f); } private void unduck() { Streamer.getInstance().setVolume(1); } public void loadStation(final Station station) { Streamer.getInstance().loadStation(station); } public void togglePlayback() { final Streamer streamer = Streamer.getInstance(); setPlaying(!streamer.isPlaying()); } public void setPlaying(final boolean state) { final Streamer streamer = Streamer.getInstance(); if (!state) { streamer.pause(); } else { if (streamer.isStopped()) streamer.loadStation(streamer.getStation()); streamer.start(); } } public void stopPlayback() { final Streamer streamer = Streamer.getInstance(); streamer.stop(); releaseAudioFocus(); try { stopService(playIntent); int pid = android.os.Process.myPid(); android.os.Process.killProcess(pid); System.exit(0); } catch (Exception e) { e.printStackTrace(); } } @Override public void onAudioFocusChange(final int focusChange) { switch (focusChange) { case AudioManager.AUDIOFOCUS_GAIN: case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK: setPlaying(true); unduck(); break; case AudioManager.AUDIOFOCUS_LOSS: //stopPlayback(); setPlaying(false); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: setPlaying(false); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: duck(); break; default: break; } } @Subscribe public void onMetadataUpdated(final StreamMetaDataUpdate update) { updateNotification(); } @Subscribe public void onPlayerStateChanged(final PlayerStateChange update) { updateNotification(); if (!Streamer.getInstance().isStopped()) { ensureLocked(); requestAudioFocus(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { startMediaSession(); } else { registerRemote(); } } else { ensureUnlocked(); releaseAudioFocus(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { stopMediaSession(); } else { unregisterRemote(); } } } @Subscribe public void onError(final PlayerError error) { updateNotification(); } @Subscribe public void onStationUpdate(final StationUpdate update) { updateNotification(); } public class LocalBinder extends Binder { public PlaybackService getService() { return PlaybackService.this; } } } 
  • Add a checkbox that if the reproduction is programmatically quenched, then programmatically and start, if you manually pause, then only manually start. - Yura Ivanov
  • What is the box? @YuraIvanov - Anton
  • well, just boolean userPaused = true if the user paused from the notification or in the application. if paused by userPaused = false. And in setPlaying or in front of him to check (sorry, not starting at home, it’s not quite clear what events lead to the effect you described) ... - Yura Ivanov

0