diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7616244..6092008 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -24,6 +24,7 @@ + \ No newline at end of file diff --git a/app/src/main/java/fr/svpro/radiomercure/MainActivity.java b/app/src/main/java/fr/svpro/radiomercure/MainActivity.java index b1f2ad7..0d4a3a4 100644 --- a/app/src/main/java/fr/svpro/radiomercure/MainActivity.java +++ b/app/src/main/java/fr/svpro/radiomercure/MainActivity.java @@ -4,22 +4,20 @@ import android.Manifest; import android.annotation.SuppressLint; import android.app.Dialog; import android.app.DownloadManager; +import android.content.ComponentName; +import android.content.Context; import android.content.Intent; +import android.content.ServiceConnection; import android.content.pm.PackageManager; -import android.media.MediaPlayer; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; -import android.os.PowerManager; -import android.util.Log; +import android.os.IBinder; import android.view.Menu; import android.view.MenuItem; -import android.view.WindowManager; import android.webkit.CookieManager; -import android.webkit.JavascriptInterface; import android.webkit.URLUtil; -import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; @@ -30,8 +28,6 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; -import java.io.IOException; - public class MainActivity extends AppCompatActivity { private static final int WRITE_EXTERNAL_STORAGE_RC = 100; @@ -43,6 +39,8 @@ public class MainActivity extends AppCompatActivity { private TextView tv_version; private static String versionName; private static final String NUMERO_TEL_RADIO = "+33375411456"; + private MediaPlayerService player; + boolean serviceBound = false; static { versionName = BuildConfig.VERSION_NAME; @@ -177,20 +175,13 @@ public class MainActivity extends AppCompatActivity { return true; case R.id.live: - MediaPlayer mediaPlayer = new MediaPlayer(); - mediaPlayer.setScreenOnWhilePlaying(true); - try { - mediaPlayer.setDataSource("https://live.radiomercure.fr/on-air/live"); - } catch (IOException e) { - e.printStackTrace(); - } - try { - mediaPlayer.prepare(); - } catch (IOException e) { - e.printStackTrace(); - } - mediaPlayer.start(); - return true; + liveRadio("https://live.radiomercure.fr/on-air/live"); + + /* Intent playerIntent = new Intent(this, MediaPlayerService.class); + startService(playerIntent); + bindService(playerIntent, serviceConnection, Context.BIND_AUTO_CREATE);*/ + + return true; default: return super.onOptionsItemSelected(item); @@ -207,4 +198,56 @@ public class MainActivity extends AppCompatActivity { } } + //Binding this Client to the AudioPlayer Service + private ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + MediaPlayerService.LocalBinder binder = (MediaPlayerService.LocalBinder) service; + player = binder.getService(); + serviceBound = true; + + Toast.makeText(MainActivity.this, "Vous écoutez Radio Mercure en direct", Toast.LENGTH_SHORT).show(); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + serviceBound = false; + } + }; + + private void liveRadio(String StreamUrl) { + //Check is service is active + if (!serviceBound) { + Intent playerIntent = new Intent(this, MediaPlayerService.class); + playerIntent.putExtra("stream_url",StreamUrl); + startService(playerIntent); + bindService(playerIntent, serviceConnection, Context.BIND_AUTO_CREATE); + } else { + //Toast.makeText(player, "OK", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + savedInstanceState.putBoolean("ServiceState", serviceBound); + super.onSaveInstanceState(savedInstanceState); + } + + @Override + public void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + serviceBound = savedInstanceState.getBoolean("ServiceState"); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (serviceBound) { + unbindService(serviceConnection); + //service is active + player.stopSelf(); + } + } + } \ No newline at end of file diff --git a/app/src/main/java/fr/svpro/radiomercure/MediaPlayerService.java b/app/src/main/java/fr/svpro/radiomercure/MediaPlayerService.java new file mode 100644 index 0000000..2bb8e7e --- /dev/null +++ b/app/src/main/java/fr/svpro/radiomercure/MediaPlayerService.java @@ -0,0 +1,176 @@ +package fr.svpro.radiomercure; + +import android.app.Service; +import android.content.Intent; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.os.Binder; +import android.os.IBinder; +import android.util.Log; + +import java.io.IOException; + +public class MediaPlayerService extends Service implements MediaPlayer.OnCompletionListener, + MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnSeekCompleteListener, + MediaPlayer.OnInfoListener, MediaPlayer.OnBufferingUpdateListener, + + AudioManager.OnAudioFocusChangeListener { + + + // 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: + 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; + } + + @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 focusChange) { + //Invoked when the audio focus of the system is updated. + } + + public class LocalBinder extends Binder { + public MediaPlayerService getService() { + return MediaPlayerService.this; + } + } + + private MediaPlayer mediaPlayer; + private String StreamUrl; + + 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(false); + //Reset so that the MediaPlayer is not pointing to another data source + mediaPlayer.reset(); + + mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + try { + mediaPlayer.setDataSource(StreamUrl); + } 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(); + StreamUrl = intent.getExtras().getString("stream_url"); + } catch (NullPointerException e) { + stopSelf(); + } + + //Request audio focus + /* if (requestAudioFocus() == false) { + //Could not gain focus + stopSelf(); + }*/ + + if (StreamUrl != null && StreamUrl != "") + initMediaPlayer(); + + return super.onStartCommand(intent, flags, startId); + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (mediaPlayer != null) { + stopMedia(); + mediaPlayer.release(); + } + //removeAudioFocus(); + } + + +}