Media Player loading media again and again - java

I am making a chat application and I have implemented the feature for sending audio messages.But here I find one thing which I don't want it to happen.It is that whenever my adapter gets updated,The media player starts loading again. In this way there will be an issue for if someone is listening to an audio and the user at other end sends a message ,the media player stops and it loads again.Here is the code of my adapter.
final MediaPlayer mediaPlayer;
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
handler = new Handler();
try {
mediaPlayer.setOnCompletionListener(mediaPlayer1 -> {
mediaPlayer1.stop();
binding.audioSeekbar.setProgress(0);
});
if (mediaPlayer.isPlaying()){
mediaPlayer.stop();
mediaPlayer.release();
}
mediaPlayer.setDataSource(finalUrlToLoad[1]);
mediaPlayer.setVolume(1f, 1f);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(mediaPlayer1 -> {
int totalDuration = mediaPlayer1.getDuration();
binding.totalDurationAudio.setText(createTimeLabel(totalDuration));
binding.loadingAudio.setVisibility(GONE);
binding.playPauseAudio.setVisibility(VISIBLE);
});
} catch (IOException e) {e.printStackTrace();}
binding.playPauseAudio.setOnClickListener(view -> {
if (mediaPlayer.isPlaying()){
handler.removeCallbacks(runnable);
mediaPlayer.pause();
binding.playPauseAudio.setImageResource(R.drawable.pause_to_play);
Drawable drawable = binding.playPauseAudio.getDrawable();
if( drawable instanceof AnimatedVectorDrawable) {
AnimatedVectorDrawable animation = (AnimatedVectorDrawable) drawable;
animation.start();
}
}else {
mediaPlayer.seekTo(binding.audioSeekbar.getProgress());
mediaPlayer.start();
handler.post(runnable);
binding.playPauseAudio.setImageResource(R.drawable.play_to_pause);
Drawable drawable = binding.playPauseAudio.getDrawable();
if( drawable instanceof AnimatedVectorDrawable) {
AnimatedVectorDrawable animation = (AnimatedVectorDrawable) drawable;
animation.start();
}
}
});
runnable = () -> {
int totalTime = mediaPlayer.getDuration();
binding.audioSeekbar.setMax(totalTime);
int currentPosition = mediaPlayer.getCurrentPosition();
binding.audioSeekbar.setProgress(currentPosition);
binding.totalDurationAudio.setText(createTimeLabel(totalTime));
Log.d("time", String.valueOf(currentPosition));
handler.postDelayed(runnable,1000);
};
binding.audioSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (b){
mediaPlayer.seekTo(i);
seekBar.setProgress(i);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mediaPlayer.setOnBufferingUpdateListener((mediaPlayer1, i) -> binding.audioSeekbar.setSecondaryProgress(i));
Here finalurltoload[1] is the url for the audio.
Now what do I need to do in order to prevent loading it again and again.
I will be really grateful to who answer this question.
Thanks😊.

It's hard to tell from this code but I assume this is all set in your onBind event? If so, then this means every time RecyclerView creates a new holder and binds it, the associated media will be prepped and loaded, and whichever is the 'last holder to have been called with onBind, "wins" (and is what MediaPlayer will be loaded with). Since by default RecyclerView typically creates multiple holders up front, you are seeing your MediaPlayer being "loaded" multiple times.
You probably just don't want to do the initialization of each audio message in the onBind. Instead, just use the onBind event to initialize state variables (duration, progress, etc.) to some default value, hide them and bind the specific audio Uri. Then when the user takes some action like tapping on the holder, you unhide an indeterminate progress bar while the initialization takes place, and in the onPrepared() event unhide the state information (duration, progress, seekbar, etc.), and finally hide the indeterminate progress bar and start the audio.
I assume you are also sending over the sound file as part of your messaging app (i.e. not storing it on the web somewhere in a central location?), and this file gets stored in an app-specific storage location? If so, you don't need to worry about persisting the permission to that URI, but if that isn't the case you will.

First extract the media player code into singleton class like AudioManager.
Add few method like setMediaUpdateListener that set a callback for seek duration. and togglePlayPause to play or pause the audio.
Passed the message id or any unique identifier to the audio manager while playing the video.
In Adapter class onBind Method.
First Compare the id and playing Id is same like AudioManager.getInstance().isPlaying(messageId);
If yes then set the seekUpdatelistner to the audio manager class.
also update the play/pause icon based on AudioManager.isPlaying() method.
3.if user play other message by clicking play button. call AudioManager.play(message) method.In which we release the previous message and play the new one.
If current message is not playing then reset the view on non-playing state.
If Auto play is enabled then you need to check if audioManager is free then only you can play the last message otherwise ignored.
Like a class who are managing the audio for you and store all the state.
class AudioManager {
public static AudioManager instance;
final MediaPlayer mediaPlayer;
private AudioListener audioListener;
private Uri currentPlaying;
public AudioManager getInstance() {
if (instance == null) {
instance = new AudioManager();
}
}
public void play(Uri dataUri) {
if (mediaPlayer != null && currentPlaying == null || currentPlaying.equals(dataUri)) {
if (!mediaPlayer.isPlaying) {
mediaPlayer.play();
}
return;
} else if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
handler = new Handler();
try {
mediaPlayer.setOnCompletionListener(mediaPlayer1 -> {
mediaPlayer1.stop();
sendProgress(0);
});
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
}
mediaPlayer.setDataSource(dataUri;
mediaPlayer.setVolume(1f, 1f);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(mediaPlayer1 -> {
int totalDuration = mediaPlayer1.getDuration();
sendTotalDuration(totalDuration);
});
} catch (IOException e) {
e.printStackTrace();
}
}
public void pause() {
// update the pause code.
}
public void sendProgress(int progress) {
if (audioListener != null) {
audioListener.onProgress(progress);
}
}
public void sendTotalDuration(int duration) {
if (audioListener != null) {
audioListener.onTotalDuraration(duration);
}
}
public void AudioListener(AudioListener audioListener) {
this.audioListener = audioListener;
}
public interface AudioListener {
void onProgress(int progress);
void onTotalDuraration(int duration);
void onAudioPlayed();
void onAudioPaused():
}
}

Related

Is it good practice or necessary to use a Service to use a Media Player in the backgound

Hello StackOverflow's users,
I'm developing a Music Player App for android. In my main activity when the user clicks on a song I start a new intent that displays PlayerActivity. In there, I initialize a MediaPlayer and all the other UI elements. When the user clicks the back button, I bring them back to the main activity and the song continues to play in the background. The same thing happens if they exit the application. Now I was wondering if it's fine to do something like this or if I should instead start a new Service for the MediaPlayer from the PlayerActivity class instead of doing it in there.
PlayerActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
Bundle extras = getIntent().getExtras();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));
getWindow().setNavigationBarColor(getResources().getColor(R.color.colorPrimaryDark));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
getWindow().setNavigationBarDividerColor(getResources().getColor(R.color.white));
}
playBtn = findViewById(R.id.btn_play);
artImage = findViewById(R.id.art);
remainingTimeLabel = findViewById(R.id.current_song_duration);
totalTimeLabel = findViewById(R.id.total_duration);
manager = MainActivity.getManager();
Song song = manager.getCurrentSong();
boolean wasCall = extras != null && extras.containsKey("call");
if (!wasCall && manager.hasStarted()) {
MediaPlayer mediaPlayer = manager.getMediaPlayer();
mediaPlayer.pause();
mediaPlayer.stop();
}
if (!wasCall) {
mp = MediaPlayer.create(this, Uri.parse(song.getPath()));
mp.setLooping(true);
mp.seekTo(0);
mp.setVolume(0.5f, 0.5f);
} else {
mp = manager.getMediaPlayer();
mp.setLooping(true);
mp.setVolume(0.5f, 0.5f);
}
totalTime = mp.getDuration();
artImage.setImageBitmap(Bitmap.createScaledBitmap(song.getIcon(), 250, 250, true));
totalTimeLabel.setText(createTimeLabel(totalTime));
songName = findViewById(R.id.songName);
songName.setText(song.getName());
songAuthor = findViewById(R.id.songAuthor);
songAuthor.setText(song.getArtist());
Toolbar toolbar = findViewById(R.id.player_top_bar);
toolbar.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
setSupportActionBar(toolbar);
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
assert toolbar.getNavigationIcon() != null;
toolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
getSupportActionBar().setTitle(Html.fromHtml("<font color='#ffffff'>MySound</font>"));
positionBar = findViewById(R.id.seek_song_progressbar);
positionBar.setMax(totalTime);
positionBar.setOnSeekBarChangeListener(
new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
mp.seekTo(progress);
positionBar.setProgress(progress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
);
LinearLayout layout = findViewById(R.id.player_control);
layout.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
new Thread(() -> {
while (mp != null) {
try {
Message msg = new Message();
msg.what = mp.getCurrentPosition();
handler.sendMessage(msg);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
this.action = SongEndAction.REPEAT;
mp.start();
manager.setMediaPlayer(mp);
}
Here is a Music Service that I implemented in my book.
https://github.com/Wickapps/Practical-Android-MusicService
This implementation includes play, stop, and seek forward, but you could add other functions.
Service is the best architecture for future scalability.
There is a MainActivity.java which starts the service.
MusicService.java is the service implementation.
Hope this helps.
If you want your app to keep playing audio while it's in background ( like spotify ), then yes, it is a must to use a foreground service.
Unfortunately it's more complex than your current implementation.
This is a nice starting point : https://developer.android.com/guide/topics/media-apps/audio-app/building-an-audio-app

Transport Controls not Updating after MediaPlayerService is destroyed

Okay. I have been struggling with this issue for a while.
Since the latest Wear OS upgrade, a play/pause transport control is displayed in the notification panel instead of showing media controls on a notification. My media player service works fine until it has been paused for some time and android destroys it as it has moved to the background. If the user selects the play button from the transport controls, the music starts playing as it should, but the transport controls no longer update meaning the user can only hit play and can no longer pause. This can be very frustrating if they need to stop audio and can't.
Here is the code where I initialize the media session. This is called at onCreate
private void initMediaSession() {
if (mediaSessionManager != null) return;
mediaSessionManager = (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE);
//Create a new mediaSession
mediaSession = new MediaSessionCompat(getApplicationContext(), "com.turndapage.navmusic.mediaplayer");
//Get mediaSessions Transport Controls
mediaSession.getController().getTransportControls();
//Set Mediasession ready to receive media commands
mediaSession.setActive(true);
mediaSession.setFlags(
MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
callback = new MediaSessionCompat.Callback() {
// Implement callbacks
#Override
public void onPlay() {
super.onPlay();
Cat.d("Playing from transport controls.");
// This is the event that is triggered from the transport controls
resumeMedia();
}
#Override
public void onPause() {
super.onPause();
Cat.d("Pausing from transport controls");
pauseMedia();
}
#Override
public void onSkipToNext() {
super.onSkipToNext();
skipToNext();
}
#Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
skipToPrevious();
}
#Override
public void onStop() {
super.onStop();
stop();
}
#Override
public void onSeekTo(long position) {
super.onSeekTo(position);
mediaPlayer.seekTo((int)position);
}
#Override
public void onFastForward() {
super.onFastForward();
fastForward();
}
#Override
public void onRewind() {
super.onRewind();
rewind();
}
#Override
public void onPlayFromMediaId(String mediaId, Bundle extras) {
int id = Integer.parseInt(mediaId.replace("song", ""));
int thisIndex = 0;
for(Song song : songLibrary.getSongs()) {
if(song.getID() == id) {
ArrayList<Song> songs = getCurrentList();
thisIndex = songs.indexOf(song);
break;
}
}
int[] ids = new int[getCurrentList().size()];
for(int i = 0; i < ids.length; i++) {
ids[i] = getCurrentList().get(i).getID();
}
startPlaying(ids, thisIndex);
}
#Override
public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
KeyEvent event = mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
Cat.e("onMediaButtonEvent called: " + event);
if (event.getAction() == KeyEvent.ACTION_UP) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_MEDIA_PAUSE:
pauseMedia();
break;
case KeyEvent.KEYCODE_MEDIA_PLAY:
playMedia();
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
//skipToNext();
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
//skipToPrevious();
break;
}
}
return super.onMediaButtonEvent(mediaButtonEvent);
}
};
// Attach a callback to receive MediaSession update
mediaSession.setCallback(callback);
setSessionToken(mediaSession.getSessionToken());
}
This method is called when the user clicks the play transport control
public void resumeMedia() {
wasPlaying = true;
if(mediaPlayer != null) {
try {
if (!getPlaying()) {
mediaPlayer.seekTo(resumePosition);
mediaPlayer.start();
sendPlayPauseUpdate(true);
buildNotification(true);
}
ComplicationHelper.updatePlayPause(this, true);
} catch (IllegalStateException ex) {
ex.printStackTrace();
//restoreState();
startMediaPlayer();
}
}
}
the send play/pause update just sends a broadcast to the activity to update controls there.
Inside the notification code, I have this to update the playback state of the media session. As you can see, the pause or play actions are only added based on whether the media player is playing or not. Despite this, the play action is still displayed:
long actions = MEDIA_SESSION_ACTIONS;
if(isPlaying)
actions |= PlaybackStateCompat.ACTION_PAUSE;
else
actions |= PlaybackStateCompat.ACTION_PLAY;
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setActions(actions)
.setState(isPlaying ? PlaybackStateCompat.STATE_PLAYING :
PlaybackStateCompat.STATE_PAUSED, resumePosition, 1)
.build());
and here are the media session actions:
// Media Session Actions
private static final long MEDIA_SESSION_ACTIONS =
PlaybackStateCompat.ACTION_SEEK_TO |
PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS |
PlaybackStateCompat.ACTION_SKIP_TO_NEXT |
PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH |
PlaybackStateCompat.ACTION_PREPARE |
PlaybackStateCompat.ACTION_PREPARE_FROM_SEARCH |
PlaybackStateCompat.ACTION_PLAY_PAUSE |
PlaybackStateCompat.ACTION_STOP |
PlaybackStateCompat.ACTION_FAST_FORWARD |
PlaybackStateCompat.ACTION_REWIND;
What I have tried:
Changing media session to static and back
making the callback a variable rather than a making a new one when created.
Manually setting the mediasession's playback state to playing after play from transport controls
This works find on the phone app although I am using a pending intent to send a start command to run the resume function rather than transport controls. I am also able to resume playback from the watch's transport controls if I am using the phone to play audio and the controls update correctly even though the phone app is using the exact same class.
Please let me know if any other information could be helpful.
Thanks!
-Joel

MediaPlayer.isPlaying() does not return as True

I have a problem.
I am using the mediaPlayer.isPlaying () command, but never that returns true.
When the audio is playing it still allows another audio to play along with the first one.
I have already used the following commands:
1 -
If (mediaPlayer.isPlaying () == true)
{
MediaPlayer.stop ();
MediaPlayer.release ();
} Else if (mediaPlayer.isPlaying () == false)
{
PlaySom ();
}
2 -
If (! (MediaPlayer.isPlaying ()))
{
PlaySom ();
}
But without result, several audios are played at the same time, I would like you to play only one.
Does anyone know of any solution to the problem or some alternative to the mediaPlayer.isPlaying () command?
Thank you so much!!!
My Code:
private static MediaPlayer mediaPlayer;
// EVENTO DE CLIQUE
lista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mediaPlayer = MediaPlayer.create(MainActivity.this, caminhoAudio[position]);
if (!(mediaPlayer.isPlaying()))
{
tocarSom();
Toast.makeText(getApplicationContext(),"Aguarde o término do áudio para executar o outro.",Toast.LENGTH_LONG).show();
}
}
});
// INICIAR O SOM
public void tocarSom() {
if (mediaPlayer != null)
{
mediaPlayer.start();
}
// LIBERAR MEMÓRIA
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
};
});
}
Answer to this question due to if someone can get help from my answer...
You need to create top level (just below the class declaration) media Player like that
private val player =
MediaPlayer().apply {
setOnPreparedListener { start() }
setOnCompletionListener { reset() }
}
After this create player sound method to play audio from storage
private fun playBeats(context: Context, id: Uri) {
player.run {
reset()
setDataSource(context,id)
prepareAsync()
}
}
If you love my answer please find my YouTube channel and subscribe to help me..
YouTube channel name : codebage

Unexpected behavior: immediate completion of media player

I am trying to restore audio to the position it was and the file it was when the user left the fragment. To do this I save the location of the audio file, and the seek position using personal prefs, along with a boolean for whether or not the audio was playing when the user left. I save this info first thing in onPause().
When I resume, I initialize the views etc. and the very last thing I do in onResume is read from personal prefs and play the audio stored there is appropriate.
However when I try to play from onResume, the media completion listener gets called immediately and the file gets skipped.
I have been running tests and I know that the media player is handed the right data, is prepared correctly and set to play.
The way I am trying to play the audio is the same way I do it if a user clicks manually to play audio, and that works flawlessly.
Only when trying to 'restore' the audio to where it was when a user left does the completion listener get called immediately.
Has anyone seen this before?
public void setAudioURLAndPLay(Context context, String url)
{
Log.d(TAG, "setAudioURLAndPLay");
CacheQueue.getInstance().addImmediateTaskToQueue(CacheQueue.AUDIO_TASK, context, url, 0, handler);
}
private void playCahcedFile(String location)
{
Log.d(TAG, "playCahcedFile");
try
{
this.reset();
this.setAudioStreamType(AudioManager.STREAM_MUSIC);
this.setDataSource(location);
this.setOnPreparedListener(new OnPreparedListener()
{
#Override
public void onPrepared(MediaPlayer mp)
{
setPlay();
}
});
this.prepareAsync();
}
catch (Exception e)
{
Log.d(TAG, "Exception", e);
}
}
public void setPlay()
{
Log.d(TAG, "setPlay");
this.start();
this.setProgressHandler(this.listener);
}
and where the calls are being made
public void initializeFromResume()
{
PersonalPrefs prefs = new PersonalPrefs(getActivity());
if (!prefs.isPLaying())
{
return;
}
else
{
playNewAudio(prefs.getURL());
// ((ActivityMain) getActivity()).getMediaManager().setSeek(prefs.getSeek());
}
}
private void playNewAudio(String url)
{
getMediaManager().setAudioURLAndPLay(getActivity(), url)
mediaState = MediaState.playing;
initializeSeekBar();
getMediaManager().setOnCompletionListener(this);
mediaController.togglePlayButton(mediaState);
}
I figured it out and will post the answer to anyone who has similar troubles in the future.
Just need to run a post delayed. Not exactly amazing, but it works.
h.postDelayed(new Runnable()
{
#Override
public void run()
{
PersonalPrefs prefs = new PersonalPrefs(getActivity());
playNewAudio(prefs.getURL());
}
}, 1000);

How can I download mp3 files and play them in my app?

Could someone show me or teach me how I can download 5 or more mp3 in a file and playing them in my app. I've searched about it but all of people how has asked this, nothing explained it well. I don't want to download only one mp3, but multiple mp3s in a file.here is main.java
public class StreamingMp3Player extends Activity implements OnClickListener, OnTouchListener, OnCompletionListener, OnBufferingUpdateListener{
private ImageButton buttonPlayPause;
private SeekBar seekBarProgress;
public EditText editTextSongURL;
private MediaPlayer mediaPlayer;
private int mediaFileLengthInMilliseconds; // this value contains the song duration in milliseconds. Look at getDuration() method in MediaPlayer class
private final Handler handler = new Handler();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initView();
}
/** This method initialise all the views in project*/
private void initView() {
buttonPlayPause = (ImageButton)findViewById(R.id.ButtonTestPlayPause);
buttonPlayPause.setOnClickListener(this);
seekBarProgress = (SeekBar)findViewById(R.id.SeekBarTestPlay);
seekBarProgress.setMax(99); // It means 100% .0-99
seekBarProgress.setOnTouchListener(this);
editTextSongURL = (EditText)findViewById(R.id.EditTextSongURL);
editTextSongURL.setText(R.string.testsong_20_sec);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
}
/** Method which updates the SeekBar primary progress by current song playing position*/
private void primarySeekBarProgressUpdater() {
seekBarProgress.setProgress((int)(((float)mediaPlayer.getCurrentPosition()/mediaFileLengthInMilliseconds)*100)); // This math construction give a percentage of "was playing"/"song length"
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(notification,1000);
}
}
#Override
public void onClick(View v) {
if(v.getId() == R.id.ButtonTestPlayPause){
/** ImageButton onClick event handler. Method which start/pause mediaplayer playing */
try {
mediaPlayer.setDataSource(editTextSongURL.getText().toString()); // setup song from http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3 URL to mediaplayer data source
mediaPlayer.prepare(); // you must call this method after setup the datasource in setDataSource method. After calling prepare() the instance of MediaPlayer starts load data from URL to internal buffer.
} catch (Exception e) {
e.printStackTrace();
}
mediaFileLengthInMilliseconds = mediaPlayer.getDuration(); // gets the song length in milliseconds from URL
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
buttonPlayPause.setImageResource(R.drawable.button_pause);
}else {
mediaPlayer.pause();
buttonPlayPause.setImageResource(R.drawable.button_play);
}
primarySeekBarProgressUpdater();
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if(v.getId() == R.id.SeekBarTestPlay){
/** Seekbar onTouch event handler. Method which seeks MediaPlayer to seekBar primary progress position*/
if(mediaPlayer.isPlaying()){
SeekBar sb = (SeekBar)v;
int playPositionInMillisecconds = (mediaFileLengthInMilliseconds / 100) * sb.getProgress();
mediaPlayer.seekTo(playPositionInMillisecconds);
}
}
return false;
}
#Override
public void onCompletion(MediaPlayer mp) {
/** MediaPlayer onCompletion event handler. Method which calls then song playing is complete*/
buttonPlayPause.setImageResource(R.drawable.button_play);
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
/** Method which updates the SeekBar secondary progress by current song loading from URL position*/
seekBarProgress.setSecondaryProgress(percent);
}
You'll need to use 3rd party libraries to support MP3 playback, as it is not included in the standard library. See Wikipedia for a list of alternatives.
For the downloading part, use an URLConnection to get an InputStream on the file and write it to a FileOutputStream. This might help, too: Working unbuffered Streams

Categories