Browse Source
Merge branch 'testing'
Merge branch 'testing'
# Conflicts: # app/src/main/java/fr/svpro/radiomercure/MainActivity.javamaster
9 changed files with 304 additions and 25 deletions
-
17.idea/deploymentTargetDropDown.xml
-
4.idea/misc.xml
-
4app/build.gradle
-
5app/src/main/AndroidManifest.xml
-
2app/src/main/java/fr/svpro/radiomercure/MainActivity.java
-
268app/src/main/java/fr/svpro/radiomercure/MediaPlayerService.java
-
10app/src/main/res/layout/activity_main.xml
-
7app/src/main/res/menu/option.xml
-
12app/src/main/res/values/strings.xml
@ -1,17 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project version="4"> |
|||
<component name="deploymentTargetDropDown"> |
|||
<targetSelectedWithDropDown> |
|||
<Target> |
|||
<type value="QUICK_BOOT_TARGET" /> |
|||
<deviceKey> |
|||
<Key> |
|||
<type value="VIRTUAL_DEVICE_PATH" /> |
|||
<value value="C:\Users\samue\.android\avd\Nexus_6_API_29.avd" /> |
|||
</Key> |
|||
</deviceKey> |
|||
</Target> |
|||
</targetSelectedWithDropDown> |
|||
<timeTargetWasSelectedWithDropDown value="2022-03-31T21:48:44.877184900Z" /> |
|||
</component> |
|||
</project> |
@ -0,0 +1,268 @@ |
|||
package fr.svpro.radiomercure; |
|||
|
|||
import android.app.Service; |
|||
import android.content.Context; |
|||
import android.content.Intent; |
|||
import android.media.AudioManager; |
|||
import android.media.MediaPlayer; |
|||
import android.os.Binder; |
|||
import android.os.Build; |
|||
import android.os.IBinder; |
|||
import android.telephony.PhoneStateListener; |
|||
import android.telephony.TelephonyManager; |
|||
import android.util.Log; |
|||
import android.widget.Toast; |
|||
|
|||
import androidx.annotation.RequiresApi; |
|||
|
|||
import java.io.IOException; |
|||
|
|||
@RequiresApi(api = Build.VERSION_CODES.O) |
|||
public class MediaPlayerService extends Service implements MediaPlayer.OnCompletionListener, |
|||
MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnSeekCompleteListener, |
|||
MediaPlayer.OnInfoListener, MediaPlayer.OnBufferingUpdateListener, |
|||
|
|||
AudioManager.OnAudioFocusChangeListener { |
|||
|
|||
private AudioManager audioManager; |
|||
|
|||
// Binder given to clients |
|||
private final IBinder iBinder = new LocalBinder(); |
|||
|
|||
@Override |
|||
public IBinder onBind(Intent intent) { |
|||
return iBinder; |
|||
} |
|||
|
|||
@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: |
|||
Toast.makeText(this, "Données corrompues", Toast.LENGTH_SHORT).show(); |
|||
Log.d("MediaPlayer Error", "MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + extra); |
|||
break; |
|||
case MediaPlayer.MEDIA_ERROR_SERVER_DIED: |
|||
Toast.makeText(this, "Serveur innacessible", Toast.LENGTH_SHORT).show(); |
|||
Log.d("MediaPlayer Error", "MEDIA ERROR SERVER DIED " + extra); |
|||
break; |
|||
case MediaPlayer.MEDIA_ERROR_UNKNOWN: |
|||
Toast.makeText(this, "Erreur inconnue", Toast.LENGTH_SHORT).show(); |
|||
Log.d("MediaPlayer Error", "MEDIA ERROR UNKNOWN " + extra); |
|||
break; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
@Override |
|||
public boolean onInfo(MediaPlayer mp, int what, int extra) { |
|||
//Invoked to communicate some info. |
|||
return false; |
|||
} |
|||
|
|||
@Override |
|||
public void onPrepared(MediaPlayer mp) { |
|||
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 class LocalBinder extends Binder { |
|||
public MediaPlayerService getService() { |
|||
return MediaPlayerService.this; |
|||
} |
|||
} |
|||
|
|||
private MediaPlayer mediaPlayer; |
|||
private String fichierMedia; |
|||
|
|||
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); |
|||
//mediaPlayer.setScreenOnWhilePlaying(true); |
|||
//Reset so that the MediaPlayer is not pointing to another data source |
|||
mediaPlayer.reset(); |
|||
|
|||
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); |
|||
try { |
|||
mediaPlayer.setDataSource(fichierMedia); |
|||
} catch (IOException e) { |
|||
e.printStackTrace(); |
|||
stopSelf(); |
|||
} |
|||
mediaPlayer.prepareAsync(); |
|||
} |
|||
|
|||
//Used to pause/resume MediaPlayer |
|||
private int resumePosition; |
|||
|
|||
private void playMedia() { |
|||
if (!mediaPlayer.isPlaying()) { |
|||
mediaPlayer.start(); |
|||
} |
|||
} |
|||
|
|||
private void stopMedia() { |
|||
if (mediaPlayer == null) return; |
|||
if (mediaPlayer.isPlaying()) { |
|||
mediaPlayer.stop(); |
|||
} |
|||
} |
|||
|
|||
private void pauseMedia() { |
|||
if (mediaPlayer.isPlaying()) { |
|||
mediaPlayer.pause(); |
|||
resumePosition = mediaPlayer.getCurrentPosition(); |
|||
} |
|||
} |
|||
|
|||
private void resumeMedia() { |
|||
if (!mediaPlayer.isPlaying()) { |
|||
mediaPlayer.seekTo(resumePosition); |
|||
mediaPlayer.start(); |
|||
} |
|||
} |
|||
|
|||
//The system calls this method when an activity, requests the service be started |
|||
@Override |
|||
public int onStartCommand(Intent intent, int flags, int startId) { |
|||
try { |
|||
//An audio file is passed to the service through putExtra(); |
|||
fichierMedia = intent.getExtras().getString("media"); |
|||
} catch (NullPointerException e) { |
|||
stopSelf(); |
|||
} |
|||
|
|||
//Request audio focus |
|||
if (requestAudioFocus() == false) { |
|||
//Could not gain focus |
|||
stopSelf(); |
|||
} |
|||
|
|||
if (fichierMedia != null && fichierMedia != "") |
|||
initMediaPlayer(); |
|||
|
|||
return super.onStartCommand(intent, flags, startId); |
|||
} |
|||
|
|||
@Override |
|||
public void onDestroy() { |
|||
super.onDestroy(); |
|||
if (mediaPlayer != null) { |
|||
stopMedia(); |
|||
mediaPlayer.release(); |
|||
} |
|||
removeAudioFocus(); |
|||
} |
|||
|
|||
//Gestion des appels tel entrant : suspension de la lecture |
|||
private boolean ongoingCall = false; |
|||
private PhoneStateListener phoneStateListener; |
|||
private TelephonyManager telephonyManager; |
|||
|
|||
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); |
|||
} |
|||
|
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue