Notification通知栏(小图标出现在在电池电量条,下拉会出现一个提示通知对话框)
- notification的构造方法
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);//通过工厂设计模式来构造
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.color));//设置大图标 (图中4的部分)
builder.setSmallIcon(R.drawable.ic_stat_notification); //设置小图标(图中1的部分)
builder.setContentTitle(getString(R.string.notification));//设置通知栏标题(图中2的部分)
builder.setContentText(getString(R.string.ping));//设置通知栏内容(图中3的部分)
builder.setDefaults(Notification.DEFAULT_ALL); //设置通知栏的提示(震动,响铃,三色灯)需要震动(Vibrate)权限
builder.setWhen(System.currentTimeMillis());//设置当前时间为通知时间(图中5的位置)
builder.setStyle(new NotificationCompat.BigTextStyle().bigText(msg));//设置通知栏风格(图中5的部分点击上括号可以显示大文本风格)
builder.addAction(R.drawable.ic_stat_dismiss, getString(R.string.dismiss), dismissPendingIntent);//为通知栏添加点击按钮(图中6的部分)点击相应事件通过pendingIntent来实现
bulider.setContentIntent(pendingIntent);//点击内容时的跳转intent
builder.setDeleteIntent(pendingIntent);//向右滑动Notification时跳转的intent
builder.addAction(R.drawable.ic_stat_snooze, getString(R.string.snooze), piSnooze);;//为通知栏添加点击按钮(图中6的部分)
NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
nm.notify(CommonConstants.NOTIFICATION_ID, builder.build());//通过NotificationManager将通知栏发送出去(ID是为这个通知取的序号,当需要更新这个通知时,可以根据这个序号再notify)
标准的通知栏如图
其中 1(smallIcon),2(ContentTitle),3(contentText),是必须要设置的,不然通知栏将无法显示
notification的不同风格
- 进度条风格(4.0及以后版本才有用)
builder.setProgress(int max, int progress, boolean indeterminate);//当需要进度精确显示时,设置indeterminate为FALSE,设置最大进度max,设置当前进度progress,进度发生变化时,不断设置builder.setProgress()中的progress值,不断更新该通知,实现进度条增长的效果
// 在子线程中更新进度条
new Thread(
new Runnable() {
@Override
public void run() {
int incr;
for (incr = 0; incr <= 100; incr+=5) {
mBuilder.setProgress(100, incr, false);
mNotifyManager.notify(id, mBuilder.build());
try {
// Sleep for 5 seconds
Thread.sleep(5*1000);
} catch (InterruptedException e) {
Log.d(TAG, "sleep failure");
}
}
mBuilder.setContentText("Download complete")//下载完成
.setProgress(0,0,false); //移除进度条
mNotifyManager.notify(id, mBuilder.build());
}
}
).start();
builder.setContentText("Download complete);
builder.setProgress(0,0,false);//当下载完成时,设置为这些值时,进度条消失
不需要精确显示进度条是,可以设置为builder.setProgress(0,0,true),当indeterminate设置为true时,会自动忽略前面的两个参数
- 大图风格 BigPictureStyle(4.1之前的版本不支持大视图)
Bitmap picture = BitmapFactory.decodeResource(getResources(), R.drawable.sunflower);
builder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(picture));//设置style为BigPictureStyle,即可显示图片
-BigTextStyle(4.1之前的版本不支持大视图)
NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
bigTextStyle.setSummaryText("summaryText");
bigTextStyle.setBigContentTitle("BigContentTitle");
builder.setContentText("contentText");
builder.setStyle(bigTextStyle);
-InBoxStyle
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.setBigContentTitle("BigContentTitle");
String[] events = getResources().getStringArray(R.array.events);
for (int i = 0; i < events.length; i++) {
inboxStyle.addLine(events[i]);//设置每项的类容
}
inboxStyle.setSummaryText("summaryText");//设置简要类容描述
builder.setStyle(inboxStyle);
-自定义布局(remoteViews)
RemoteViews:在其他进程中显示的Views并修改Viewss属性值,它主要被用于AppWidget和Notification
/**
*首先在res/layout/下定义一个布局文件,用于创建remoteViews
**/
/*创建RemoteViews对象,将定义好的布局文件传入进去*/
RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.remote_views);
remoteViews.setTextViewText(R.id.title_tv, title);//修改RemoteViews中TextView的内容
remoteViews.setImageViewResource(R.id.icon_iv, R.drawable.logo);//修改ImageView或ImageButton中图片
remoteViews.setInt(R.id.close_iv, "setColorFilter", getIconColor());
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.notice_view_type_0, pendingIntent);//为RemoteViews中的某个区域添加点击事件
/*带按钮的布局相应点击事件在3.0以下版本没有用,所以需要做系统版本判断,来显示消失按钮。*/
if(Build.VERSION.SDK_INT <= 9){
remoteViews.setViewVisibility(R.id.imageView, View.GONE);
}else{
remoteViews.setViewVisibility(R.id.ib_01, View.GONE);
}
/*将remoteViews应用于Notification上*/
builder.setContent(remoteViews);//通过setContent()方法设置的Notification是定高的(一般为64dp的高度,)
builder.setCustomContentView(remoteViews);//设置正常大小的Notification(为)
builder.setCustomBigContentView(remoteViews);//Sdk16引入的可以向下拉伸的扩展的Notification(最高为256dp)
注意:
Notification的自定义布局是RemoteViews,和其他RemoteViews一样,在自定义视图布局文件中,仅支持FrameLayout、LinearLayout、RelativeLayout三种布局控件和AnalogClock、Chronometer、Button、ImageButton、ImageView、ProgressBar、TextView、ViewFlipper、ListView、GridView、StackView和AdapterViewFlipper这些显示控件,不支持这些类的子类或Android提供的其他控件。否则会引起ClassNotFoundException异常
-点击跳转中返回父Activity推栈
/*在manifest中设置parentActivity */
<activity
android:name=".SecondActivity"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity>
//在代码中设置
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(this);
Intent resultIntent = new Intent(this, ThirdActivity.class);
taskStackBuilder.addNextIntentWithParentStack(resultIntent);
PendingIntent mPending = taskStackBuilder.getPendingIntent(1, PendingIntent.FLAG_UPDATE_CURRENT);
/*flag 参数的取值:FLAG_CANCEL_CURRENT:如果构建的PendingIntent已经存在,则取消前一个,重新构建一个。
FLAG_NO_CREATE:如果前一个PendingIntent已经不存在了,将不再构建它。
FLAG_ONE_SHOT:表明这里构建的PendingIntent只能使用一次。
FLAG_UPDATE_CURRENT:如果构建的PendingIntent已经存在,那么系统将不会重复创建,只是把之前不同的传值替换掉。
使用FLAG_UPDATE_CURRENT这个参数后,常常会发现,我们点击通知栏后,系统没有响应,时灵时不灵的,很是忧郁,这是为什么呢?原来使用FLAG_UPDATE_CURRENT这个参数后,系统不会重新创建新的PendingIntent,这样一来,如果你传递的Intent的 extra参数没有变化的话,那么系统就会认为你没有发送新的PendingIntent,这样就不会重新响应你的点击事件。一般情况下,为了能够区分每次的PendingIntent不一样,我们常常会在构造Intent的时候,设置不同的Action或者Extra值,这样一来,即使是使用FLAG_UPDATE_CURRENT这个参数,系统也会因为传值参数的变化而去响应每次的点击跳转事件。不过这种解决方法还是有些麻烦,有时候,我们根本不需要传递额外的Aciton或者参数值,这该怎么办呢?哈哈,解决代码已经在上面的代码中写出来了,在stackBuilder.getPendingIntent(requestCode, PendingIntent.FLAG_UPDATE_CURRENT)这个方法中,我们注意到第一个参数,这里,我们只要为这个参数设置一个独一无二的标识,那么刚刚提到的点击无响应的问题就迎刃而解了
*/
builder.setContentIntent(mPending);
Android 5.0(API 21) Notification新特性:
-设置Notification的优先级
setPriority(Notification.PRIORITY_DEFAULT)//有如下几种级别
-Head-up Notification浮动通知栏(api21以上 5.0)
以弹出式窗口显示通知,,满足的条件:
1.设备正在使用且处于全屏状态
2.该Notifiacation具有较高的优先级,且设置了声音(或震动)。
-设置了锁屏可见
builder.setVisibility(Notification.VISIBILITY_PUBLIC);//setVisibility锁屏状态下Notification是否可见
/*有三个取值 Notification.VISIBILITY_PUBLIC锁屏状态下可见
Notification.VISIBILITY_PRIVATE锁屏状态下不可见
Notification.VISIBILITY_SECRET锁屏状态下标题可见,具体content不可见*/
后续再补充:
android5.0新特性:
NotificationCompat.MediaStyle()
android7.0新特性:
Notification.DecoratedCustomViewStyle()
Notification.DecoratedMediaCustomViewStyle()
Notification.MessageStyle()
remoteInput