We want to play online music file, show dialog when
buffering.
Use AsyncTask to do this.
Create new class, file xml like this.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="45dp"
android:layout_gravity="center_horizontal"
android:text="Online music"
android:textSize="15sp"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="45dp"
android:orientation="horizontal"
>
<TextView
android:id="@+id/songDuration1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_weight="1" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_weight="1"
/>
<TextView
android:id="@+id/songDuration"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_weight="1"
/>
</LinearLayout>
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:orientation="horizontal"
>
<ImageButton
android:id="@+id/media_rew"
android:layout_width="52sp"
android:layout_height="35sp"
android:background="@android:color/transparent"
android:contentDescription="@null"
android:onClick="rewind"
android:src="@drawable/ic"
/>
<ImageButton
android:id="@+id/im"
android:layout_width="52sp"
android:layout_height="35sp"
android:layout_marginLeft="14dp"
android:background="@android:color/transparent"
android:contentDescription="@null"
android:src="@drawable/ic2" />
<ImageButton
android:id="@+id/media_ff"
android:layout_width="52sp"
android:layout_height="35sp"
android:layout_marginLeft="14dp"
android:background="@android:color/transparent"
android:contentDescription="@null"
android:onClick="forward"
android:src="@drawable/ic3" />
</LinearLayout>
</LinearLayout>
Copy icon for play, pause, next, previous button in to
drawable folder.
Copy variables to above Override.
private MediaPlayer mediaPlayer;
String
path;
private ImageButton buttonPlayPause;
private SeekBar seekBarProgress;
public TextView duration,duration2;
private double startTime = 0;
double timeElapsed = 0;
private double finalTime = 0;
private int forwardTime = 50000, backwardTime = 50000;
private int mediaFileLengthInMilliseconds;
private
final Handler handler
= new Handler();
Copy to below setContentView.
initView();
path = "https://s3.amazonaws.com/kargopolov/kukushka.mp3";
AsyncTask<Void, Void, Void> updateTask = new AsyncTask<Void, Void,
Void>(){
ProgressDialog dialog
= new ProgressDialog(doc4.this);
@Override
protected void onPreExecute() {
dialog.setMessage("Please wait.");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
@Override
protected Void doInBackground(Void... params) {
// do your background operation here
try {
mediaPlayer.setDataSource(path);
mediaPlayer.prepare();
}
catch (Exception e) {
e.printStackTrace();
}
mediaFileLengthInMilliseconds = mediaPlayer.getDuration();
return null;
}
@Override
protected void onPostExecute(Void result) {
// what to do when background task is completed
if(!mediaPlayer.isPlaying()){
mediaPlayer.start(); buttonPlayPause.setImageResource(R.drawable.ic2); }
else {
mediaPlayer.pause();
buttonPlayPause.setImageResource(R.drawable.ic4);
}
finalTime = mediaPlayer.getDuration();
timeElapsed = mediaPlayer.getCurrentPosition();
primarySeekBarProgressUpdater();
dialog.dismiss();
};
@Override
protected void onCancelled() {
dialog.dismiss();
super.onCancelled();
}
};
updateTask.execute((Void[])null);
Copy to class declare.
implements
OnClickListener, OnTouchListener, OnCompletionListener,
OnBufferingUpdateListener
im
Ignore all red mark errors. Let look at code.
We show a Dialog when loading.
In AsyncTask we load music, get
duration, play when done, set icon for button, quit Dialog when music play.
Copy functions to outside setContentView.
private void initView() {
buttonPlayPause = (ImageButton)findViewById(R.id.im);
buttonPlayPause.setOnClickListener(this);
duration = (TextView) findViewById(R.id.songDuration);
duration2 = (TextView) findViewById(R.id.songDuration1);
seekBarProgress = (SeekBar)findViewById(R.id.seekbar);
seekBarProgress.setMax(99); // It means 100% .0-99
seekBarProgress.setOnTouchListener(this);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
seekBarProgress.setClickable(false);
}
This initial of seekbar and mediaPlayer.
Copy continue to below.
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() {
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@SuppressLint("NewApi")
public void run() {
timeElapsed = mediaPlayer.getCurrentPosition();
double timeRemaining = finalTime - timeElapsed;
duration.setText(String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining), TimeUnit.MILLISECONDS.toSeconds((long) timeRemaining) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining))));
startTime = mediaPlayer.getCurrentPosition();
duration2.setText(String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes((long) startTime),
TimeUnit.MILLISECONDS.toSeconds((long) startTime) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.
toMinutes((long) startTime)))
);
primarySeekBarProgressUpdater();
}
};
//
handler.postDelayed(this,100);
handler.postDelayed(notification,1000);
}
}
This function control seekbar, make it run and show time to
textView.
Copy to continue.
@Override
public void onClick(View v) {
if(v.getId() == R.id.im){
/* ImageButton onClick event handler. Method which
start/pause mediaplayer playing */
try {
mediaPlayer.setDataSource(path); mediaPlayer.prepare();
} 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.ic2);
}else {
mediaPlayer.pause();
buttonPlayPause.setImageResource(R.drawable.ic4);
}
finalTime = mediaPlayer.getDuration();
timeElapsed = mediaPlayer.getCurrentPosition();
primarySeekBarProgressUpdater();
duration.setText(String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes((long) finalTime),
TimeUnit.MILLISECONDS.toSeconds((long) finalTime) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.
toMinutes((long) finalTime)))
);
}
}
This control play and pause button, change icons, get time
set to textView.
Copy to continue.
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event)
{
Toast.makeText(doc4.this,"Please wait…", Toast.LENGTH_SHORT).show();
if(v.getId() == R.id.seekbar){
//** 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;
}
This control seekbar when user slide forward or back.
Copy to continue.
public void forward(View view) {
Toast.makeText(doc4.this, "Please wait…",
Toast.LENGTH_SHORT).show();
//check if we can go forward at
forwardTime seconds before song endes
if ((timeElapsed + forwardTime) <= finalTime) {
timeElapsed = timeElapsed + forwardTime;
//seek to the exact second of
the track
mediaPlayer.seekTo((int) timeElapsed);
}
}
public void rewind(View view) {
Toast.makeText(doc4.this,"Please wait…",
Toast.LENGTH_SHORT).show();
//check if we can go forward at forwardTime
seconds before song endes
if ((timeElapsed - backwardTime) > 0) {
timeElapsed = timeElapsed - backwardTime;
//seek to the exact second of
the track
mediaPlayer.seekTo((int) timeElapsed);
}
}
This control forward and back button, we set time next to 50
seconds..
Copy to continue.
@Override
public void onCompletion(MediaPlayer mp) {
/** MediaPlayer onCompletion event handler. Method
which calls then song playing is complete*/
buttonPlayPause.setImageResource(R.drawable.ic4);
}
@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);
}
This control when music finish, we set icon play to button,
update seekbar.
Copy to above last close bracket.
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
//Log.d(DEBUG_TAG, "In
onDestroy.");
if(mediaPlayer != null) {
mediaPlayer.stop();
finish();
}
}
This make music stop when user press Back button on phone.
Import libraries, if still has errors, add this line.
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
Run to see result.
No comments:
Post a Comment