Android-Summary of simple music player

Source: Internet
Author: User
 

Business: Android program for playing music.

Knowledge point:

1. Three of the four Android components are used (activity, service, broadcast)

The communication between activity and Serivice is implemented by the broadcast component. More than 10 broadcasts are published and received in the program.

2. The thread and application class are also used to save global data.

The purpose of enabling a thread in the service is to continuously broadcast the update progress to the activity when the activity is required. The activity is displayed on the interface after it is received.

Difficulties:

I personally feel that although there are many broadcasts, the logic is generally not very complicated. What is a little hard to understand is the determination of the thread Start and Stop conditions and the final cleaning in the destroy method of the service.

1. You need to wake up the thread under these conditions.

1) in the play () method, when playing music, let it start to work.

2) In the seekto () method, when you drag the seekbar to reposition and play the music, let it start to work.

3) when an activity publishes a broadcast and requests the service to publish an update progress broadcast, it needs to wake up the thread and let it start working.

4) when the service method is to exit destruction, it needs to wake up the thread and let it exit the loop.

Complete project code:

Http://download.csdn.net/detail/tzguo1314/5542427

Some code:

All code of the main activity

Package com.tar ENA. day1901; import com.tar ENA. entity. music; import com.tar ENA. utils. consts; import com.tar ENA. utils. formatutils; import android. app. activity; import android. content. broadcastreceiver; import android. content. context; import android. content. intent; import android. content. intentfilter; import android. OS. bundle; import android. util. log; import android. view. menu; import android. view. menuinflater; import android. view. menuitem; import android. view. view; import android. widget. button; import android. widget. listview; import android. widget. seekbar; import android. widget. seekbar. onseekbarchangelistener; import android. widget. textview; public class mainactivity extends activity {private listview lvmusics; private menuinflater Inflater; private musicadapter adapter; private button btnplayorpause; private musicapplication app; private textview tvmusicname; private textview tvduration; private seekbar sbprogress; @ override public void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. main); Inflater = getmenuinflater (); APP = (musicapplication) getapplication (); // setupview (); addlistener (); // start service intent = new intent (this, musicservice. class); startservice (intent); // create a broadcast receiver createreceiver ();} // activity to start, send a broadcast to the service to inform the broadcast @ override protected void onstart () {super. onstart (); intent = new intent (consts. action_need_update_progress); intent. putextra (consts. extra_need_update_progress, true); sendbroadcast (intent); log. I ("info", "onstart") ;}@ override protected void onresume () {log. I ("info", "onresume"); super. onresume () ;}// activity stops. Send a broadcast to the service to notify the service that the broadcast that can stop sending progress updates @ override protected void onstop () {super. onstop (); intent = new intent (consts. action_need_update_progress); intent. putextra (consts. extra_need_update_progress, false); sendbroadcast (intent) ;}@ override protected void ondestroy () {super. ondestroy (); unregisterreceiver (receiver); // when mainactivity is destroyed, unregister the broadcast receiver.} // set public void setupview () {lvmusics = (listview) findviewbyid (R. id. lvmusics); adapter = new musicadapter (this); lvmusics. setadapter (adapter); btnplayorpause = (button) findviewbyid (R. id. btnplayorpause); tvmusicname = (textview) findviewbyid (R. id. tvmusicname); tvduration = (textview) findviewbyid (R. id. tvduration); sbprogress = (seekbar) findviewbyid (R. id. sbprogress);} // Add menu @ override public Boolean oncreateoptionsmenu (menu) {Inflater. inflate (R. menu. opts, menu); return Super. oncreateoptionsmenu (menu);} // select the system menu option and send broadcast @ override public Boolean onoptionsitemselected (menuitem item) {intent = NULL; Switch (item. getitemid () {case R. id. menu_sub_loop: intent = new intent (consts. action_play_mode); intent. putextra (consts. extra_play_mode, consts. play_mode_loop); sendbroadcast (intent); log. I ("info", "loop"); break; case R. id. menu_sub_random: intent = new intent (consts. action_play_mode); intent. putextra (consts. extra_play_mode, consts. play_mode_radom); sendbroadcast (intent); log. I ("info", "random"); break; case R. id. menu_opts_exit: intent = new intent (consts. action_app_stoped); sendbroadcast (intent); finish (); break;} return Super. onoptionsitemselected (item);} // listen to the user's drag seekbar and record the drag position private void addlistener () {sbprogress. listener (New onseekbarchangelistener () {@ overridepublic void onstoptrackingtouch (seekbar) {// todo auto-generated method stub} @ overridepublic void onstarttrackingtouch (seekbar) {// todo auto-generated method stub} @ overridepublic void onprogresschanged (seekbar, int progress, Boolean fromuser) {If (fromuser) {intent = new intent (consts. action_seek_to); intent. putextra (consts. extra_seek_to, progress); sendbroadcast (intent) ;}}) ;}// perform the corresponding public void doclick (view v) {intent = NULL; switch (v. GETID () {case R. id. btnnext: intent = new intent (consts. action_play_next); btnplayorpause. settext ("pause"); break; case R. id. btnplayorpause: String text = (button) V ). gettext (). tostring (); If ("play ". equals (text) {intent = new intent (consts. action_play); (button) V ). settext ("paused");} else if ("paused ". equals (text) {intent = new intent (consts. action_pause); (button) V ). settext ("play");} break; case R. id. btnprevious: intent = new intent (consts. action_play_previous); btnplayorpause. settext ("pause"); break;} sendbroadcast (intent);} // create a broadcast receiver private void createreceiver () {receiver ER = new innerbroadcastreceiver (); intentfilter filter = new intentfilter (); filter. addaction (consts. action_current_music_change); filter. addaction (consts. action_start_update_progress); filter. addaction (consts. action_send_playing_state); registerreceiver (receiver, filter);} private class innerbroadcastreceiver extends broadcastreceiver {@ overridepublic void onreceive (context, intent) {string action = intent. getaction (); // receives broadcast, music changes, and the front-end displays the new music name and duration if (consts. action_current_music_change.equals (Action) {Music = app. getcurrentmusic (); tvmusicname. settext (music. getname (); tvduration. settext (formatutils. format (music. getduration ();} else if (consts. action_start_update_progress.equals (Action) {// current playback duration int progress = intent. getintextra (consts. extra_current_music_time_position, 0); // total duration int duration = (INT) app. getcurrentmusic (). getduration (); tvduration. settext (formatutils. format (Progress); // display the sbprogress when the song has been played on the interface. setprogress (Progress * 100/duration);} else if (consts. action_send_playing_state.equals (Action) {int state = intent. getintextra (consts. extra_play_state, consts. state_others); music M = app. getcurrentmusic (); int progress = intent. getintextra (consts. extra_current_music_time_position, 0); int duration = (INT) app. getcurrentmusic (). getduration (); tvduration. settext (formatutils. format (Progress); // display the sbprogress when the song has been played on the interface. setprogress (Progress * 100/duration); tvmusicname. settext (M. getname (); If (State = consts. state_pause) {btnplayorpause. settext ("play");} else if (State = consts. state_isplaying) {btnplayorpause. settext ("paused ");}}}}}

Complete musicservice code

Package com.tar ENA. day1901; import Java. io. ioexception; import Java. util. random; import com.tar ENA. entity. music; import com.tar ENA. utils. consts; import android. app. service; import android. content. broadcastreceiver; import android. content. context; import android. content. intent; import android. content. intentfilter; import android. media. mediaplayer; import android. media. mediaplayer. oncompletionlistener; import Droid. OS. ibinder; import android. util. log; public class musicservice extends Service {private mediaplayer player; private musicapplication app; private Boolean ispause; private Boolean needupdate; // you need to publish the update progress Private Boolean isloop; // control the loop statement private int playmode; private random; private innerbroadcastreceiver worker er; private thread workthread; @ overridepublic void oncreate () {super. oncreate (); APP = (MUS Icapplication) getapplication (); player = new mediaplayer (); playmode = consts. play_mode_loop; isloop = true; needupdate = true; random = new random (); // sets the listener addlistener () for the next automatic playback; // adds the receiver createreceiver (); workthread = new thread () {public void run () {While (isloop & needupdate & player. isplaying () {intent = new intent (consts. action_start_update_progress); // package the position where the current music is played. putextra (consts. E Xtra_current_music_time_position, player. getcurrentposition (); sendbroadcast (intent); try {sleep (1000);} catch (interruptedexception e) {e. printstacktrace () ;}/// this worker thread needs to loop continuously unless the loop flag is modified. Wait when you do not need to send the broadcast. Sleep synchronized (this) {try {This. wait ();} catch (interruptedexception e) {e. printstacktrace () ;}}};}; workthread. start () ;}// when the service is destroyed, remove the registered broadcast receiver @ overridepublic void ondestroy () {unregisterreceiver (receiver); // wake up the thread, let the thread exit the loop isloop = false; synchronized (workthread) {workthread. Y ();} // if the music is still playing, stop it. If (player. isplaying () player. stop (); // release the resource player. release (); super. ondestroy ();} // if it is I The spause status value is true for direct playback. else resets the player. Remember to wake up the public void play () {If (ispause) {player. start ();} else {Music = app. getcurrentmusic (); string Path = music. getmusicpath (); If (path! = NULL) {try {player. reset (); player. setdatasource (PATH); player. prepare (); player. start (); // the change of the Song represented by the current index. Broadcast intent = new intent (consts. action_current_music_change); sendbroadcast (intent);} catch (illegalargumentexception e) {e. printstacktrace ();} catch (illegalstateexception e) {e. printstacktrace ();} catch (ioexception e) {e. printstacktrace () ;}} ispause = false; // start playing the music. Set the pause status flag to falsesynchronized (workthread) {workthread. Y () ;}/// if playing, pause the public void pause () {If (player. isplaying () {player. pause (); ispause = true ;}// a public void next () {int Index = app. getcurrentposition (); Switch (playmode) {Case consts. play_mode_loop: If (++ index> = app. getplaylistsize () {Index = 0;} break; Case consts. play_mode_radom: do {Index = random. nextint (App. getplaylistsize ();} while (Index = app. getcurrentposition (); break;} app. setcurrentposition (INDEX); ispause = false; play () ;}// the first public void previous () {int Index = app. getcurrentposition (); Switch (playmode) {Case consts. play_mode_loop: If (-- index <= 0) {Index = app. getplaylistsize ()-1;} break; Case consts. play_mode_radom: do {Index = random. nextint (App. getplaylistsize ();} while (Index = app. getcurrentposition (); break;} app. setcurrentposition (INDEX); ispause = false; play () ;}// locate the specified time to start playing public void seekto (INT positon) {player. seekto (positon); player. start (); synchronized (workthread) {workthread. Y () ;}@ overridepublic ibinder onbind (intent) {return NULL;} // sets the next public void addlistener () {player. setoncompletionlistener (New oncompletionlistener () {@ overridepublic void oncompletion (mediaplayer MP) {next () ;}});} // Add the receiver private void createreceiver () {runner ER = new innerbroadcastreceiver (); intentfilter filter = new intentfilter (); filter. addaction (consts. action_pause); filter. addaction (consts. action_play); filter. addaction (consts. action_play_next); filter. addaction (consts. action_play_previous); filter. addaction (consts. action_play_mode); filter. addaction (consts. action_app_stoped); filter. addaction (consts. action_need_update_progress); filter. addaction (consts. action_seek_to); registerreceiver (receiver, filter);} // receiver class private class innerbroadcastreceiver extends broadcastreceiver {@ overridepublic void onreceive (context, intent) {string action = intent. getaction (); If (consts. action_play.equals (Action) {play ();} else if (consts. action_pause.equals (Action) {pause ();} else if (consts. action_play_next.equals (Action) {next ();} else if (consts. action_play_previus.equals (Action) {previous ();} else if (consts. action_play_mode.equals (Action) {playmode = intent. getintextra (consts. extra_play_mode, consts. play_mode_loop);} // gets and determines whether the current broadcast else if (consts. action_need_update_progress.equals (Action) {needupdate = intent. getbooleanextra (consts. extra_need_update_progress, true); If (needupdate) {synchronized (workthread) {workthread. Y ();} // when updating the progress, the intent intent2 = new intent (consts. action_send_playing_state); int state = consts. state_others; int position = 0; If (player. isplaying () {state = consts. state_isplaying;} else if (ispause) {state = consts. state_pause;} position = player. getcurrentposition (); intent2.putextra (consts. extra_current_music_time_position, position); intent2.putextra (consts. extra_play_state, State); sendbroadcast (intent2);} // calculate the time value that should start playing Based on the drag position} else if (consts. action_seek_to.equals (Action) {int progress = intent. getintextra (consts. extra_seek_to, player. getcurrentposition (); int duration = (INT) app. getcurrentmusic (). getduration (); seekto (Progress * duration/100);} else if (consts. action_app_stoped.equals (Action) {stopself ();}}}}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.