自定义通知,显示自定义的通知,告别系统样式的限制,让你的通知更加漂亮。
1.自定义按钮的响应需要api版本11(Android 3.0)以上的支持!
2.通知是远程视图,不跟发出通知的活动、服务等处在同一个运行空间!
3.通知上的对象只能在发出之前设置,不能再发出后获取
===>要更新通知,只能是重新设置通知对象上的对象值,再重新发出通知。
网上方法说是使用setLatestEventInfo()方法
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
但是效果并非你想要的效果,更新过后你的自定义通知的视图是被覆盖的,他的样式是系统的样式。所以只能是重新设置通知内容再发通知。
写法步骤:
1.创建通知管理器、创建远程视图并绑定自定义通知视图
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notify);//远程视图
2.设置远程视图上的对应控件的内容
// 设置远程视图中的控件内容
contentView.setImageViewResource(R.id.notify_music_icon, R.drawable.icon);//图片控件的设置方法
contentView.setTextViewText(R.id.txt_notify_Title, playingName);//文本控件的设置方法
2.1.设置通知上对应按钮点击的响应动作(如果没有自定义按钮可以不写)
contentView.setOnClickPendingIntent(R.id.btn_notify_next, pendingIntent);//设置了按钮btn_notify_next的点击的pendingIntent对象
3.设置通知的PendingIntent(点击通知后要做什么事)
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent , 0);
4.通知绑定远程视图、绑定PendingIntent和发通知
notification.contentView = contentView;// 绑定远程视图
notification.contentIntent = contentIntent;// 绑定 PendingIntent
notificationManager.notify(NOTIFYY_ID, notification);
注:pendingIntent对象可以绑定的是活动,服务或广播(需要广播类进行接收广播)。
比如我们要实现下图的通知,可以看到上面还有三个按钮,我们还要进行响应按钮动作:
图片无法上传,等等。。。。。。。。。。。
这是布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/lavenderblush"
android:orientation="vertical" >
<TextView
android:id="@+id/txt_notify_Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/notify_music_icon"
android:layout_alignTop="@+id/notify_music_icon"
android:layout_marginLeft="5dp"
android:layout_toLeftOf="@+id/btn_notify_pause"
android:layout_toRightOf="@+id/notify_music_icon"
android:paddingTop="3dp"
android:text="TextView"
android:textColor="@color/black" />
<ImageView
android:id="@+id/notify_music_icon"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:src="@drawable/icon" />
<ImageView
android:id="@+id/btn_nitify_exit"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:clickable="true"
android:src="@drawable/btn_notify_exit" />
<ImageView
android:id="@+id/btn_notify_next"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerVertical="true"
android:layout_marginRight="3dp"
android:layout_toLeftOf="@+id/btn_nitify_exit"
android:clickable="true"
android:src="@drawable/btn_notify_next" />
<ImageView
android:id="@+id/btn_notify_pause"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerVertical="true"
android:layout_marginRight="3dp"
android:layout_toLeftOf="@+id/btn_notify_next"
android:clickable="true"
android:src="@drawable/btn_notify_pause" />
RelativeLayout>
以下是完整通知代码:
按钮动作是发送广播,用一个全局广播类接收广播
private void sendNotification() {
//1
notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);//通知管理器
//2
contentView = new RemoteViews(getPackageName(), R.layout.notify);//远程视图
// 设置远程视图中的控件内容
contentView.setImageViewResource(R.id.notify_music_icon, R.drawable.icon);
contentView.setTextViewText(R.id.txt_notify_Title, playingName);
//设置对应的三个按钮和事件
Intent pauseIntent = new Intent(this, MyReceiver.class);//intent是一个广播类对象
pauseIntent.setAction(Utils.NOTIFY_PAUSE);//设置动作
PendingIntent pausePendingIntent = PendingIntent.getBroadcast(this, 0,
pauseIntent, 0);//pendingIntent得到广播
contentView.setOnClickPendingIntent(R.id.btn_notify_pause,
pausePendingIntent);//设置按钮成带PendingIntent的可点击按钮
Intent nextIntent = new Intent(this, MyReceiver.class);
nextIntent.setAction(Utils.NOTIFY_NEXT);
PendingIntent nextPendingIntent = PendingIntent.getBroadcast(this, 0,
nextIntent, 0);
contentView.setOnClickPendingIntent(R.id.btn_notify_next,
nextPendingIntent);
Intent exitIntent = new Intent(this, MyReceiver.class);
exitIntent.setAction(Utils.NOTIFY_EXIT);
PendingIntent exitPendingIntent = PendingIntent.getBroadcast(this, 0,
exitIntent, 0);
contentView.setOnClickPendingIntent(R.id.btn_nitify_exit,
exitPendingIntent);
//如果api版本11(android 3.0)以上按钮才显示
if (android.os.Build.VERSION.SDK_INT >= 11) {
contentView.setViewVisibility(R.id.btn_notify_pause, View.VISIBLE);
contentView.setViewVisibility(R.id.btn_notify_next, View.VISIBLE);
contentView.setViewVisibility(R.id.btn_nitify_exit, View.VISIBLE);
}
//3
notification = new Notification(R.drawable.music, "MusicPlayer", System.currentTimeMillis()); //实例化通知对象
// 绑定远程视图
notification.contentView = contentView;
// 4.定义 PendingIntent并绑定
Intent notificationIntent = new Intent(this, MainActivity.class);
contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;// 绑定 PendingIntent
notification.flags = Notification.FLAG_NO_CLEAR;// 设置不可取消
// 5 发通知
notificationManager.notify(NOTIFY_ID, notification);
}
广播类,用于通知上按钮点击后接收发过来的广播,需要静态的注册广播,使得系统全局都可以用。
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Utils.NOTIFY_EXIT.equals(action)) {
//在这里做需要做的事情
}
if (Utils.NOTIFY_NEXT.equals(action)) {
//在这里做需要做的事情
}
if (Utils.NOTIFY_PAUSE.equals(action)) {
//在这里做需要做的事情
}
}
}
清单文件AndroidManifest.xml中广播的静态注册和设置三个动作(动作字符串分别对应Utils.NOTIFY_EXIT,Utils.NOTIFY_NEXT,Utils.NOTIFY_PAUSE里面的字符串)
<receiver
android:name="com.ql.mediademo2.MyReceiver"
>
<intent-filter >
<action android:name="_notifi_exit"/>
<action android:name="_notifi_next"/>
<action android:name="_notifi_pause"/>
intent-filter>
receiver>
通知的更新:
以下把更新通知封装在了一个自定义方法中
private void notifyNotifycation() {
//重新设置通知上控件的数据
contentView.setImageViewResource(R.id.notify_music_icon, R.drawable.icon);//更新图片
contentView.setTextViewText(R.id.txt_notify_Title, "XXXXX");//更新文本
notificationManager.notify(NOTIFY_ID, notification);//通知管理器重新发通知
}