Skip to content

Instantly share code, notes, and snippets.

@tchiks1
Created April 4, 2019 10:23
Show Gist options
  • Save tchiks1/84b89a58bcb2d541f907242f59868d72 to your computer and use it in GitHub Desktop.
Save tchiks1/84b89a58bcb2d541f907242f59868d72 to your computer and use it in GitHub Desktop.
public class MediaPlayerService extends Service implements MediaPlayer.OnCompletionListener,
MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnSeekCompleteListener,
MediaPlayer.OnInfoListener, MediaPlayer.OnBufferingUpdateListener,
AudioManager.OnAudioFocusChangeListener {
public static final String ACTION_PLAY = "com.be.homsi.ACTION_PLAY";
public static final String ACTION_PAUSE = "com.be.homsi.ACTION_PAUSE";
public static final String ACTION_PREVIOUS = "com.be.homsi.ACTION_PREVIOUS";
public static final String ACTION_NEXT = "com.be.homsi.ACTION_NEXT";
public static final String ACTION_STOP = "com.be.homsi.ACTION_STOP";
//MediaSession
private MediaSessionManager mediaSessionManager;
private MediaSessionCompat mediaSession;
private MediaControllerCompat.TransportControls transportControls;
//AudioPlayer notification ID
private static final int NOTIFICATION_ID = 101;
// Binder given to clients
private final IBinder iBinder = new LocalBinder();
String newAudio;
private SeekBar mSeekBar;
private TextView mCurrentPosition;
private TextView mTotalDuration;
private int mInterval = 1000;
//Handle incoming phone calls
private boolean ongoingCall = false;
private PhoneStateListener phoneStateListener;
private TelephonyManager telephonyManager;
private AudioManager audioManager;
private MediaPlayer mediaPlayer;
//path to the audio file
private String mediaFile;
//Used to pause/resume MediaPlayer
private int resumePosition;
public static final String Broadcast_BTN_PLAY="com.be.homsi.btnplay";
public static final String Broadcast_BTN_PREVIOUS="com.be.homsi.btnprevious";
public static final String Broadcast_BTN_NEXT="com.be.homsi.btnnext";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
//An audio file is passed to the service through putExtra();
mediaFile = intent.getExtras().getString("media");
//play button custom notification
register_btn_previous();
register_btn_play();
register_btn_next();
} catch (NullPointerException e) {
stopSelf();
}
//Request audio focus
if (requestAudioFocus() == false) {
//Could not gain focus
stopSelf();
}
if (mediaFile != null && mediaFile != "")
initMediaPlayer();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onCreate() {
super.onCreate();
// Perform one-time setup procedures
// Manage incoming phone calls during playback.
// Pause MediaPlayer on incoming call,
// Resume on hangup.
callStateListener();
//ACTION_AUDIO_BECOMING_NOISY -- change in audio outputs -- BroadcastReceiver
registerBecomingNoisyReceiver();
//Listen for new Audio to play -- BroadcastReceiver
register_playNewAudio();
}
//receiver play button custom notification
private void register_btn_play() {
//Register playNewMedia receiver
IntentFilter filter = new IntentFilter(Broadcast_BTN_PLAY);
registerReceiver(playbtn, filter);
}
private void register_btn_previous() {
//Register playNewMedia receiver
IntentFilter filter = new IntentFilter(Broadcast_BTN_PREVIOUS);
registerReceiver(previousbtn, filter);
}
private void register_btn_next() {
//Register playNewMedia receiver
IntentFilter filter = new IntentFilter(Broadcast_BTN_NEXT);
registerReceiver(nextbtn, filter);
}
private BroadcastReceiver playbtn = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(mediaPlayer.isPlaying())
mediaPlayer.pause();
else{
mediaPlayer.start();
int duration = mediaPlayer.getDuration();
mSeekBar.setMax(duration);
mSeekBar.postDelayed(mProgressRunner, mInterval);
// Set our duration text view to display total duration in format 0:00
mTotalDuration.setText(String.format("%d:%02d",
TimeUnit.MILLISECONDS.toMinutes(duration),
TimeUnit.MILLISECONDS.toSeconds(duration) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration))
));
Log.d("playbtns","playbtn");
}
}
};
private BroadcastReceiver previousbtn = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if((mediaPlayer.getCurrentPosition() - 5000)>0){
mediaPlayer.seekTo(mediaPlayer.getCurrentPosition() - 5000);
}else
{
mediaPlayer.seekTo(0);
}
Log.d("pause","pause");
}
};
private BroadcastReceiver nextbtn = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if((mediaPlayer.getCurrentPosition() + 5000)<=mediaPlayer.getDuration()){
mediaPlayer.seekTo(mediaPlayer.getCurrentPosition() + 5000);
}else
{
mediaPlayer.seekTo(mediaPlayer.getDuration()-1000);
}
Log.d("pause","pause");
}
};
//Becoming noisy
private BroadcastReceiver becomingNoisyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//pause audio on ACTION_AUDIO_BECOMING_NOISY
pauseMedia();
// buildNotification(PlaybackStatus.PAUSED);
}
};
private BroadcastReceiver playNewAudio = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//Get the new media index form SharedPreferences
SharedPreferences preferences = context.getSharedPreferences(STORAGE, Context.MODE_PRIVATE);
newAudio=preferences.getString("newAudio",null);
mediaFile=newAudio;
if (newAudio == null ) {
stopSelf();
}
//A PLAY_NEW_AUDIO action received
//reset mediaPlayer to play the new Audio
stopMedia();
mediaPlayer.reset();
initMediaPlayer();
//updateMetaData();
// buildNotification(PlaybackStatus.PLAYING);
}
};
private void register_playNewAudio() {
//Register playNewMedia receiver
IntentFilter filter = new IntentFilter(Broadcast_PLAY_NEW_AUDIO);
registerReceiver(playNewAudio, filter);
}
private void registerBecomingNoisyReceiver() {
//register after getting audio focus
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
registerReceiver(becomingNoisyReceiver, intentFilter);
}
@Override
public void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
stopMedia();
mediaPlayer.release();
}
removeAudioFocus();
//Disable the PhoneStateListener
if (phoneStateListener != null) {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}
//removeNotification();
//unregister BroadcastReceivers
unregisterReceiver(becomingNoisyReceiver);
unregisterReceiver(playNewAudio);
SharedPreferences preferences = getSharedPreferences(STORAGE, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.clear();
editor.apply();
}
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
//Invoked indicating buffering status of
//a media resource being streamed over the network.
}
@Override
public void onCompletion(MediaPlayer mp) {
//Invoked when playback of a media source has completed.
stopMedia();
//stop the service
stopSelf();
}
//Handle errors
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
//Invoked when there has been an error during an asynchronous operation
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Log.d("MediaPlayer Error", "MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + extra);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.d("MediaPlayer Error", "MEDIA ERROR SERVER DIED " + extra);
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.d("MediaPlayer Error", "MEDIA ERROR UNKNOWN " + extra);
break;
}
return false;
}
// Async thread to update progress bar every second
private Runnable mProgressRunner = new Runnable() {
@Override
public void run() {
if (mSeekBar != null) {
mSeekBar.setProgress(mediaPlayer.getCurrentPosition());
if(mediaPlayer.isPlaying()) {
mSeekBar.postDelayed(mProgressRunner, mInterval);
}
}
}
};
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
//Invoked to communicate some info.
return false;
}
@Override
public void onPrepared(MediaPlayer mp) {
//Invoked when the media source is ready for playback.
playMedia();
}
@Override
public void onSeekComplete(MediaPlayer mp) {
//Invoked indicating the completion of a seek operation.
}
@Override
public void onAudioFocusChange(int focusState) {
//Invoked when the audio focus of the system is updated.
switch (focusState) {
case AudioManager.AUDIOFOCUS_GAIN:
// resume playback
if (mediaPlayer == null) initMediaPlayer();
else if (!mediaPlayer.isPlaying()) mediaPlayer.start();
mediaPlayer.setVolume(1.0f, 1.0f);
break;
case AudioManager.AUDIOFOCUS_LOSS:
// Lost focus for an unbounded amount of time: stop playback and release media player
if (mediaPlayer.isPlaying()) mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// Lost focus for a short time, but we have to stop
// playback. We don't release the media player because playback
// is likely to resume
if (mediaPlayer.isPlaying()) mediaPlayer.pause();
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 (mediaPlayer.isPlaying()) mediaPlayer.setVolume(0.1f, 0.1f);
break;
}
}
private boolean requestAudioFocus() {
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
//Focus gained
return true;
}
//Could not gain focus
return false;
}
private boolean removeAudioFocus() {
return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
audioManager.abandonAudioFocus(this);
}
public int updateseekbar(){
return mediaPlayer.getCurrentPosition();
}
public int totalduration(){
return mediaPlayer.getDuration();
}
@Override
public IBinder onBind(Intent intent) {
return iBinder;
}
public class LocalBinder extends Binder {
public MediaPlayerService getService() {
return MediaPlayerService.this;
}
}
private void initMediaPlayer() {
mediaPlayer = new MediaPlayer();
//Set up MediaPlayer event listeners
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnSeekCompleteListener(this);
mediaPlayer.setOnInfoListener(this);
//Reset so that the MediaPlayer is not pointing to another data source
mediaPlayer.reset();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
// Set the data source to the mediaFile location
mediaPlayer.setDataSource(mediaFile);
} catch (IOException e) {
e.printStackTrace();
stopSelf();
}
mediaPlayer.prepareAsync();
}
private void playMedia() {
buildNotification();
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
int duration = mediaPlayer.getDuration();
mSeekBar.setMax(duration);
mSeekBar.postDelayed(mProgressRunner, mInterval);
// Set our duration text view to display total duration in format 0:00
mTotalDuration.setText(String.format("%d:%02d",
TimeUnit.MILLISECONDS.toMinutes(duration),
TimeUnit.MILLISECONDS.toSeconds(duration) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration))
));
}
}
/**
* Sets seekBar to control while playing music
* @param seekBar - Seek bar instance that's already on our UI thread
*/
public void setUIControls(SeekBar seekBar, TextView currentPosition, TextView totalDuration) {
mSeekBar = seekBar;
mCurrentPosition = currentPosition;
mTotalDuration = totalDuration;
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
// Change current position of the song playback
mediaPlayer.seekTo(progress);
}
// Update our textView to display the correct number of second in format 0:00
mCurrentPosition.setText(String.format("%d:%02d",
TimeUnit.MILLISECONDS.toMinutes(progress),
TimeUnit.MILLISECONDS.toSeconds(progress) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(progress))
));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
}
private void stopMedia() {
if (mediaPlayer == null) return;
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
}
private void pauseMedia() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
resumePosition = mediaPlayer.getCurrentPosition();
}
}
public Boolean isPlaying(){
Boolean b=false;
if(mediaPlayer.isPlaying()){
b=true;
}
return b;
}
private void resumeMedia() {
if (!mediaPlayer.isPlaying()) {
mediaPlayer.seekTo(resumePosition);
mediaPlayer.start();
}
}
//Handle incoming phone calls
private void callStateListener() {
// Get the telephony manager
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
//Starting listening for PhoneState changes
phoneStateListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
//if at least one call exists or the phone is ringing
//pause the MediaPlayer
case TelephonyManager.CALL_STATE_OFFHOOK:
case TelephonyManager.CALL_STATE_RINGING:
if (mediaPlayer != null) {
pauseMedia();
ongoingCall = true;
}
break;
case TelephonyManager.CALL_STATE_IDLE:
// Phone idle. Start playing.
if (mediaPlayer != null) {
if (ongoingCall) {
ongoingCall = false;
resumeMedia();
}
}
break;
}
}
};
// Register the listener with the telephony manager
// Listen for changes to the device call state.
telephonyManager.listen(phoneStateListener,
PhoneStateListener.LISTEN_CALL_STATE);
}
private void buildNotification(){
RemoteViews expandedViews = new RemoteViews(getPackageName(), R.layout.big_notification);
NotificationCompat.Builder nc=new NotificationCompat.Builder(getApplicationContext(),"mediacontrol");
NotificationManager nm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
Intent notifyIntent = new Intent(getApplicationContext(), Interpretation.class);
//demarrer un intent implicite pour le button play
Intent playbutton=new Intent(Broadcast_BTN_PLAY);
//sendBroadcast(playbutton);
playbutton.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntents=PendingIntent.getBroadcast(getApplicationContext(),0,playbutton,0
);
expandedViews.setOnClickPendingIntent(R.id.play,pendingIntents);
//demarrer un intent implicite pour le button previous
Intent pausebutton=new Intent(Broadcast_BTN_PREVIOUS);
//sendBroadcast(pausebutton);
playbutton.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingpausebutton=PendingIntent.getBroadcast(getApplicationContext(),0,pausebutton,0
);
expandedViews.setOnClickPendingIntent(R.id.previous,pendingpausebutton);
//demarrer un intent implicite pour le button play
Intent nextbutton=new Intent(Broadcast_BTN_NEXT);
//sendBroadcast(pausebutton);
playbutton.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingnextbutton=PendingIntent.getBroadcast(getApplicationContext(),0,nextbutton,0
);
expandedViews.setOnClickPendingIntent(R.id.next,pendingnextbutton);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent=PendingIntent.getActivity(getApplicationContext(),0,notifyIntent,PendingIntent.FLAG_UPDATE_CURRENT);
nc.setContentIntent(pendingIntent);
nc.setSmallIcon(R.drawable.logo);
nc.setAutoCancel(true);
nc.setCustomBigContentView(expandedViews);
nc.setContentTitle("Homsi");
//nc.getBigContentView().setTextViewText(R.id.nom,"Sainte monique");
nm.notify(NOTIFICATION_ID,nc.build());
}
private void removeNotification() {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(NOTIFICATION_ID);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment