編輯:關於android開發
上一章講述了Android界面開發中的Widget,Service,BroadcastReceiver基本知識點,本章以一個實際案例-後台音樂播放器解析各個知識點之間的關系。
做一個Android音樂播放器
圖1
圖2
圖3
簡易說明
長按手機界面出現如圖2所示信息,彈出小部件選項,點擊進入小部件如圖1。選擇極客班-作業四,根據提示拖放界面到桌面,出現如圖3所示音樂播放界面。點擊按鈕可實現音樂切換播放歌曲功能。
後台音樂播放器主要是通過Widget的特性,用廣播為通道,完成Widget與Service之間的交互。
Widget:更新桌面信息,發送廣播信息,接收用戶操作事件。
Service:注冊服務,接收廣播信息,發送廣播信息。
音樂播放器在界面布局和配置文件中主要包括以下方面:
在用戶添加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,而是像消息一樣被發送出去,等接收方接到以後,再分析裡面的內容。項目相關代 碼摘抄如下:
接收用戶操作,在接收時,首先根據當前用戶點擊的哪個按鈕,然後給MusicManageService發送不同的廣播(發送按鈕id),讓MusicManageService做出不同的響應,接收代碼如下 :
1 // 接收廣播的回調函數 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()//發送按鍵廣播 private void pushAction(Context context, int ACTION) { //發送目的服務 Intent actionIntent = new Intent(MusicManageService.ACTION); //發送參數 actionIntent.putExtra(MusicManageService.KEY_USR_ACTION, ACTION); context.sendBroadcast(actionIntent); }
服 務要與按鈕相交互,在Service中一般是通過BroadcastReceiver來實現,所以在 MusicManageService的OnCreate函數中(Service起來的時候調用OnCreate)應該包括下面幾個步驟:注冊 Receiver。對應的項目代碼如下:
1 private BroadcastReceiver receiver = 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 @Override 23 public void onCreate() { 24 // TODO Auto-generated method stub 25 super.onCreate(); 26 IntentFilter intentFilter = new IntentFilter(); 27 intentFilter.addAction(ACTION); 28 //注冊服務 29 registerReceiver(receiver, intentFilter); 30 //加載歌曲 31 initList(); 32 //播放默認歌曲 33 mediaPlayerStart(); 34 }
歌曲為本地歌曲文件,放在項目的raw目錄下:
1 //歌曲播放 2 private void mediaPlayerStart(){ 3 mPlayer = new MediaPlayer(); 4 mPlayer = MediaPlayer.create(getApplicationContext(), mArrayList[mIndex]); 5 mPlayer.start(); 6 mPlayState = true; 7 //通過廣播發送當前播放狀態到Widget 8 postState(getApplicationContext(), ExampleAppWidgetProvider.VAL_UPDATE_UI_PLAY,mIndex); 9 } 10 //歌曲初始化 11 private void initList() { 12 //歌曲路徑 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 //歌曲名稱 18 mArrayListName[0] ="石進-夜的鋼琴曲二"; 19 mArrayListName[1] = "石進-夜的鋼琴曲四"; 20 mArrayListName[2] ="石進-夜的鋼琴曲五"; 21 mArrayListName[3] = "石進-夜的鋼琴曲六"; 22 }
歌曲通過Widget不同按鈕切換發送廣播到Service,Service通過播放功能函數(參考項目源代碼)做出相應的播放功能切換處理以後,就又一次發送一個廣播信息回饋給Widget,Widget接收到廣播信息後進行更新處理,項目代碼如下:
1 //回饋廣播信息給Widget 2 private void postState(Context context, int state,int songid) { 3 //定義發送廣播接收者 4 Intent actionIntent = new Intent(ExampleAppWidgetProvider.MAIN_UPDATE_UI); 5 //定義歌曲播放狀態(播放/暫停) 6 actionIntent.putExtra(ExampleAppWidgetProvider.KEY_MAIN_ACTIVITY_UI_BTN,state); 7 //定義發送信息(歌曲名稱) 8 actionIntent.putExtra(ExampleAppWidgetProvider.KEY_MAIN_ACTIVITY_UI_TEXT, mArrayListName[songid]); 9 context.sendBroadcast(actionIntent); 10 }
本項目源代碼在360雲盤上,開發環境為 Android Studio 2.0 beta 7。
https://yunpan.cn/cYamkZG3sq9jf 訪問密碼 f3d5
Android 手機衛士--自定義屬性,android衛士在前面的文章中,已經實現了“設置中心”第一欄的功能以及布局 本文地址:http://w
Android Studio添加Parcelable序列化小工具(快速提高開發效率) Android Studio添加Parcelable序列化小工具(快速提高開發效
Android 代碼動態改變View的屬性 設置Android View的長寬和位置我們平時都會在Layout的XML中定義,那麼什麼時候需要動態在代碼中設置View
仿哔哩哔哩應用客戶端Android版源碼,android這是一款高仿哔哩哔哩安卓客戶端,跟官方網的差不多吧,界面也幾乎是一樣的,應用裡面也加了一些彈出廣告,大家可以參考一