Android development-basic interface design knowledge IV. android Interface Design
The previous chapter describes the basic knowledge points of widgets, services, and BroadcastReceiver in Android interface development. This chapter uses a real case-background music player to analyze the relationship between various knowledge points.
1. Functional Requirements
Make an Android music player
- Use Service, Broadcast Receiver, and Widget
- Use background services to play music
- Create a Widget for playing music
- Show song name
- Display previous, next, play, pause
2. Software Implementation
Figure 1
Figure 2
Figure 3
Simple Description
The cell phone page displays the information shown in 2. The widget option is displayed. Click to enter widget 1. Select geek class-job 4 and drag and drop the interface as prompted to the desktop. The music playing Interface 3 is displayed. You can click the button to switch the music playing function.
3. Implementation Process
The background music player uses the features of widgets and broadcasts as a channel to complete interaction between widgets and services.
Widget: Update desktop information, send broadcast information, and receive user operation events.
Service: registers a Service, receives broadcast information, and sends broadcast information.
4. Interface Layout
The music player UI layout and configuration files mainly include the following:
- Appwidget-provider provides the desktop widget initialization display status, default icons, size, and other functions. It is placed in the res/xml folder. For details, refer to the music_app_widget_info.xml file in the project.
- Android: initialLayout = "@ layout/music_app_widget": Specifies the layout to be displayed during initialization. For details, refer to the music_app_widget.xml file in the project.
- The project applies services and broadcasts. The corresponding tags must be configured in AndroidManifest. xml. For more information, see the AndroidManifest. xml file in the project.
5. Core code analysis (1) Widget function-onUpdate ()
When a user adds a Widget, The OnUpdate () function is called to bind the RemoteView and update the Widget in OnUpdate. When binding controls, the PendingIntent method is mainly applied.
PendingIntent is the encapsulation of Intent. Before constructing PendingIntent, you must first construct an Intent and use the Intent attributes to transfer it to action and Extra. Similarly, when receiving, the recipient still receives Intent instead of PaddingIntent.
PendingIntent. getBroadcast (context, 0, intent, 0); obtains a PendingIntent object from the system that can send BroadcastReceiver broadcasts. The PendingIntent class is used to handle upcoming events. For example, in Notification, it is used to jump to a page, but not to jump to the page immediately. Therefore, it can be understood as an intent encapsulated as a message. That is, the intent is not started immediately, but sent out like a message. After receiving the message, the receiver analyzes the content. The project-related code excerpt is as follows:
1 private PendingIntent getPendingIntent (Context context, int buttonId) {2 Intent intent = new Intent (); 3 intent. setClass (context, ExampleAppWidgetProvider. class); 4 intent. addCategory (Intent. CATEGORY_ALTERNATIVE); 5 intent. setData (Uri. parse ("harvic:" + buttonId); 6 PendingIntent pi = PendingIntent. getBroadcast (context, 0, intent, 0); 7 return pi; 8} 9 10 // update all widget11 private void pushUpda Te (Context context, AppWidgetManager appWidgetManager, String songName, Boolean play_pause) {12 13 RemoteViews remoteView = new RemoteViews (context. getPackageName (), R. layout. music_app_widget); 14 // bind the button to the Click Event 15 remoteView. setOnClickPendingIntent (R. id. play_pause, getPendingIntent (context, R. id. play_pause); 16 remoteView. setOnClickPendingIntent (R. id. prev_song, getPendingIntent (context, R. id. prev_song); 1 7 remoteView. setOnClickPendingIntent (R. id. next_song, getPendingIntent (context, R. id. next_song); 18 19 // set content 20 if (! SongName. equals ("") {21 remoteView. setTextViewText (R. id. song_name, songName); 22} 23 // set the button image 24 if (play_pause) {25 remoteView. setImageViewResource (R. id. play_pause, R. drawable. button_stop); 26} else {27 remoteView. setImageViewResource (R. id. play_pause, R. drawable. button_on); 28} 29 // equivalent to obtaining all the appwidget30 ComponentName componentName = new ComponentName (context, ExampleAppWidgetProvider. class); 31 appWidgetManager. updateAppWidget (componentName, remoteView); 32} 33 34 @ Override35 public void onUpdate (Context context, AppWidgetManager appWidgetManager, 36 int [] appWidgetIds) {37 38 pushUpdate (context, appWidgetManager, "", false); 39}Widget-onUpdate () (2) Widget function-onReceive ()
To receive user operations, first send different broadcasts (send button IDs) to MusicManageService Based on the button clicked by the current user, so that MusicManageService can make different responses, the receiving code is as follows:
1 // receives the broadcast callback function 2 @ Override 3 public void onReceive (Context context, Intent intent) {4 String action = intent. getAction (); 5 Log. d ("harvic", "action:" + action); 6 if (intent. hasCategory (Intent. CATEGORY_ALTERNATIVE) {7 Uri data = intent. getData (); 8 int buttonId = Integer. parseInt (data. getSchemeSpecificPart (); 9 switch (buttonId) {10 case R. id. play_pause: 11 pushAction (context, MusicManageService. ACTION_PLAY_PAUSE); 12 if (mStop) {13 Intent startIntent = new Intent (context, MusicManageService. class); 14 context. startService (startIntent); 15 mStop = false; 16} 17 break; 18 case R. id. prev_song: 19 pushAction (context, MusicManageService. ACTION_PRE); 20 break; 21 case R. id. next_song: 22 pushAction (context, MusicManageService. ACTION_NEXT); 23 break; 24} 25} else if (MAIN_UPDATE_UI.equals (action) {26 int play_pause = intent. getIntExtra (KEY_MAIN_ACTIVITY_UI_BTN,-1); 27 String songid = intent. getStringExtra (KEY_MAIN_ACTIVITY_UI_TEXT); 28 if (songid = null) songid = ""; 29 switch (play_pause) {30 case VAL_UPDATE_UI_PLAY: 31 pushUpdate (context, AppWidgetManager. getInstance (context), songid, true); 32 break; 33 case VAL_UPDATE_UI_PAUSE: 34 pushUpdate (context, AppWidgetManager. getInstance (context), songid, false); 35 break; 36 default: 37 break; 38} 39 40} 41 42 super. onReceive (context, intent); 43}Widget-onReceive () (3) Send broadcast by Widget
// Send key broadcast private void pushAction (Context context, int ACTION) {// send destination service Intent actionIntent = new Intent (MusicManageService. ACTION); // send the actionIntent parameter. putExtra (MusicManageService. KEY_USR_ACTION, ACTION); context. sendBroadcast (actionIntent );}(4) Service Registration Broadcast
Server services must interact with buttons. in Service, they are generally implemented through BroadcastReceiver. Therefore, in the OnCreate function of MusicManageService (OnCreate is called when the Service is started), the following steps should be taken: register a consumer. The corresponding project code is as follows:
1 private BroadcastReceiver extends ER = new BroadcastReceiver () {2 @ Override 3 public void onReceive (Context context, Intent intent) {4 String action = intent. getAction (); 5 if (ACTION. equals (action) {6 int widget_action = intent. getIntExtra (KEY_USR_ACTION,-1); 7 switch (widget_action) {8 case ACTION_PRE: 9 playPrev (context); Log. d ("harvic", "action_prev"); break; 10 case ACTION_PLAY_PAUSE: 11 if (mPlayState) {12 pause (context); Log. d ("harvic", "action_pause"); 13} else {14 play (context); Log. d ("harvic", "action_play"); 15} 16 break; 17 case ACTION_NEXT: playNext (context); Log. d ("harvic", "action_next"); break; 18 default: break; 19} 20} 21}; 22 @ Override23 public void onCreate () {24 // TODO Auto-generated method stub25 super. onCreate (); 26 IntentFilter intentFilter = new IntentFilter (); 27 intentFilter. addAction (ACTION); 28 // Registration Service 29 registerReceiver (explorer, intentFilter); 30 // load song 31 initList (); 32 // play default song 33 mediaPlayerStart (); 34}(5) Song Definition
The song is a local song file, which is placed in the raw directory of the project:
1 // play the song 2 private void mediaPlayerStart () {3 mPlayer = new MediaPlayer (); 4 mPlayer = MediaPlayer. create (getApplicationContext (), mArrayList [mIndex]); 5 mPlayer. start (); 6 mPlayState = true; 7 // send the current playback status to the Widget 8 postState (getApplicationContext (), ExampleAppWidgetProvider through broadcast. VAL_UPDATE_UI_PLAY, mIndex); 9} 10 // song initialization 11 private void initList () {12 // song path 13 mArrayList [0] = R. raw. night_two; 14 mArrayList [1] = R. raw. night_four; 15 mArrayList [2] = R. raw. night_five; 16 mArrayList [3] = R. raw. night_six; 17 // song name 18 mArrayListName [0] = "shi jin-night piano 2"; 19 mArrayListName [1] = "shi jin-night piano 4 "; 20 mArrayListName [2] = "shi jin-Piano Music 5"; 21 mArrayListName [3] = "shi jin-piano music 6"; 22}(6) Service send Broadcast
The song sends a broadcast message to the Service through the different buttons of the Widget. After the Service switches to the Service through the playback function (refer to the project source code), it sends a broadcast message to the Widget again, after receiving the broadcast information, the Widget updates the information. The project code is as follows:
1 // return the broadcast information to Widget 2 private void postState (Context context, int state, int songid) {3 // define send broadcast receiver 4 Intent actionIntent = new Intent (ExampleAppWidgetProvider. MAIN_UPDATE_UI); 5 // define the playing status of the Song (play/pause) 6 actionIntent. putExtra (ExampleAppWidgetProvider. KEY_MAIN_ACTIVITY_UI_BTN, state); 7 // defines the sending information (song name) 8 actionIntent. putExtra (ExampleAppWidgetProvider. KEY_MAIN_ACTIVITY_UI_TEXT, mArrayListName [songid]); 9 context. sendBroadcast (actionIntent); 10}6. Download the project source code
The source code of this project is on the 360 cloud disk and the development environment is Android Studio 2.0 beta 7.
Https://yunpan.cn/cYamkZG3sq9jf access password f3d5