## 1.背景
? ? **通知 -> Service :**
? ?上一篇的MusicService 中提高了通知是Service的前臺顯示,這篇將介紹通知(MusicNotification).通知在這里有四個作用:
? ? (1)顯示當前音樂的信息
? ? (2)播放/暫停音樂
? ? (3)下一曲播放音樂
? ? (4)關閉通知欄(實際上也是停止音樂播放并關閉Service)
? ?**Service -> 通知 :**
? ? 通知和Service是緊密相連的,當Service結束的時候,取消通知;當Service啟動的時候,初始化通知/創建通知;當音樂狀態發生改變的時候,更新通知;如下圖所示 :
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
## 2.通知實現
? ? ? 在這里單獨的將通知單獨的類中,方便使用;沒有使用到通知的震動提醒/鈴聲提醒/閃光燈提醒,如果需要使用,可以看博客 :?
[Android-Notification (通知實現)](http://blog.csdn.net/lablenet/article/details/47999961).
### ? ?(1)通知布局實現
~~~
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp" >
<ImageView
android:id="@+id/iv_notification_logo"
android:layout_width="60dp"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_margin="5dp"
android:src="@drawable/logo" />
<TextView
android:id="@+id/tv_nofitication_singname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_toRightOf="@+id/iv_notification_logo"
android:maxLines="1"
android:textSize="12sp"
android:text="@string/item_notification_singname"
android:textColor="@color/text_color_whrit" />
<TextView
android:id="@+id/tv_nofitication_singer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:textSize="10sp"
android:layout_toRightOf="@+id/iv_notification_logo"
android:text="@string/item_notifiaction_singer"
android:textColor="@color/bg_color" />
<ImageView
android:id="@+id/iv_nofitication_kzhi_play"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
android:layout_toLeftOf="@+id/iv_nofitication_kzhi_next"
android:src="@android:drawable/ic_media_play" />
<ImageView
android:id="@+id/iv_nofitication_kzhi_next"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
android:layout_toLeftOf="@+id/iv_nofitication_kzhi_colse"
android:src="@android:drawable/ic_media_next" />
<ImageView
android:id="@+id/iv_nofitication_kzhi_colse"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:src="@android:drawable/ic_menu_close_clear_cancel"
android:textColor="@color/text_color_main" />
</RelativeLayout>
~~~
? ??
? ? ? ?效果 :
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
### ? ? (2)代碼實現
說明: 1)通知的實現是單例模式實現(惡漢式)(?
[設計模式之單例模式(Singleton pattern)](http://blog.csdn.net/lablenet/article/details/50014001)
);
2)通知中通過使用RemoteViews ,進行自定義布局實現;
3)通過PendingIntent來封裝響應點擊事件的Intent ;
?4)第3條中的Intent,經過測試,只能每個響應事件,填充參數的Intent,只能對應一個點擊事件 , 否則是得不到Intent中的參數的。但如果不需要區分的話,一個Intent就可以實現點擊事件的響應;
5)通過PendingInetnt.getBroadcast() 方法來通知MusicService,進行響應事件的本質作用;
?6)廣播:如果MusicService想要接收到通知來的點擊事件,那么需要在MusicServiceBroadcast中 ? ? ? ? ? ? ? ? ? ? ? ? 注冊(IntentFiliter/addAction(xxx)),同時通知中的Inent需 要setAction(xxx), xxx 要一樣;
**實現的通知源碼分享 :**
~~~
package cn.labelnet.framework;
import com.android.volley.toolbox.ImageLoader.ImageListener;
import android.R.anim;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Build;
import android.widget.RemoteViews;
import cn.labelnet.maskmusic.R;
import cn.labelnet.model.MusicModel;
import cn.labelnet.net.VolleyHttpRequest;
public class MusicNotification extends Notification {
/**
* Music播放控制 的 Notification
* 動態的顯示后臺的MusicService的前臺展示
*/
/**
* 惡漢式實現單例模式加載
*/
private static MusicNotification notifyInstance = null;
// 通知id
private final int NOTIFICATION_ID = 10001;
// 通知
private Notification musicNotifi = null;
// 管理通知
private NotificationManager manager = null;
// 界面實現
private Builder builder = null;
// 上下文
private Context context;
// 布局
private RemoteViews remoteViews;
private final int REQUEST_CODE = 30000;
// 給Service 發送廣播
private final String MUSIC_NOTIFICATION_ACTION_PLAY = "musicnotificaion.To.PLAY";
private final String MUSIC_NOTIFICATION_ACTION_NEXT = "musicnotificaion.To.NEXT";
private final String MUSIC_NOTIFICATION_ACTION_CLOSE = "musicnotificaion.To.CLOSE";
private final String MUSIC_NOTIFICAION_INTENT_KEY = "type";
private final int MUSIC_NOTIFICATION_VALUE_PLAY = 30001;
private final int MUSIC_NOTIFICATION_VALUE_NEXT = 30002;
private final int MUSIC_NOTIFICATION_VALUE_CLOSE =30003;
private Intent play=null,next=null,close = null;
private PendingIntent musicPendIntent = null;
// 給進度條頁面廣播
// 待實現
// 網絡 : 加載圖片實現
private ImageListener imageListener = null;
public void setManager(NotificationManager manager) {
this.manager = manager;
}
public void setContext(Context context) {
this.context = context;
}
private MusicNotification() {
// 初始化操作
remoteViews = new RemoteViews("cn.labelnet.maskmusic",
R.layout.list_item_notification);
builder = new Builder(context);
// 初始化控制的Intent
play = new Intent();
play.setAction(MUSIC_NOTIFICATION_ACTION_PLAY);
next = new Intent();
next.setAction(MUSIC_NOTIFICATION_ACTION_NEXT);
close = new Intent();
close.setAction(MUSIC_NOTIFICATION_ACTION_CLOSE);
}
/**
* 惡漢式實現 通知
*
* @return
*/
public static MusicNotification getMusicNotification() {
if (notifyInstance == null) {
notifyInstance = new MusicNotification();
}
return notifyInstance;
}
/**
* 創建通知
* 初始化通知
*/
@SuppressLint("NewApi")
public void onCreateMusicNotifi() {
// 設置點擊事件
// 1.注冊控制點擊事件
play.putExtra("type",
MUSIC_NOTIFICATION_VALUE_PLAY);
PendingIntent pplay = PendingIntent.getBroadcast(context, REQUEST_CODE,
play, NOTIFICATION_ID);
remoteViews.setOnClickPendingIntent(R.id.iv_nofitication_kzhi_play,
pplay);
// 2.注冊下一首點擊事件
next.putExtra("type",
MUSIC_NOTIFICATION_VALUE_NEXT);
PendingIntent pnext = PendingIntent.getBroadcast(context, REQUEST_CODE,
next, NOTIFICATION_ID);
remoteViews.setOnClickPendingIntent(R.id.iv_nofitication_kzhi_next,
pnext);
// 3.注冊關閉點擊事件
close.putExtra("type",
MUSIC_NOTIFICATION_VALUE_CLOSE);
PendingIntent pclose = PendingIntent.getBroadcast(context, REQUEST_CODE,
close, NOTIFICATION_ID);
remoteViews.setOnClickPendingIntent(R.id.iv_nofitication_kzhi_colse,
pclose);
builder.setContent(remoteViews).setWhen(System.currentTimeMillis())
// 通知產生的時間,會在通知信息里顯示
// .setPriority(Notification.PRIORITY_DEFAULT)
// 設置該通知優先級
.setOngoing(true).setTicker("播放新的一首歌")
.setSmallIcon(R.drawable.logo);
// 兼容性實現
musicNotifi = builder.getNotification();
// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
// musicNotifi = builder.getNotification();
// } else {
// musicNotifi = builder.build();
// }
musicNotifi.flags = Notification.FLAG_ONGOING_EVENT;
manager.notify(NOTIFICATION_ID, musicNotifi);
}
/**
* 更新通知
*/
public void onUpdataMusicNotifi(MusicModel mm, boolean isplay) {
// 設置添加內容
remoteViews.setTextViewText(R.id.tv_nofitication_singname,
(mm.getSongname()!=null?mm.getSongname():"什么東東") + "");
remoteViews.setTextViewText(R.id.tv_nofitication_singer,
(mm.getSingername()!=null?mm.getSingername():"未知") + "");
//判斷是否播放
if (isplay) {
remoteViews.setImageViewResource(R.id.iv_nofitication_kzhi_play,
android.R.drawable.ic_media_pause);
} else {
remoteViews.setImageViewResource(R.id.iv_nofitication_kzhi_play,
android.R.drawable.ic_media_play);
}
onCreateMusicNotifi();
}
/**
* 取消通知欄
*/
public void onCancelMusicNotifi(){
manager.cancel(NOTIFICATION_ID);
}
}
~~~
### (3)廣播的基本使用圖解 ??

## 3.總結
通知的更新控制是在音樂狀態發生改變的時候,就會更新通知的內容;相反通知也可以控制音樂當前的狀態;后面還有音樂播放界面的控制,省去了很多事,簡單的在Service 中調用就可以實現。
? ?MusicService 與 MusicNotification 的基本控制圖 ,如下圖所示 :

音樂的播放/暫停/上一曲/下一曲/停止 基本控制 是在MusicService中實現的,所以請看?
[Android實戰 - 音心播放器 (Music Service 實現)](http://blog.csdn.net/lablenet/article/details/50322487);
- 前言
- Android實戰 - 音心音樂播放器 (開啟篇)
- Android實戰 - 音心音樂播發器 (主界面實現)
- Android實戰 - 音心播放器 (Music Service 實現)
- Android實戰 - 音心播放器 (通知實現音樂的播放/暫停/下一曲控制)
- Android實戰 - 音心播發器 (MusicService ,Notification, MainActivity 總結)
- Android實戰 - 音心播放器 (MusicActivity-音樂播放頁面界面實現)
- Android實戰 - 音心播放器 (MusciActivity-專輯圖片獲得,基本控制實現)
- Android實戰 - 音心播放器(MusicActivity - 歌詞實現)
- Android實戰 - 音心播放器 (MusicActivity - 倒計時 ,進度條實現)
- Android實戰 - 音心播放器 (MusicActivity ,MusicNotification,MusicService總結)
- Android實戰 - 音心播放器 (MusicListActivity - 分類信息界面實現)
- Android實戰 - 音心播放器 (MusicListActivity - 音樂播放和MainActivity的一個問題)
- Android實戰 - 音心播放器 (啟動頁與社交分享(ShareSDK))
- Android實戰 - 音心播放器 (優化Service退出,按兩下退出應用實現)
- Android實戰 - 音心播放器 (項目總結,應用打包發布)