There is always a saying in the Android industry that you want to learn about Service, so you have to write a music player.
Why Service?
Services are running behind the scenes, and they are not easy to see, but coincidentally, music is just invisible to others. I believe this is why they are together.
As we all know, there are two ways to interact with a Service in an Activity:
1) startService. You can directly call the startService method in the Activity to create a Service object that is invisible in the background (but still in the same process, it is able to quietly execute similar download tasks in the back, but also to sing "The vast world is your love... ", but in this way, we can only say to it," Service, do this thing ", but we can't say to it when it is half done," Service, don't do this. Do that. "(actually, you can, but every time you create a new Intent, define what we want to do, and then call startService again, let it do it again, but I think it is not scientific ).
2) bindService. We can also bindService to bind the Activity with the Service. Why can we call the Service at any time after binding the Service? Through binding, a class inherited from the Binder is returned from the Service to the Activity. Through this inherited class, some interactive callback functions can be defined in it, then the Activity can use these methods to tell the Service what to do at any time. This is called interaction.
Therefore, the bindService method must be used for the music player, because we need to interact with each other. First look at the interface:
There are different control buttons on the list interface and the lyrics interface, such as forward and backward, mode change, and playback pause. So we have to think about how to design the Service.
How to design a Service? I divide the Service into three situations: 1) responding to the control of the buttons in the Activity; 2) the logic of the Service itself, such as automatically playing the next song after a song is played; 3) actively notify the Activity.
The first case is actually the interface we need to define in the Binder, the Response List interface's singing stop before and after and the Pattern Transformation.
Class NatureBinder extends Binder {/***. Someone wants to hear */public void startPlay (int currentMusic, int currentPosition) {}/*** stop singing */public void stopPlay () {}/*** next to */public void toNext () {}/*** previous */public void toPrevious () {}/*** someone changed the mode. I have to write it down */public void changeMode () {}/*** tell someone whether you are playing in sequence or randomly * MODE_ONE_LOOP = 1; * MODE_ALL_LOOP = 2; * MODE_RANDOM = 3; * MODE_SEQUENCE = 4; * @ return */public I Nt getCurrentMode () {}/*** tells the caller whether the caller is doing anything... * @ Return */public boolean isPlaying () {}/ *** tell the caller which song is playing and how long is it? */public void policyactivity () {}/*** someone dragged the Seekbar and told the service to change the playback position * @ param progress */public void changeProgress (int progress ){}}
The second case is the logic control of servcie itself. In fact, the main logic is that when a song is played, it has to determine what to play next and whether it has to play, therefore, we need to implement the OnCompletionListener method of MediaPlayer. Here, we want to implement the next step, continue playing, or stop, and do we want to notify the list interface? I 've changed my songs...
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mp) {...});}
The third case is how to go to the notification list interface. Here, the broadcast is sent, and the Activity registers the corresponding broadcast filter to receive messages sent from the Service, such as the progress of playing a song and changing the song. The following code tells the front-end where I am playing. You can update the progress bar for me.
private void toUpdateProgress(){if(mediaPlayer != null && isPlaying){int progress = mediaPlayer.getCurrentPosition();Intent intent = new Intent();intent.setAction(ACTION_UPDATE_PROGRESS);intent.putExtra(ACTION_UPDATE_PROGRESS,progress);sendBroadcast(intent);handler.sendEmptyMessageDelayed(updateProgress, 1000);}}
Correspondingly, we will receive such broadcasts in the Activity to make corresponding updates. Of course, do not forget to register the corresponding actions, otherwise we will not receive them. The Code is as follows:
Private void registerReceiver () {progressReceiver = new ProgressReceiver (); IntentFilter intentFilter = new IntentFilter (); intentFilter. addAction (NatureService. ACTION_UPDATE_PROGRESS );... registerReceiver (progressReceiver, intentFilter);} // The above is the registration broadcast, the following is the receipt of the broadcast, and finally do not forget to cancel the broadcast... class ProgressReceiver extends BroadcastReceiver {@ Overridepublic void onReceive (Context context, Intent intent) {String action = intent. getAction (); if (NatureService. ACTION_UPDATE_PROGRESS.equals (action) {int progress = intent. getIntExtra (NatureService. ACTION_UPDATE_PROGRESS, 0); if (progress> 0) {currentPosition = progress; // Remember the current positionpbDuration. setProgress (progress/1000 );}...}}
Now that you have thought about what the Service should do, it is clear that the next step is to call the Service. How to use the Service? Nonsense! Of course it is called in Activity. That's right. In the Activity, we get a Binder through BindService, and then we can communicate with the Service through the Binder.
private NatureBinder natureBinder;private ServiceConnection serviceConnection = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {natureBinder = (NatureBinder) service;}};private void connectToNatureService(){Intent intent = new Intent(MainActivity.this, NatureService.class);bindService(intent, serviceConnection, BIND_AUTO_CREATE);}
Of course, there are several steps to go: 1) create a ServiceConnection object and return our Binder in its onServiceConnected method. 2) Call bindService and pass serviceConnection as a parameter. It's that simple. Next we can use the binder to do things. For example, play:
natureBinder.startPlay(currentMusic,currentPosition);
Pause:
natureBinder.stopPlay();
Next:
natureBinder.toNext();
Yes, that's it. Almost forgot, please click the source code to download: