Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class MusicPlaybackService extends Service {
- /**
- * DEBUG
- */
- private static final String LOG_TAG = "MusicPlaybackService";
- /**
- * Notification ID
- */
- private static final int NOTIFICATION_ID = 12427;
- /**
- * {@link android.media.MediaPlayer} instance
- */
- private MusicPlayer mMediaPlayer;
- /**
- * {@link aj.jair.music.MusicPlaybackService.ServiceBinder}
- * for binding {@link android.app.Activity} or {@link android.support.v4.app.FragmentActivity}
- * with {@link aj.jair.music.MusicPlaybackService}
- */
- private final IBinder mBinder = new ServiceBinder();
- /**
- * Song Data
- */
- public static int mSongNumber = -1;
- public int mPreviousSongNumber = -1;
- private Song mSong;
- /**
- * List containing all the songs or Queue
- */
- private ArrayList<Song> mSongs;
- private AudioManager mAudioManager;
- /**
- * Called to go toggle between pausing and playing the music
- */
- public static final String PLAY_PAUSE_ACTION = "aj.jair.music.toggle.playback";
- /**
- * Called to pause the playback
- */
- public static final String PAUSE_ACTION = "aj.jair.music.pause";
- /**
- * Called to go to pause the playback
- */
- public static final String PLAY_ACTION = "aj.jair.music.play";
- /**
- * Called to go to reset the playback
- */
- public static final String STOP_ACTION = "aj.jair.music.stop";
- /**
- * Called to go to the previous track
- */
- public static final String PREVIOUS_ACTION = "aj.jair.music.previous";
- /**
- * Called to go to the next track
- */
- public static final String NEXT_ACTION = "aj.jair.music.next";
- /**
- * Called to start/reset shuffle
- */
- public static final String SHUFFLE_ACTION = "aj.jair.music.shuffle";
- /**
- * Called to start/reset shuffle
- */
- public static final String REPEAT_ACTION = "aj.jair.music.repeat";
- /**
- * Indicates the meta data has changed in some way, like a track change
- */
- public static final String META_CHANGED = "aj.jair.music.metachanged";
- /**
- * Indicates that the music has paused or resumed
- */
- public static final String PLAY_STATE_CHANGED = "aj.jair.music.playstatechanged";
- private MediaSessionCompat mMediaSessionCompat;
- /**
- * For headset keystrokes
- */
- // For double press recognition
- private static final int DOUBLE_CLICK = 400;
- private long mLastClickTime = 0;
- public class ServiceBinder extends Binder {
- public MusicPlaybackService getService() {
- return MusicPlaybackService.this;
- }
- }
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- //setupMediaSession();
- // Initialize the wake lock
- if (intent != null) {
- final String action = intent.getAction();
- /**
- * Handles calls from Notification, Widget & UI
- */
- if (PLAY_PAUSE_ACTION.equals(action)) {
- /*if (isMediaPlayerActive()) {
- if (!isNotification()) startNotification();
- if (isPlaying()) pause();
- else resume();
- } else setupFromWidget(action);*/
- if (isMediaPlayerActive()) {
- if (isPlaying()) mTransportController.pause();
- else mTransportController.play();
- }
- else setupFromWidget(action);
- } else if (NEXT_ACTION.equals(action)) {
- /*if (isMediaPlayerActive()) {
- if (!isNotification()) startNotification();
- playNext(mSongNumber);
- }
- else setupFromWidget(action);*/
- if (isMediaPlayerActive()) mTransportController.skipToNext();
- else setupFromWidget(action);
- } else if (PREVIOUS_ACTION.equals(action)) {
- /*if (isMediaPlayerActive()) {
- if (!isNotification()) startNotification();
- playPrevious(mSongNumber);
- }
- else setupFromWidget(action);*/
- if (isMediaPlayerActive()) mTransportController.skipToPrevious();
- else setupFromWidget(action);
- } else if (STOP_ACTION.equals(action)) {
- /*if (isMediaPlayerActive()) {
- Log.d(LOG_TAG, "Stopping Self");
- pause();
- commitMusicData();
- stopSelf();
- //releaseAudioManager();
- }
- stopNotification();*/
- //stopSelf();
- if (isMediaPlayerActive()) mTransportController.stop();
- }
- }
- return START_STICKY;
- }
- /**
- * Initializes the remote control client
- */
- private void setupMediaSession() {
- /* Activate Audio Manager */
- mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC,
- AudioManager.AUDIOFOCUS_GAIN);
- ComponentName mRemoteControlResponder = new ComponentName(getPackageName(),
- MediaButtonReceiver.class.getName());
- //final Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
- //mediaButtonIntent.setComponent(mRemoteControlResponder);
- boolean useLockscreen = PrefUtils.getBoolean(getBaseContext(), "useLockscreen", true);
- mMediaSessionCompat = new MediaSessionCompat(this, "JairSession", mRemoteControlResponder, null);
- //mMediaSessionCompat.setFlags(useLockscreen ? MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS : MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
- mMediaSessionCompat.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
- mMediaSessionCompat.setCallback(mMediaSessionCallback);
- //mMediaSessionCompat.setRatingType(RatingCompat.RATING_HEART);
- //mMediaSessionCompat.setSessionActivity(retrievePlaybackActions(5));
- mMediaSessionCompat.setPlaybackState(new PlaybackStateCompat.Builder()
- .setState(PlaybackStateCompat.STATE_PAUSED, 0, 0)
- .setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_SKIP_TO_NEXT|PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS)
- .build());
- //updateMediaSessionMetaData();
- mMediaSessionCompat.setActive(true);
- //mTransportController = mMediaSessionCompat.getController().getTransportControls();
- //Log.d(LOG_TAG, "isActive = " + mMediaSessionCompat.isActive());
- //Log.d(LOG_TAG, "Remote = " + mMediaSessionCompat.getRemoteControlClient());
- }
- /**
- * Play the next song
- * @param songNumber current song number
- */
- public void playNext(int songNumber) {
- if (isShuffle) {
- Log.d(LOG_TAG, "Shuffling song");
- mPreviousSongNumber = mSongNumber;
- mSongNumber = mShuffler.nextInt(mSongs.size());
- if (mSongNumber < mSongs.size()) {
- Log.d(LOG_TAG, "Playing shuffled");
- play(mSongNumber);
- }
- } else {
- songNumber = songNumber + 1;
- if (songNumber < mSongs.size()) {
- Log.d(LOG_TAG, "Playing next song");
- mSongNumber = songNumber;
- mSong = mSongs.get(mSongNumber);
- //checkAndStartNotification();
- play(getSongPath());
- } else {
- Log.d(LOG_TAG, "Playing first song");
- mSongNumber = 0;
- mSong = mSongs.get(mSongNumber);
- //checkAndStartNotification();
- play(getSongPath());
- }
- }
- }
- /**
- * Play the previous song
- *
- * @param songNumber of current song
- */
- public void playPrevious(int songNumber) {
- if (mPreviousSongNumber != -1 && isShuffle) {
- if (mPreviousSongNumber < mSongs.size()) {
- Log.d(LOG_TAG, "Playing shuffled");
- play(mPreviousSongNumber);
- mPreviousSongNumber = -1;
- }
- } else {
- songNumber = songNumber - 1;
- if (songNumber >= 0 && songNumber < mSongs.size()) {
- Log.d(LOG_TAG, "Playing previous song");
- mSongNumber = songNumber;
- mSong = mSongs.get(mSongNumber);
- play(getSongPath());
- } else {
- Log.d(LOG_TAG, "Playing last song");
- mSongNumber = mSongs.size() - 1;
- mSong = mSongs.get(mSongNumber);
- play(getSongPath());
- }
- }
- }
- /**
- * Initiating the basic elements
- *
- * @param mSongs List of songs
- * @param songNumber of current song
- */
- public void init(ArrayList<Song> mSongs, int songNumber) {
- Log.d(LOG_TAG, "init()");
- setupMediaSession();
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- Log.d(LOG_TAG, "Destroying music service");
- releaseMediaSession();
- releaseAudioManager();
- }
- /**
- * Releasing the {@link android.media.AudioManager}
- */
- public void releaseAudioManager() {
- if (mAudioManager != null) {
- Log.d(LOG_TAG, "Un-registering Audio focus listener");
- mAudioManager.abandonAudioFocus(mAudioFocusListener);
- //Log.d(LOG_TAG, "Un-registering Remote controller");
- //mAudioManager.unregisterRemoteControlClient(mRemoteControlClient);
- }
- }
- private void releaseMediaSession() {
- if (mMediaSessionCompat != null && mMediaSessionCompat.isActive()) {
- Log.d(LOG_TAG, "Un-registering Media Session");
- mMediaSessionCompat.release();
- }
- }
- /**
- * Pause the media player playback
- */
- public void pause() {
- Log.d(LOG_TAG, "Music playback paused");
- mMediaPlayer.pause();
- // Update the lockscreen controls
- mMediaSessionCompat.setPlaybackState(
- new PlaybackStateCompat.Builder()
- .setState(PlaybackStateCompat.STATE_PAUSED, getCurrentPosition(), 1.0f)
- // .setActions(
- // PlaybackStateCompat.ACTION_SEEK_TO |
- // PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS |
- // PlaybackStateCompat.ACTION_SKIP_TO_NEXT |
- // PlaybackStateCompat.ACTION_PLAY_PAUSE |
- // PlaybackStateCompat.ACTION_PLAY |
- // PlaybackStateCompat.ACTION_PAUSE |
- // PlaybackStateCompat.ACTION_STOP
- // )
- .build());
- }
- /**
- * Start playing the song from song path
- *
- * @param path for song
- */
- public void play(String path) {
- Log.d(LOG_TAG, "Starting song playback");
- mMediaPlayer.reset();
- mMediaPlayer.setDataSource(path);
- mMediaPlayer.start();
- mMediaSessionCompat.setActive(true);
- updateMediaSessionMetaData();
- }
- /**
- * Resuming the paused song
- */
- public void resume() {
- Log.d(LOG_TAG, "Resuming song");
- mMediaPlayer.start();
- }
- /**
- * Play the song located at song number
- *
- * @param songNumber of current song
- */
- public void play(int songNumber) {
- if (songNumber < mSongs.size()) {
- Log.d(LOG_TAG, "Playing song");
- mSongNumber = songNumber;
- mSong = mSongs.get(songNumber);
- play(getSongPath());
- }
- }
- /**
- * Playing songs after completion of previous song
- * Intelligent algorithm which knows to shuffle
- * or repeat or reset song or end the queue
- */
- private void onSongCompletion() {
- Log.d(LOG_TAG, "Song playback completed");
- // Marks Step 1
- if (isShuffle) {
- // Shuffle->ON : Play a random song
- Log.d(LOG_TAG, "Shuffling song");
- mSongNumber = mShuffler.nextInt(mSongs.size());
- if (mSongNumber < mSongs.size()) {
- Log.d(LOG_TAG, "Playing shuffled");
- play(mSongNumber);
- }
- } else {
- // Marks Step 2
- if (isRepeatCurrent) {
- Log.d(LOG_TAG, "Repeating current song");
- seekTo(0);
- resume();
- } else {
- if (mSongNumber < mSongs.size() - 1) // 2nd last song
- playNext(mSongNumber);
- else {
- // Last song
- if (isRepeatAll) {
- Log.d(LOG_TAG, "Repeating the queue");
- play(0);
- } else {
- Log.d(LOG_TAG, "End of list");
- pause();
- }
- }
- }
- }
- }
- /**
- * @param which Which {@link android.app.PendingIntent} to return
- * @return A {@link android.app.PendingIntent} ready to control playback
- */
- private PendingIntent retrievePlaybackActions(final int which) {
- Intent action;
- PendingIntent pendingIntent;
- final ComponentName serviceName = new ComponentName(getBaseContext(), MusicPlaybackService.class);
- switch (which) {
- case 1:
- // Play and pause
- action = new Intent(MusicPlaybackService.PLAY_PAUSE_ACTION);
- action.setComponent(serviceName);
- pendingIntent = PendingIntent.getService(getBaseContext(), 1, action, 0);
- return pendingIntent;
- case 2:
- // Skip tracks
- action = new Intent(MusicPlaybackService.NEXT_ACTION);
- action.setComponent(serviceName);
- pendingIntent = PendingIntent.getService(getBaseContext(), 2, action, 0);
- return pendingIntent;
- case 3:
- // Previous tracks
- action = new Intent(MusicPlaybackService.PREVIOUS_ACTION);
- action.setComponent(serviceName);
- pendingIntent = PendingIntent.getService(getBaseContext(), 3, action, 0);
- return pendingIntent;
- case 4:
- // Stop and collapse the notification
- action = new Intent(MusicPlaybackService.STOP_ACTION);
- action.setComponent(serviceName);
- pendingIntent = PendingIntent.getService(getBaseContext(), 4, action, 0);
- return pendingIntent;
- case 5:
- Intent player = new Intent(getBaseContext(), Main.class);
- player.putExtra(NOW_PLAYING, true);
- pendingIntent = PendingIntent.getActivity(getBaseContext(), 0, player, PendingIntent.FLAG_UPDATE_CURRENT);
- return pendingIntent;
- default:
- break;
- }
- return null;
- }
- /**
- * Audio focus listener for Jair lockscreen key press listening
- */
- private final OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() {
- @Override
- public void onAudioFocusChange(final int focusChange) {
- // TODO: Add fading to loss & gain
- if (isMediaPlayerActive()) {
- Log.d(LOG_TAG, "F = " + focusChange);
- switch (focusChange) {
- case AudioManager.AUDIOFOCUS_LOSS:
- if (isPlaying())
- mPausedByTransientLossOfFocus = false;
- pause();
- break;
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
- if (isPlaying()) {
- mPausedByTransientLossOfFocus = true;
- pause();
- }
- break;
- case AudioManager.AUDIOFOCUS_GAIN:
- if (!isPlaying() && mPausedByTransientLossOfFocus) {
- mPausedByTransientLossOfFocus = false;
- //mCurrentVolume = 0f;
- //mMediaPlayer.setVolume(0f);
- resume();
- }
- break;
- /* case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
- // Lost focus for a short time, but it's ok to keep playing
- // at an attenuated level
- if (mMediaPlayer.isPlaying()) mMediaPlayer.setVolume(0.1f);
- break;*/
- default:
- }
- }
- }
- };
- /**
- * Updates the lockscreen controls, if enabled.
- */
- private void updateMediaSessionMetaData() {
- //boolean useLockscreen = PrefUtils.getBoolean(getBaseContext(), "useLockscreen", true);
- //if (useLockscreen/* && mSong != null*/) {
- mMediaSessionCompat.setPlaybackState(new PlaybackStateCompat.Builder()
- .setActions(
- PlaybackStateCompat.ACTION_PLAY_PAUSE |
- PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS |
- PlaybackStateCompat.ACTION_SKIP_TO_NEXT |
- )
- .setState(
- isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED,
- getCurrentPosition(),
- 1.0f)
- .build());
- mMediaSessionCompat.setMetadata(new MediaMetadataCompat.Builder()
- .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, getArtistName())
- .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, getAlbumName())
- .putString(MediaMetadataCompat.METADATA_KEY_TITLE, getTrackName())
- .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, getDuration())
- .putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, mSongNumber)
- .putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, mSongs.size())
- .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, MusicUtils.getArtwork(this, getAlbumID(), true))
- .build());
- mMediaSessionCompat.setActive(true);
- //}
- }
- private final MediaSessionCompat.Callback mMediaSessionCallback = new MediaSessionCompat.Callback() {
- @Override
- public void onPlay() {
- super.onPlay();
- //Log.d(LOG_TAG, "Play()");
- resume();
- }
- @Override
- public void onPause() {
- super.onPause();
- //Log.d(LOG_TAG, "onPause()");
- pause();
- }
- @Override
- public void onSkipToNext() {
- super.onSkipToNext();
- //Log.d(LOG_TAG, "onSkipToNext()");
- playNext(mSongNumber);
- }
- @Override
- public void onSkipToPrevious() {
- super.onSkipToPrevious();
- //Log.d(LOG_TAG, "onSkipToPrevious()");
- playPrevious(mSongNumber);
- }
- @Override
- public void onSeekTo(long pos) {
- super.onSeekTo(pos);
- //Log.d(LOG_TAG, "onSeekTo()");
- seekTo(pos);
- }
- @Override
- public void onStop() {
- super.onStop();
- //Log.d(LOG_TAG, "onStop()");
- pause();
- commitMusicData();
- updatePlayingUI(STOP_ACTION);
- stopSelf();
- }
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement