Java tutorial
package com.reallynourl.nourl.fmpfoldermusicplayer.backend; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.media.AudioManager; import android.media.MediaPlayer; import android.net.Uri; import android.os.IBinder; import android.os.PowerManager; import android.support.annotation.Nullable; import android.support.v4.media.session.MediaSessionCompat; import android.util.Log; import android.widget.Toast; import com.reallynourl.nourl.fmpfoldermusicplayer.ui.activity.MainActivity; import com.reallynourl.nourl.fmpfoldermusicplayer.ui.notifications.MediaNotification; import com.reallynourl.nourl.fmpfoldermusicplayer.utility.file.ExtendedFile; import java.io.File; import java.io.IOException; /** * Copyright (C) 2015 Jannes Peters * <p/> * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * <p/> * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * <p/> * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ public class MediaService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, AudioManager.OnAudioFocusChangeListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnInfoListener { private final static int MEDIA_ERROR_SYSTEM = -2147483648; private final static String MEDIA_SESSION_NAME = "fmp_folder_music_player_playback"; private static final int INTENT_MEDIA_KEYS = 1000; private static final int INTENT_SESSION_ACTIVITY = 1001; private static MediaService sInstance = null; private MediaPlayer mMediaPlayer; private MediaSessionCompat mMediaSession; private MediaEventReceiver mMediaEventReceiver; private boolean mIsPreparedToPlay = false; private ExtendedFile mCurrentFile; private void setupMediaPlayer(ExtendedFile file) { mIsPreparedToPlay = false; mCurrentFile = file; if (mMediaPlayer == null) { mMediaPlayer = new MediaPlayer(); mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK); mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnErrorListener(this); mMediaPlayer.setOnInfoListener(this); } else { if (mMediaPlayer.isPlaying()) mMediaPlayer.stop(); mMediaPlayer.reset(); } try { mMediaPlayer.setDataSource(getApplicationContext(), Uri.fromFile(file)); } catch (IOException e) { Toast.makeText(getApplicationContext(), "Failed to load the file.", Toast.LENGTH_LONG).show(); return; } mMediaPlayer.prepareAsync(); } public void play(ExtendedFile file) { setupMediaPlayer(file); } private boolean requestAudioFocus() { AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { mIsPreparedToPlay = false; Toast.makeText(getApplicationContext(), "Failed to get audio focus. Not starting playback.", Toast.LENGTH_LONG).show(); if (mMediaPlayer != null) { mMediaPlayer.stop(); } return false; } else { mMediaPlayer.setVolume(1.0f, 1.0f); } return true; } private boolean abandonAudioFocus() { AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); int result = audioManager.abandonAudioFocus(this); if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { Toast.makeText(getApplicationContext(), "Failed to remove audio focus.", Toast.LENGTH_LONG).show(); return false; } return true; } @Override public void onCreate() { super.onCreate(); mIsPreparedToPlay = false; if (sInstance != null) { sInstance = null; } mMediaEventReceiver = new MediaEventReceiver(); setupMediaSession(); sInstance = this; Log.d("Media Service", "Media Service created!"); } private void setupMediaSession() { mMediaSession = new MediaSessionCompat(getApplicationContext(), MEDIA_SESSION_NAME); mMediaSession.setCallback(mMediaEventReceiver); mMediaSession.setMediaButtonReceiver(PendingIntent.getBroadcast(getApplicationContext(), INTENT_MEDIA_KEYS, new Intent(getApplicationContext(), MediaIntentReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT)); mMediaSession.setQueueTitle("Now Playing"); mMediaSession.setSessionActivity(PendingIntent.getActivity(getApplicationContext(), INTENT_SESSION_ACTIVITY, new Intent(getApplicationContext(), MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT)); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { releasePlayer(); sInstance = null; mMediaSession.release(); mMediaSession = null; MediaNotification.remove(this); mMediaEventReceiver = null; Log.d("Media Service", "Media Service stopped!"); super.onDestroy(); } @Nullable public static MediaService getInstance() { return sInstance; } @Override public void onPrepared(MediaPlayer mp) { mIsPreparedToPlay = true; play(); } @Override public void onCompletion(MediaPlayer mp) { mIsPreparedToPlay = false; Log.d("MediaService", "onCompletion got called!"); MediaManager mediaManager = MediaManager.getInstance(); if (mediaManager == null) { stopSelf(); } else { MediaManager.getInstance().onCompletion(mp); MediaNotification.showUpdate(this); } } @Override public boolean onError(MediaPlayer mp, int what, int extra) { mIsPreparedToPlay = false; String message = "undefined media player error"; switch (what) { case MediaPlayer.MEDIA_ERROR_SERVER_DIED: message = "The media server died. This is probably not my fault, but playback had to be stopped, feel free to start it again."; break; case MediaPlayer.MEDIA_ERROR_UNKNOWN: switch (extra) { case MediaPlayer.MEDIA_ERROR_IO: message = "There was an error reading the current media file."; break; case MediaPlayer.MEDIA_ERROR_MALFORMED: message = "The file is probably not a valid audio file."; break; case MediaPlayer.MEDIA_ERROR_UNSUPPORTED: message = "The current file is not supported by your device, I'm really sorry."; break; case MediaPlayer.MEDIA_ERROR_TIMED_OUT: message = "The media player timed out."; break; case MediaService.MEDIA_ERROR_SYSTEM: message = "A low level system error occured. This should have never happened, sorry :/"; break; } break; } releasePlayer(); Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); return false; } @Override public void onAudioFocusChange(int focusChange) { switch (focusChange) { case AudioManager.AUDIOFOCUS_GAIN: if (mMediaPlayer != null) { mMediaPlayer.setVolume(1.0f, 1.0f); } break; case AudioManager.AUDIOFOCUS_LOSS: abandonAudioFocus(); if (mMediaPlayer != null) { releasePlayer(); } break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: pause(); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { mMediaPlayer.setVolume(0.15f, 0.15f); } break; } } private void releasePlayer() { mIsPreparedToPlay = false; if (mMediaPlayer != null) { if (mMediaPlayer.isPlaying()) { stop(); } mMediaSession.setActive(false); mMediaPlayer.release(); mMediaPlayer = null; } } public void pause() { if (mMediaPlayer != null && mIsPreparedToPlay && mMediaPlayer.isPlaying()) { mMediaPlayer.pause(); MediaNotification.showUpdate(this); abandonAudioFocus(); } } public void play() { if (mMediaPlayer != null && mIsPreparedToPlay && !mMediaPlayer.isPlaying()) { if (requestAudioFocus()) { mMediaPlayer.start(); mMediaPlayer.setOnCompletionListener(this); mMediaSession.setActive(true); MediaNotification.showUpdate(this); } } } public void seekTo(int msec) { if (mMediaPlayer != null && mIsPreparedToPlay && mMediaPlayer.getDuration() > msec) { mMediaPlayer.seekTo(msec); MediaNotification.showUpdate(this); } } public int getDuration() { if (mMediaPlayer != null && mIsPreparedToPlay) { return mMediaPlayer.getDuration(); } return 0; } public int getPosition() { if (mMediaPlayer != null && mIsPreparedToPlay) { return mMediaPlayer.getCurrentPosition(); } return 0; } public boolean isPlaying() { return mMediaPlayer != null && mMediaPlayer.isPlaying(); } public void stop() { if (mMediaPlayer != null && mIsPreparedToPlay) { mIsPreparedToPlay = false; if (mMediaPlayer.isPlaying()) mMediaPlayer.stop(); abandonAudioFocus(); releasePlayer(); MediaNotification.remove(this); } } public boolean isInitialized() { return mIsPreparedToPlay; } @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { Toast.makeText(this, "An info event was fired by the MediaPlayer.", Toast.LENGTH_SHORT).show(); return true; } @Nullable public ExtendedFile getCurrentFile() { return mCurrentFile; } public MediaSessionCompat getMediaSession() { return mMediaSession; } }