編輯:關於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衛士
Android 手機衛士--自定義屬性,android衛士在前面的文章中,已經實現了“設置中心”第一欄的功能以及布局 本文地址:http://w
Android Studio添加Parcelable序列化小工具(快速提高開發效率)
Android Studio添加Parcelable序列化小工具(快速提高開發效率) Android Studio添加Parcelable序列化小工具(快速提高開發效
Android 代碼動態改變View的屬性
Android 代碼動態改變View的屬性 設置Android View的長寬和位置我們平時都會在Layout的XML中定義,那麼什麼時候需要動態在代碼中設置View
仿哔哩哔哩應用客戶端Android版源碼,android
仿哔哩哔哩應用客戶端Android版源碼,android這是一款高仿哔哩哔哩安卓客戶端,跟官方網的差不多吧,界面也幾乎是一樣的,應用裡面也加了一些彈出廣告,大家可以參考一