Android Development - use broadcast to design simple music box

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

  1. 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.

  2. 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:

  3. 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

  1. In mainactivity In Java, the variables and subclasses that need to be used are defined at the outermost layer.
  2. 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);
    }
  1. 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;
            }
        }
    }
  1. 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

  1. In musicservice In Java, the variables and subclasses that need to be used are defined at the outermost layer.
  2. 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]);
            }
        });
    }
  1. 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);
        }
    }
  1. 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

Keywords: Java Android Android Studio

Added by ccalzaretta on Thu, 17 Feb 2022 22:13:33 +0200