1, Function description
When using the mobile music player, you will see the buttons of "previous", "pause / play", "restart" and "next".
It can be seen that the song name and singer name are displayed at the top of the screen, and four buttons are placed at the bottom to operate "previous", "pause / play", "restart" and "next" respectively. This article is about how to realize the functions of these buttons and play the prepared music resource files.
2, Program analysis
In this case, the service is embedded in the broadcast, and a simple music box is designed. It is roughly divided into two parts: UI design and function design.
(1) UI design
-
First, put all the picture resources into the [res] - [drawable] folder. Because the play / pause button needs to make different effects between clicking and not clicking, there are five pictures in total.
-
By the way, put the music resources into the [res] - [raw] folder. Since the raw folder didn't exist at first, you need to create it yourself:
-
Create main in the layout folder XML file and set its style.
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="180dp"> <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="32dp" android:layout_weight="1" android:gravity="center" android:ellipsize="marquee" android:marqueeRepeatLimit="marquee_forever" android:textColor="#9C27B0" android:textSize="25sp" android:text="Song name"/> <TextView android:id="@+id/author" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="Singer name" android:textSize="25sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="90dp" android:orientation="horizontal"> <ImageButton android:id="@+id/pre" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/pre" /> <ImageButton android:id="@+id/play" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/play"/> <ImageButton android:id="@+id/stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/stop"/> <ImageButton android:id="@+id/next" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/next" /> </LinearLayout> </LinearLayout>
(2) Functional design
MainActivity.java
- In mainactivity In Java, the variables and subclasses that need to be used are defined at the outermost layer.
- onCreate() function is used to get the corresponding button, add listener and register receiver.
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Get the two buttons in the program interface front=(ImageButton)this.findViewById(R.id.front); play = (ImageButton) this.findViewById(R.id.play); stop = (ImageButton) this.findViewById(R.id.stop); next=(ImageButton)this.findViewById(R.id.next); title = (TextView) findViewById(R.id.title); author = (TextView) findViewById(R.id.author); // Add a listener for the click event of the two buttons play.setOnClickListener(this); stop.setOnClickListener(this); front.setOnClickListener(this); next.setOnClickListener(this); activityReceiver = new ActivityReceiver(); // Create IntentFilter IntentFilter filter = new IntentFilter(); // Specifies the Action that BroadcastReceiver listens to filter.addAction(UPDATE_ACTION); // Register BroadcastReceiver registerReceiver(activityReceiver, filter); Intent intent = new Intent(this, MusicService.class); // Start background Service startService(intent); }
- The subclass of the activityservice is responsible for monitoring the broadcast status and displaying the music transmitted from the subsystem of the activityservice.
// The customized BroadcastReceiver is responsible for listening to the broadcast sent back from the Service public class ActivityReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // Get the update message in Intent. Update represents the playback status int update = intent.getIntExtra("update", -1); // Get the current message in Intent. Current represents the song currently playing int current = intent.getIntExtra("current", -1); if (current >= 0) { title.setText(titleStrs[current]); author.setText(authorStrs[current]); } switch (update) { case 0x11: play.setImageResource(R.drawable.play); status = 0x11; break; // The control system enters the playback state case 0x12: // Set the pause icon when playing play.setImageResource(R.drawable.stop); // Set current status status = 0x12; break; // The control system enters a suspended state case 0x13: // Set play icon in pause state play.setImageResource(R.drawable.play); // Set current status status = 0x13; break; } } }
- onClick function, use switch to judge the click event and send a broadcast to the Service.
@Override public void onClick(View source) { // Create Intent Intent intent = new Intent("org.xr.action.CTL_ACTION"); switch (source.getId()) { // Press the play / pause button case R.id.play: intent.putExtra("control", 1); break; // Press the stop button case R.id.stop: intent.putExtra("control", 2); break; case R.id.front: intent.putExtra("control",3); break; //Press next case R.id.next: intent.putExtra("control",4); break; } // The broadcast is sent and will be received by the BroadcastReceiver in the Service component sendBroadcast(intent); }
MusicService.java
- In musicservice In Java, the variables and subclasses that need to be used are defined at the outermost layer.
- The onCreate function adds a listener, registers a receiver, and sends a broadcast to the Activity.
@Override public void onCreate() { super.onCreate(); am=getAssets(); //Create BroadcastReceiver serviceReceiver=new MyReceiver(); //Create intentfilter IntentFilter filter=new IntentFilter(); filter.addAction(MainActivity.CTL_ACTION); registerReceiver(serviceReceiver,filter); //Create MediaPlayer mPlayer=new MediaPlayer(); //Bind listener for MediaPlayer playback completion event mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { current++; if (current>=4) { current=0; } //Send broadcast notification Activity change text box Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION); sendIntent.putExtra("current",current); //The broadcast is sent and will be received by the BroadcastReceiver in the Activity component sendBroadcast(sendIntent); //Ready to play music prepareAndPlay(musics[current]); } }); }
- MyReceiver subclass, which receives the information from MainActivity and sends the broadcast, defines the processing process after receiving the broadcast from MainActivity.
public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { int control =intent.getIntExtra("control",-1); switch (control) { //Play or pause case 1: //It was not playing if (status==0x11) { //Prepare and play music prepareAndPlay(musics[current]); status=0x12; } //It was playing else if (status==0x12) { //suspend mPlayer.pause(); //Change to suspended state status=0x13; } //It was suspended else if (status==0x13) { //play mPlayer.start(); //Change state status=0x12; } break; //Stop sound case 2: // If the original is playing or pausing if (status == 0x12 || status == 0x13) { // stop playing mPlayer.stop(); status = 0x11; } break; //Play previous song case 3: //It was not played or paused if (status==0x11||status==0x13) { if(current==0) { current=3; prepareAndPlay(musics[current]); } //Prepare and play music else { current=current-1; prepareAndPlay(musics[current]); } status=0x12; } //It was playing else if (status==0x12) { //Previous / / prepare and play music if(current==0) { current=3; prepareAndPlay(musics[current]); } else { current=current-1; prepareAndPlay(musics[current]); } } break; //Play the next song case 4: //It was not played or paused if (status==0x11||status==0x13) { if(current==3) { current=0; prepareAndPlay(musics[current]); } //Prepare and play music else { current=current+1; prepareAndPlay(musics[current]); } status=0x12; } //It was playing else if (status==0x12) { //Next if(current==3) { current=0; prepareAndPlay(musics[current]); } else { current=current+1; prepareAndPlay(musics[current]); } } break; } //Broadcast notification Activity change icon, text box Intent sendIntent=new Intent(MainActivity.UPDATE_ACTION); sendIntent.putExtra("update",status); sendIntent.putExtra("current",current); //The broadcast is sent and will be received by the BroadcastReceiver in the Activity component sendBroadcast(sendIntent); } }
- The prepareAndPlay function is used to prepare and play music.
private void prepareAndPlay(String music) { try { //Open the specified music file AssetFileDescriptor afd=am.openFd(music); mPlayer.reset(); //Use MediaPlayer to load the specified music file mPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength()); //Prepare sound mPlayer.prepare(); //play mPlayer.start(); }catch (IOException e) { e.printStackTrace(); } }
3, Operation interface
No matter whether it is currently playing or suspended, when you click the "next" button, you can enter the next song, and the song name and singer name will be switched.
4, Complete source code
Source code gitee address: Use broadcast design simple music box source code