Android enables online music playing
Hello, friends, the first blog published by Shanshan in August. Recently, Wu was looking for a job, and when she got sick, she didn't have much energy to write a blog. Today, I am dragging my head to publish an article about the online music effect that has been achieved previously. It is not difficult to play music online, that is, the input Url is a network address. Here I want to implement online music playing that can be buffered by the network.
Effect implementation:
This blog is in the multi-thread download that blog to increase online playing music implementation, the following is a project: http://download.csdn.net/detail/wwj_748/7018493
The following describes the specific implementation process:
Define a Player with buffering effect: the buffer effect we see in Player is achieved by setting the secondary progress of the drag bar, which requires setting the buffer update listener of MediaPlayer. Code implementation:
Package com. wwj. download. util; import java. io. IOException; import java. util. timer; import java. util. timerTask; import android. media. audioManager; import android. media. mediaPlayer; import android. media. mediaPlayer. onBufferingUpdateListener; import android. media. mediaPlayer. onCompletionListener; import android. media. mediaPlayer. onPreparedListener; import android. OS. handler; import android. util. log; import andro Id. widget. seekBar; public class Player implements OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener {public MediaPlayer mediaPlayer; // Media Player private SeekBar seekBar; // drag a private Timer mTimer = new Timer (); // timer // initialize the Player public Player (SeekBar seekBar) {super (); this. seekBar = seekBar; try {mediaPlayer = new MediaPlayer (); mediaPlayer. setAudioStreamType (AudioManager. STREAM_MUSIC );// Sets mediaPlayer. setOnBufferingUpdateListener (this); mediaPlayer. setOnPreparedListener (this);} catch (Exception e) {e. printStackTrace ();} // mTimer is triggered every second. schedule (timerTask, 0, 1000);} // timer TimerTask timerTask = new TimerTask () {@ Overridepublic void run () {if (mediaPlayer = null) return; if (mediaPlayer. isPlaying () & seekBar. isPressed () = false) {handler. sendEmptyMessage (0); // send message }}; Handler h Andler = new Handler () {public void handleMessage (android. OS. message msg) {int position = mediaPlayer. getCurrentPosition (); int duration = mediaPlayer. getDuration (); if (duration> 0) {// calculate the progress (obtain the maximum scale of the progress bar * Current music playback position/current music duration) long pos = seekBar. getMax () * position/duration; seekBar. setProgress (int) pos) ;}};}; public void play () {mediaPlayer. start ();}/***** @ param url * url address */public void playUrl (Strin G url) {try {mediaPlayer. reset (); mediaPlayer. setDataSource (url); // set the data source mediaPlayer. prepare (); // prepare automatic playback} catch (IllegalArgumentException e) {e. printStackTrace ();} catch (SecurityException e) {e. printStackTrace ();} catch (IllegalStateException e) {e. printStackTrace ();} catch (IOException e) {e. printStackTrace () ;}/// pause public void pause () {mediaPlayer. pause ();} // stop public void stop () {if (med IaPlayer! = Null) {mediaPlayer. stop (); mediaPlayer. release (); mediaPlayer = null ;}// prepare for playing @ Overridepublic void onPrepared (MediaPlayer mp) {mp. start (); Log. e ("mediaPlayer", "onPrepared");} // playback completed @ Overridepublic void onCompletion (MediaPlayer mp) {Log. e ("mediaPlayer", "onCompletion");}/*** buffer update */@ Overridepublic void onBufferingUpdate (MediaPlayer mp, int percent) {seekBar. setSecondaryProgress (percent); int currentProgress = seekBar. getMax () * mediaPlayer. getCurrentPosition ()/mediaPlayer. getDuration (); Log. e (currentProgress + "% play", percent + "buffer ");}}
Package com. wwj. download; import java. io. file; import java. io. unsupportedEncodingException; import java.net. URLEncoder; import android. app. activity; import android. OS. bundle; import android. OS. environment; import android. OS. handler; import android. OS. message; import android. view. view; import android. widget. button; import android. widget. editText; import android. widget. progressBar; import android. widget. seekBar; I Mport android. widget. seekBar. onSeekBarChangeListener; import android. widget. textView; import android. widget. toast; import com. wwj. download. util. player; import com.wwj.net. download. downloadProgressListener; import com.wwj.net. download. fileDownloader; public class MainActivity extends Activity {private static final int PROCESSING = 1; private static final int FAILURE =-1; private EditText pathText; // url location Private TextView resultView; private Button downloadButton; private Button stopButton; private ProgressBar progressBar; private Button playBtn; private Player player; // Player private SeekBar musicProgress; // music progress private Handler handler = new UIHandler (); private final class UIHandler extends Handler {public void handleMessage (Message msg) {switch (msg. what) {case PROCESSING: // Update Progress ssssbar. setProgre Ss (msg. getData (). getInt ("size"); float num = (float) progressBar. getProgress ()/(float) progressBar. getMax (); int result = (int) (num * 100); // calculate the progress of resultView. setText (result + "%"); if (progressBar. getProgress () = progressBar. getMax () {// download completed Toast. makeText (getApplicationContext (), R. string. success, Toast. LENGTH_LONG ). show ();} break; case FAILURE: // download failed Toast. makeText (getApplicationContext (), R. st Ring. error, Toast. LENGTH_LONG ). show (); break ;}}@ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. main); pathText = (EditText) findViewById (R. id. path); resultView = (TextView) findViewById (R. id. resultView); downloadButton = (Button) findViewById (R. id. downloadbutton); stopButton = (Button) findViewById (R. id. stopbutton); progressBar = (P RogressBar) findViewById (R. id. progressBar); ButtonClickListener listener = new ButtonClickListener (); downloadButton. setOnClickListener (listener); stopButton. setOnClickListener (listener); playBtn = (Button) findViewById (R. id. btn_online_play); playBtn. setOnClickListener (listener); musicProgress = (SeekBar) findViewById (R. id. music_progress); player = new Player (musicProgress); musicProgress. setOnSeekBarChan GeListener (new SeekBarChangeEvent ();} private final class ButtonClickListener implements View. onClickListener {@ Overridepublic void onClick (View v) {switch (v. getId () {case R. id. downloadbutton: // start to download. // http://abv.cn/music/guang hui .mp3 can be replaced with the chain string path = pathText. getText (). toString (); String filename = path. substring (path. lastIndexOf ('/') + 1); try {// URL encoding (URL encoding for Chinese) filename = URLEncod Er. encode (filename, "UTF-8");} catch (UnsupportedEncodingException e) {e. printStackTrace ();} path = path. substring (0, path. lastIndexOf ("/") + 1) + filename; if (Environment. getExternalStorageState (). equals (Environment. MEDIA_MOUNTED) {// File savDir = // Environment. getExternalStoragePublicDirectory (Environment. DIRECTORY_MOVIES); // save path File savDir = Environment. getExternalStorageDirectory (); download (Path, savDir);} else {Toast. makeText (getApplicationContext (), R. string. sdcarderror, Toast. LENGTH_LONG ). show ();} downloadButton. setEnabled (false); stopButton. setEnabled (true); break; case R. id. stopbutton: // pause download exit (); Toast. makeText (getApplicationContext (), "Now thread is Stopping !! ", Toast. LENGTH_LONG ). show (); downloadButton. setEnabled (true); stopButton. setEnabled (false); break; case R. id. btn_online_play: new Thread (new Runnable () {@ Overridepublic void run () {player. playUrl (pathText. getText (). toString ());}}). start (); break;}/** due to user input events (click the button and touch the screen ....) it is handled by the main thread. If the main thread is in the working state, * If the user-generated input event fails to be processed within 5 seconds, the system reports the "application does not respond" error. * Therefore, you cannot execute a time-consuming task in the main thread. Otherwise, the user input event cannot be processed due to the main thread blocking. * This leads to the "Application No response" error. Time-consuming work should be executed in the Child thread. */Private DownloadTask task; private void exit () {if (task! = Null) task. exit ();} private void download (String path, File savDir) {task = new DownloadTask (path, savDir); new Thread (task ). start ();}/***** UI control screen re-painting (update) is handled by the main thread. If the UI control value is updated in the Child thread, the updated value is not repainted to the screen * You must update the UI control value in the main thread so that it can be displayed on the screen, the value of the UI control cannot be updated in the Child thread **/private final class DownloadTask implements Runnable {private String path; private File saveDir; private FileDownloader loader; public DownloadTask (String pa Th, File saveDir) {this. path = path; this. saveDir = saveDir;}/*** exit download */public void exit () {if (loader! = Null) loader. exit ();} DownloadProgressListener downloadProgressListener = new DownloadProgressListener () {@ Overridepublic void onDownloadSize (int size) {Message msg = new Message (); msg. what = PROCESSING; msg. getData (). putInt ("size", size); handler. sendMessage (msg) ;}}; public void run () {try {// instantiate a file loader = new FileDownloader (getApplicationContext (), path, saveDir, 3 ); // set the maximum progress bar. setMa X (loader. getFileSize (); loader. download (downloadProgressListener);} catch (Exception e) {e. printStackTrace (); handler. sendMessage (handler. obtainMessage (FAILURE); // send an empty message object }}}// progress change class SeekBarChangeEvent implements changes {int progress; @ Overridepublic void onProgressChanged (SeekBar seekBar, int progress, boolean fromUser) {// originally (progress/seekBar. getMax () * player. mediaPlayer. GetDuration () this. progress = progress * player. mediaPlayer. getDuration ()/seekBar. getMax () ;}@ Overridepublic void onStartTrackingTouch (SeekBar seekBar) {}@ Overridepublic void onStopTrackingTouch (SeekBar seekBar) {// seekTo () is a number relative to the video time, instead of seekBar. the number player relative to getMax. mediaPlayer. seekTo (progress) ;}@overrideprotected void onDestroy () {super. onDestroy (); if (player! = Null) {player. stop (); player = null ;}}}