/** Handle a request to pause music */ private void handlePauseRequest() { LogHelper.d(TAG, "handlePauseRequest: mState=" + mPlayback.getState()); mPlayback.pause(); // reset the delayed stop handler. mDelayedStopHandler.removeCallbacksAndMessages(null); mDelayedStopHandler.sendEmptyMessageDelayed(0, STOP_DELAY); }
/** * Update the current media player state, optionally showing an error message. * * @param error if not null, error message to present to the user. */ private void updatePlaybackState(String error) { LogHelper.d(TAG, "updatePlaybackState, playback state=" + mPlayback.getState()); long position = PlaybackState.PLAYBACK_POSITION_UNKNOWN; if (mPlayback != null && mPlayback.isConnected()) { position = mPlayback.getCurrentStreamPosition(); } PlaybackState.Builder stateBuilder = new PlaybackState.Builder().setActions(getAvailableActions()); setCustomAction(stateBuilder); int state = mPlayback.getState(); // If there is an error message, send it to the playback state: if (error != null) { // Error states are really only supposed to be used for errors that cause playback to // stop unexpectedly and persist until the user takes action to fix it. stateBuilder.setErrorMessage(error); state = PlaybackState.STATE_ERROR; } stateBuilder.setState(state, position, 1.0f, SystemClock.elapsedRealtime()); // Set the activeQueueItemId if the current index is valid. if (QueueHelper.isIndexPlayable(mCurrentIndexOnQueue, mPlayingQueue)) { MediaSession.QueueItem item = mPlayingQueue.get(mCurrentIndexOnQueue); stateBuilder.setActiveQueueItemId(item.getQueueId()); } mSession.setPlaybackState(stateBuilder.build()); if (state == PlaybackState.STATE_PLAYING || state == PlaybackState.STATE_PAUSED) { mMediaNotificationManager.startNotification(); } }
/** Handle a request to stop music */ private void handleStopRequest(String withError) { LogHelper.d(TAG, "handleStopRequest: mState=" + mPlayback.getState() + " error=", withError); mPlayback.stop(true); // reset the delayed stop handler. mDelayedStopHandler.removeCallbacksAndMessages(null); mDelayedStopHandler.sendEmptyMessageDelayed(0, STOP_DELAY); updatePlaybackState(withError); // service is no longer necessary. Will be started again if needed. stopSelf(); mServiceStarted = false; }
/** * Play the sound file currently selected in the file list. If there is no selection in the list, * or if the selected file is not a sound file, do nothing. */ private void play() { String filename = (String) fileList.getSelectedValue(); if (filename == null) { // nothing selected return; } // slider.setValue(0); boolean successful = player.play(new File(AUDIO_DIR, filename)); if (successful) { showInfo(filename + " (" + player.getDuration() + " seconds)"); } else { showInfo("Could not play file - unknown format"); } }
void action() { if (playback.paused()) { System.out.println("\"page action paused..."); StackTraceElement[] stes = Thread.currentThread().getStackTrace(); for (int i = 1; i < stes.length; i++) { StackTraceElement ste = stes[i]; if (!ste.getClassName().startsWith(getClass().getPackage().getName())) { System.out.println(ste); break; } } playback.proceed(); System.out.println("\"page action continue"); } else playback.proceed(); }
/* * (non-Javadoc) * @see android.app.Service#onCreate() */ @Override public void onCreate() { super.onCreate(); LogHelper.d(TAG, "onCreate"); mPlayingQueue = new ArrayList<>(); mMusicProvider = new MusicProvider(); mPackageValidator = new PackageValidator(this); // Start a new MediaSession mSession = new MediaSession(this, "MusicService"); setSessionToken(mSession.getSessionToken()); mSession.setCallback(new MediaSessionCallback()); mSession.setFlags( MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); mPlayback = new LocalPlayback(this, mMusicProvider); mPlayback.setState(PlaybackState.STATE_NONE); mPlayback.setCallback(this); mPlayback.start(); Context context = getApplicationContext(); Intent intent = new Intent(context, NowPlayingActivity.class); PendingIntent pi = PendingIntent.getActivity( context, 99 /*request code*/, intent, PendingIntent.FLAG_UPDATE_CURRENT); mSession.setSessionActivity(pi); mSessionExtras = new Bundle(); CarHelper.setSlotReservationFlags(mSessionExtras, true, true, true); mSession.setExtras(mSessionExtras); updatePlaybackState(null); mMediaNotificationManager = new MediaNotificationManager(this); mCastManager = ((UAMPApplication) getApplication()).getCastManager(getApplicationContext()); mCastManager.addVideoCastConsumer(mCastConsumer); mMediaRouter = MediaRouter.getInstance(getApplicationContext()); }
/** Handle a request to play music */ private void handlePlayRequest() { LogHelper.d(TAG, "handlePlayRequest: mState=" + mPlayback.getState()); mDelayedStopHandler.removeCallbacksAndMessages(null); if (!mServiceStarted) { LogHelper.v(TAG, "Starting service"); // The MusicService needs to keep running even after the calling MediaBrowser // is disconnected. Call startService(Intent) and then stopSelf(..) when we no longer // need to play media. startService(new Intent(getApplicationContext(), MusicService.class)); mServiceStarted = true; } if (!mSession.isActive()) { mSession.setActive(true); } if (QueueHelper.isIndexPlayable(mCurrentIndexOnQueue, mPlayingQueue)) { updateMetadata(); mPlayback.play(mPlayingQueue.get(mCurrentIndexOnQueue)); } }
/** * (non-Javadoc) * * @see android.app.Service#onStartCommand(android.content.Intent, int, int) */ @Override public int onStartCommand(Intent startIntent, int flags, int startId) { if (startIntent != null) { String action = startIntent.getAction(); String command = startIntent.getStringExtra(CMD_NAME); if (ACTION_CMD.equals(action)) { if (CMD_PAUSE.equals(command)) { if (mPlayback != null && mPlayback.isPlaying()) { handlePauseRequest(); } } else if (CMD_STOP_CASTING.equals(command)) { mCastManager.disconnect(); } } } return START_STICKY; }
private long getAvailableActions() { long actions = PlaybackState.ACTION_PLAY | PlaybackState.ACTION_PLAY_FROM_MEDIA_ID | PlaybackState.ACTION_PLAY_FROM_SEARCH; if (mPlayingQueue == null || mPlayingQueue.isEmpty()) { return actions; } if (mPlayback.isPlaying()) { actions |= PlaybackState.ACTION_PAUSE; } if (mCurrentIndexOnQueue > 0) { actions |= PlaybackState.ACTION_SKIP_TO_PREVIOUS; } if (mCurrentIndexOnQueue < mPlayingQueue.size() - 1) { actions |= PlaybackState.ACTION_SKIP_TO_NEXT; } return actions; }
/** * (non-Javadoc) * * @see android.app.Service#onStartCommand(android.content.Intent, int, int) */ @Override public int onStartCommand(Intent startIntent, int flags, int startId) { if (startIntent != null) { String action = startIntent.getAction(); String command = startIntent.getStringExtra(CMD_NAME); if (ACTION_CMD.equals(action)) { if (CMD_PAUSE.equals(command)) { if (mPlayback != null && mPlayback.isPlaying()) { handlePauseRequest(); } } else if (CMD_STOP_CASTING.equals(command)) { mCastManager.disconnect(); } } } // Reset the delay handler to enqueue a message to stop the service if // nothing is playing. mDelayedStopHandler.removeCallbacksAndMessages(null); mDelayedStopHandler.sendEmptyMessageDelayed(0, STOP_DELAY); return START_STICKY; }
/** * Helper to switch to a different Playback instance * * @param playback switch to this playback */ private void switchToPlayer(Playback playback, boolean resumePlaying) { if (playback == null) { throw new IllegalArgumentException("Playback cannot be null"); } // suspend the current one. int oldState = mPlayback.getState(); int pos = mPlayback.getCurrentStreamPosition(); String currentMediaId = mPlayback.getCurrentMediaId(); LogHelper.d(TAG, "Current position from " + playback + " is ", pos); mPlayback.stop(false); playback.setCallback(this); playback.setCurrentStreamPosition(pos < 0 ? 0 : pos); playback.setCurrentMediaId(currentMediaId); playback.start(); // finally swap the instance mPlayback = playback; switch (oldState) { case PlaybackState.STATE_BUFFERING: case PlaybackState.STATE_CONNECTING: case PlaybackState.STATE_PAUSED: mPlayback.pause(); break; case PlaybackState.STATE_PLAYING: if (resumePlaying && QueueHelper.isIndexPlayable(mCurrentIndexOnQueue, mPlayingQueue)) { mPlayback.play(mPlayingQueue.get(mCurrentIndexOnQueue)); } else if (!resumePlaying) { mPlayback.pause(); } else { mPlayback.stop(true); } break; case PlaybackState.STATE_NONE: break; default: LogHelper.d(TAG, "Default called. Old state is ", oldState); } }
/** Resume a previously suspended sound file. */ private void resume() { player.resume(); }
/** Stop the currently playing sound file (if there is one playing). */ private void pause() { player.pause(); }
/** Stop the currently playing sound file (if there is one playing). */ private void stop() { player.stop(); }
/* * (non-Javadoc) * @see android.app.Service#onCreate() */ @Override public void onCreate() { super.onCreate(); LogHelper.d(TAG, "onCreate"); mPlayingQueue = new ArrayList<>(); mMusicProvider = new MusicProvider(); mPackageValidator = new PackageValidator(this); ComponentName mediaButtonReceiver = new ComponentName(this, RemoteControlReceiver.class); Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); mediaButtonIntent.setComponent(mediaButtonReceiver); PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0); // Start a new MediaSessionCompat mSession = new MediaSessionCompat(this, "MusicService", mediaButtonReceiver, mediaPendingIntent); /* final MediaSessionCallback cb = new MediaSessionCallback(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Shouldn't really have to do this but the MediaSessionCompat method uses // an internal proxy class, which doesn't forward events such as // onPlayFromMediaId when running on Lollipop. final MediaSession session = (MediaSession) mSession.getMediaSession(); session.setCallback(new MediaSessionCallbackProxy(cb)); } else { mSession.setCallback(cb); } */ setSessionToken(mSession.getSessionToken()); mSession.setCallback(new MediaSessionCallback()); mSession.setFlags( MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); mPlayback = new LocalPlayback(this, mMusicProvider); mPlayback.setState(PlaybackStateCompat.STATE_NONE); mPlayback.setCallback(this); mPlayback.start(); Context context = getApplicationContext(); Intent intent = new Intent(context, NowPlayingActivity.class); PendingIntent pi = PendingIntent.getActivity( context, 99 /*request code*/, intent, PendingIntent.FLAG_UPDATE_CURRENT); mSession.setSessionActivity(pi); mSessionExtras = new Bundle(); CarHelper.setSlotReservationFlags(mSessionExtras, true, true, true); WearHelper.setSlotReservationFlags(mSessionExtras, true, true); WearHelper.setUseBackgroundFromTheme(mSessionExtras, true); mSession.setExtras(mSessionExtras); updatePlaybackState(null); mMediaNotificationManager = new MediaNotificationManager(this); mCastManager = VideoCastManager.getInstance(); mCastManager.addVideoCastConsumer(mCastConsumer); mMediaRouter = MediaRouter.getInstance(getApplicationContext()); IntentFilter filter = new IntentFilter(CarHelper.ACTION_MEDIA_STATUS); mCarConnectionReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String connectionEvent = intent.getStringExtra(CarHelper.MEDIA_CONNECTION_STATUS); mIsConnectedToCar = CarHelper.MEDIA_CONNECTED.equals(connectionEvent); LogHelper.i( TAG, "Connection event to Android Auto: ", connectionEvent, " isConnectedToCar=", mIsConnectedToCar); } }; registerReceiver(mCarConnectionReceiver, filter); }