Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android編程入門 >> android開發-界面設計基本知識Ⅳ

android開發-界面設計基本知識Ⅳ

編輯:Android編程入門

上一章講述了Android界面開發中的Widget,Service,BroadcastReceiver基本知識點,本章以一個實際案例-後台音樂播放器解析各個知識點之間的關系。

1.功能需求

做一個Android音樂播放器

  •  用到Service、Broadcast Receiver、Widget
  •  使用後台服務播放音樂
  • 做一個音樂播放的Widget
  •  顯示歌曲名
  • 顯示上一首、下一首、播放、暫停

2.軟件實現

        

                    圖1                              

                      圖2                         

                          圖3

簡易說明

長按手機界面出現如圖2所示信息,彈出小部件選項,點擊進入小部件如圖1。選擇極客班-作業四,根據提示拖放界面到桌面,出現如圖3所示音樂播放界面。點擊按鈕可實現音樂切換播放歌曲功能。

3.實現流程

後台音樂播放器主要是通過Widget的特性,用廣播為通道,完成Widget與Service之間的交互。

Widget:更新桌面信息,發送廣播信息,接收用戶操作事件。

Service:注冊服務,接收廣播信息,發送廣播信息。

4.界面布局

音樂播放器在界面布局和配置文件中主要包括以下方面:

  • appwidget-provider提供了桌面widget的初始化顯示狀態、默認圖標、大小等功能,它放在res/xml文件夾下,參考項目中的music_app_widget_info.xml文件。
  • android:initialLayout="@layout/music_app_widget":這個就是指定初始化顯示時,應該顯示的布局,參考項目中的music_app_widget.xml文件。
  • 項目應用了服務,廣播,須在AndroidManifest.xml中配置相應的標簽。具體信息參考項目中的AndroidManifest.xml文件。

5.核心代碼分析

(1)Widget函數-onUpdate()

在用戶添加Widget時,會調用OnUpdate()函數,在OnUpdate()中要實現綁定RemoteView和更新Widget的操作。在綁定控件時,主要應用了PendingIntent的方式。

PendingIntent 是Intent的封裝,在構造PendingIntent前,也要先構造一個Intent,並可以利用Intent 的屬性傳進去action,Extra等,同樣,在接收時,對方依然是接收Intent的,而不是接收PaddingIntent。
PendingIntent.getBroadcast(context, 0,intent, 0);指從系統中獲取一個用於可以發送BroadcastReceiver廣播的PendingIntent對象。PendingIntent這個類用於 處理即將發生的事情。比如在通知Notification中用於跳轉頁面,但不是馬上跳轉。所以可以將它理解成 一個封裝成消息的intent的。即這個intent並不是立即start,而是像消息一樣被發送出去,等接收方接到以後,再分析裡面的內容。項目相關代 碼摘抄如下:

 private PendingIntent getPendingIntent(Context context, int buttonId) {
         Intent intent = new Intent();
         intent.setClass(context, ExampleAppWidgetProvider.class);
         intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
         intent.setData(Uri.parse("harvic:" + buttonId));
         PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
         return pi;
     }
 
     // 更新所有的 widget
     private void pushUpdate(Context context,AppWidgetManager appWidgetManager,String songName,Boolean play_pause) {
 
         RemoteViews remoteView = new RemoteViews(context.getPackageName(),R.layout.music_app_widget);
         //將按鈕與點擊事件綁定
         remoteView.setOnClickPendingIntent(R.id.play_pause,getPendingIntent(context, R.id.play_pause));
         remoteView.setOnClickPendingIntent(R.id.prev_song, getPendingIntent(context, R.id.prev_song));
         remoteView.setOnClickPendingIntent(R.id.next_song, getPendingIntent(context, R.id.next_song));
 
         //設置內容
         if (!songName.equals("")) {
             remoteView.setTextViewText(R.id.song_name, songName);
         }
         //設定按鈕圖片
         if (play_pause) {
             remoteView.setImageViewResource(R.id.play_pause, R.drawable.button_stop);
         }else {
             remoteView.setImageViewResource(R.id.play_pause, R.drawable.button_on);
         }
         // 相當於獲得所有本程序創建的appwidget
         ComponentName componentName = new ComponentName(context,ExampleAppWidgetProvider.class);
         appWidgetManager.updateAppWidget(componentName, remoteView);
     }
 
     @Override
     public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                          int[] appWidgetIds) {
 
         pushUpdate(context,appWidgetManager,"",false);
     }
Widget-onUpdate()

(2)Widget函數-onReceive()

接收用戶操作,在接收時,首先根據當前用戶點擊的哪個按鈕,然後給MusicManageService發送不同的廣播(發送按鈕id),讓MusicManageService做出不同的響應,接收代碼如下 :

 // 接收廣播的回調函數
     @Override
     public void onReceive(Context context, Intent intent) {
         String action = intent.getAction();
         Log.d("harvic", "action:"+action);
         if (intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) {
             Uri data = intent.getData();
             int buttonId = Integer.parseInt(data.getSchemeSpecificPart());
             switch (buttonId) {
                 case R.id.play_pause:
                     pushAction(context,MusicManageService.ACTION_PLAY_PAUSE);
                     if(mStop){
                         Intent startIntent = new Intent(context,MusicManageService.class);
                         context.startService(startIntent);
                         mStop = false;
                     }
                     break;
                 case R.id.prev_song:
                     pushAction(context, MusicManageService.ACTION_PRE);
                     break;
                 case R.id.next_song:
                     pushAction(context, MusicManageService.ACTION_NEXT);
                     break;
             }
         }else if (MAIN_UPDATE_UI.equals(action)){
             int play_pause =  intent.getIntExtra(KEY_MAIN_ACTIVITY_UI_BTN, -1);
             String songid = intent.getStringExtra(KEY_MAIN_ACTIVITY_UI_TEXT);
             if(songid==null) songid="歌曲";
             switch (play_pause) {
                 case VAL_UPDATE_UI_PLAY:
                     pushUpdate(context, AppWidgetManager.getInstance(context), songid,true);
                     break;
                 case VAL_UPDATE_UI_PAUSE:
                     pushUpdate(context, AppWidgetManager.getInstance(context), songid,false);
                     break;
                 default:
                     break;
             }
 
         }
 
         super.onReceive(context, intent);
     }
Widget-onReceive()

(3)Widget發送廣播

//發送按鍵廣播
    private void pushAction(Context context, int ACTION) {
        //發送目的服務
        Intent actionIntent = new Intent(MusicManageService.ACTION);
        //發送參數
        actionIntent.putExtra(MusicManageService.KEY_USR_ACTION, ACTION);
        context.sendBroadcast(actionIntent);
    }

(4)Service注冊廣播

服 務要與按鈕相交互,在Service中一般是通過BroadcastReceiver來實現,所以在 MusicManageService的OnCreate函數中(Service起來的時候調用OnCreate)應該包括下面幾個步驟:注冊 Receiver。對應的項目代碼如下:

 private BroadcastReceiver receiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             String action  = intent.getAction();
             if (ACTION.equals(action)) {
                 int widget_action = intent.getIntExtra(KEY_USR_ACTION, -1);
                 switch (widget_action){
                     case ACTION_PRE:
                         playPrev(context);Log.d("harvic","action_prev");break;
                     case ACTION_PLAY_PAUSE:
                         if (mPlayState) {
                             pause(context);Log.d("harvic","action_pause");
                         }else{
                             play(context);Log.d("harvic","action_play");
                         }
                         break;
                     case ACTION_NEXT:playNext(context);Log.d("harvic","action_next");break;
                     default:break;
                 }}
         }
     };
     @Override
     public void onCreate() {
         // TODO Auto-generated method stub
         super.onCreate();
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(ACTION);
         //注冊服務
         registerReceiver(receiver, intentFilter);
         //加載歌曲
         initList();
         //播放默認歌曲
         mediaPlayerStart();
     }

(5)歌曲定義

歌曲為本地歌曲文件,放在項目的raw目錄下:

 //歌曲播放
     private void mediaPlayerStart(){
         mPlayer = new MediaPlayer();
         mPlayer = MediaPlayer.create(getApplicationContext(), mArrayList[mIndex]);
         mPlayer.start();
         mPlayState = true;
         //通過廣播發送當前播放狀態到Widget
         postState(getApplicationContext(), ExampleAppWidgetProvider.VAL_UPDATE_UI_PLAY,mIndex);
     }
     //歌曲初始化
     private void initList() {
         //歌曲路徑
         mArrayList[0] = R.raw.night_two;
         mArrayList[1] = R.raw.night_four;
         mArrayList[2] = R.raw.night_five;
         mArrayList[3] = R.raw.night_six;
         //歌曲名稱
         mArrayListName[0] ="石進-夜的鋼琴曲二";
         mArrayListName[1] = "石進-夜的鋼琴曲四";
         mArrayListName[2] ="石進-夜的鋼琴曲五";
         mArrayListName[3] = "石進-夜的鋼琴曲六";
     }

(6)Service發送廣播

歌曲通過Widget不同按鈕切換發送廣播到Service,Service通過播放功能函數(參考項目源代碼)做出相應的播放功能切換處理以後,就又一次發送一個廣播信息回饋給Widget,Widget接收到廣播信息後進行更新處理,項目代碼如下:

 //回饋廣播信息給Widget
     private void postState(Context context, int state,int songid) {
         //定義發送廣播接收者
         Intent actionIntent = new Intent(ExampleAppWidgetProvider.MAIN_UPDATE_UI);
         //定義歌曲播放狀態(播放/暫停)
         actionIntent.putExtra(ExampleAppWidgetProvider.KEY_MAIN_ACTIVITY_UI_BTN,state);
         //定義發送信息(歌曲名稱)
         actionIntent.putExtra(ExampleAppWidgetProvider.KEY_MAIN_ACTIVITY_UI_TEXT, mArrayListName[songid]);
         context.sendBroadcast(actionIntent);
     }

6.項目源代碼下載

本項目源代碼在360雲盤上,開發環境為 Android Studio 2.0 beta 7。

https://yunpan.cn/cYamkZG3sq9jf  訪問密碼 f3d5

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved