android:Notification
转载:https://www.jianshu.com/p/141fc999ac10
那种基础概念什么的我就简单的说一下了,不过你要是问我通知栏的每一部分对应什么参数,我就不高兴回答了
基本属性
public Builder setTicker(CharSequence tickerText)
设置状态栏开始动画的文字
public Builder setContentTitle(CharSequence title)
设置内容区的标题,必须设置
public Builder setContentText(CharSequence text)
设置内容区的内容,必须设置
public Builder setContentIntent(PendingIntent intent)
设置点击通知后操作(可以跳转Activity,打开Service,或者发送广播)
public Builder setColor(@ColorInt int argb)
这个可以设置smallIcon的背景色
public Builder setSmallIcon(@DrawableRes int icon)
设置小图标,必须设置
*public Builder setLargeIcon(Bitmap b) *
设置打开通知栏后的大图标
*public Builder setWhen(long when) *
设置显示通知的时间,不设置默认获取系统时间,这个值会在Notification上面显示出来
*public Builder setAutoCancel(boolean autoCancel) *
设置为true,点击该条通知会自动删除,false时只能通过滑动来删除
public Builder setPriority(int pri)
设置优先级,级别高的排在前面
public Builder setDefaults(int defaults)
设置上述铃声,振动,闪烁用|分隔,常量在Notification里
public Builder setOngoing(boolean ongoing)
设置是否为一个正在进行中的通知,这一类型的通知将无法删除
通知的提醒方式
声音提醒
默认声音
notification.defaults |= Notification.DEFAULT_SOUND;
自定义声音
notification.sound = Uri.parse("file:///sdcard0/notification.ogg");
震动提醒
默认振动
notification.defaults |= Notification.DEFAULT_VIBRATE;
自定义振动
long[] vibrate = {100, 200, 300, 400}; //震动效果,表示在100、200、300、400这些时间点交替启动和关闭震动
notification.vibrate = vibrate;
闪烁提醒
默认闪烁
notification.defaults |= Notification.DEFAULT_LIGHTS;
自定义闪烁
notification.ledARGB = 0xff00ff00; // LED灯的颜色,绿灯
notification.ledOnMS = 300; // LED灯显示的毫秒数,300毫秒
notification.ledOffMS = 1000; // LED灯关闭的毫秒数,1000毫秒
notification.flags |= Notification.FLAG_SHOW_LIGHTS; // 必须加上这个标志
PendingIntent
PendingIntent pendingIntent=PendingIntent.getActivity(MainActivity.this, (int) SystemClock.uptimeMillis(),newIntent(MainActivity.this, OpenActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
flags有四种不同的值:
FLAG_CANCEL_CURRENT:如果构建的PendingIntent已经存在,则取消前一个,重新构建一个。
FLAG_NO_CREATE:如果前一个PendingIntent已经不存在了,将不再构建它。
FLAG_ONE_SHOT:表明这里构建的PendingIntent只能使用一次。
FLAG_UPDATE_CURRENT:如果构建的PendingIntent已经存在,那么系统将不会重复创建,只是把之前不同的传值替换掉。通常做法就是在构建PendingIntent的时候传入不一样的requestCode来更新PendingIntent
最简单的通知
将之前提到的那些基础点串起来,就可以发送一条一行文本的通知了
NotificationManager manager= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
publicvoidsample(String ticker, String title, String content,intsmallIcon, PendingIntent intent,booleansound,booleanvibrate,booleanlights){ builder.setTicker(ticker); builder.setContentTitle(title); builder.setContentText(content); builder.setContentIntent(intent); builder.setColor(Color.RED); builder.setSmallIcon(smallIcon); builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher)); builder.setWhen(System.currentTimeMillis()); builder.setAutoCancel(true); builder.setPriority(NotificationCompat.PRIORITY_MAX);intdefaults=0;if(sound) { defaults |= Notification.DEFAULT_SOUND; }if(vibrate) { defaults |= Notification.DEFAULT_VIBRATE; }if(lights) { defaults |= Notification.DEFAULT_LIGHTS; } builder.setDefaults(defaults); builder.setOngoing(true); }
publicvoidsendSingleLineNotification(String ticker, String title, String content,intsmallIcon, PendingIntent intent,booleansound,booleanvibrate,booleanlights){ sample(ticker, title ,content, smallIcon, intent, sound, vibrate, lights); Notification notification=builder.build(); send(notification);}
大视图通知
从api16开始,通知出现了大视图的样式
大图通知一般分成3种,文字型(BigTextStyle)、图片型(BigPictureStyle)、列表型(InboxStyle)
处理这一类的通知,需要在基本配置上,外加一些处理
多行文本
publicvoidsendMoreLineNotification(String ticker, String title, String content,intsmallIcon, PendingIntent intent,booleansound,booleanvibrate,booleanlights){if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { Toast.makeText(context,"您的手机低于Android 4.1.2,不支持!!", Toast.LENGTH_SHORT).show();return; } sample(ticker, title, content, smallIcon, intent, sound, vibrate, lights); Notification notification=newNotificationCompat.BigTextStyle(builder).bigText(content).build(); send(notification);}
多行文本比之前多一个bigText方法,放置好content即可
大图模式
publicvoidsendBigPicNotification(String ticker, String title, String content,intsmallIcon, PendingIntent intent,booleansound,booleanvibrate,booleanlights){if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { Toast.makeText(context,"您的手机低于Android 4.1.2,不支持!!", Toast.LENGTH_SHORT).show();return; } sample(ticker, title, content, smallIcon, intent, sound, vibrate, lights);//大图Bitmap bigPicture=BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher);//图标Bitmap bigLargeIcon=BitmapFactory.decodeResource(context.getResources(), R.mipmap.android_bigicon); Notification notification=newNotificationCompat.BigPictureStyle(builder).bigLargeIcon(bigLargeIcon).bigPicture(bigPicture).build(); send(notification);}
bigPicture为那张大图,bigLargeIcon就是之前setLargeIcon位置上的Icon,这边之所以变成2个方法,是因为让两种展现形式效果不同,因为你可以通过滑动通知,来改变通知的样式
列表型
publicvoidsendListNotification(String ticker, String title, String content,intsmallIcon, PendingIntent intent, ArrayList conntents,booleansound,booleanvibrate,booleanlights){if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { Toast.makeText(context,"您的手机低于Android 4.1.2,不支持!!", Toast.LENGTH_SHORT).show();return; } sample(ticker, title, content, smallIcon, intent, sound, vibrate, lights); NotificationCompat.InboxStyle style=newNotificationCompat.InboxStyle(builder);for(String conntent : conntents) { style.addLine(conntent); } style.setSummaryText(conntents.size()+"条消息"); style.setBigContentTitle(title); Notification notification=style.build(); send(notification);}
addLine就是中间列表部分,setSummaryText就是底部文字,setBigContentTitle就是标题
InboxStyle效果
添加可点击的按钮的通知
Action
publicvoidsendActionNotification(String ticker, String title, String content,intsmallIcon, PendingIntent intent,intleftIcon, String leftText, PendingIntent leftPI,intrightIcon, String rightText, PendingIntent rightPI,booleansound,booleanvibrate,booleanlights){ sample(ticker, title, content, smallIcon, intent, sound, vibrate, lights); builder.addAction(leftIcon, leftText, leftPI); builder.addAction(rightIcon, rightText, rightPI); Notification notification=builder.build(); send(notification);}
只要传入按钮的文字、图标以及PendingIntent即可
带进度条的通知
带进度条的通知
带进度条的通知
这种一般在下载过程中使用的比较多
publicvoidsendProgressNotification(String ticker, String title, String content,intsmallIcon, PendingIntent intent,booleansound,booleanvibrate,booleanlights){ sample(ticker, title, content, smallIcon, intent, sound, vibrate, lights);newThread(newRunnable() {@Overridepublicvoidrun(){for(inti=0;i<=100;i+=10) { builder.setProgress(100, i,false); send(builder.build());try{ Thread.sleep(500); }catch(InterruptedException e) { e.printStackTrace(); } }//下载完成builder.setContentText("下载完成").setProgress(0,0,false); send(builder.build()); } }).start();}
只要加上setProgress即可,三个参数分别是最大值、当前值、是否显示具体进度。我这里是模拟一个下载过程
自定义通知
自定义通知首先明确一点是要用RemoteViews来设置布局
PendingIntent remotePending=PendingIntent.getActivity(MainActivity.this,0,newIntent(MainActivity.this, ShareActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);RemoteViews contentView=newRemoteViews(getPackageName(), R.layout.remoteview);contentView.setTextViewText(R.id.share_content,"这是自定义的view");contentView.setOnClickPendingIntent(R.id.share_facebook, remotePending);contentView.setOnClickPendingIntent(R.id.share_twitter, remotePending);RemoteViews bigContentView=newRemoteViews(getPackageName(), R.layout.bigcontentview);bigContentView.setTextViewText(R.id.share_content,"这是自定义的view");bigContentView.setOnClickPendingIntent(R.id.share_facebook, remotePending);bigContentView.setOnClickPendingIntent(R.id.share_twitter, remotePending);
//这边写了2个RemoteViews,同样是因为在api大于等于16的情况下,如果视图超过一定范围,可以转变成bigContentView
publicvoidsendCustomerNotification(String ticker, String title, String content,intsmallIcon, PendingIntent intent, RemoteViews contentView, RemoteViews bigContentView,booleansound,booleanvibrate,booleanlights){ sample(ticker, title, content, smallIcon, intent, sound, vibrate, lights); Notification notification=builder.build(); notification.bigContentView=bigContentView; notification.contentView=contentView; send(notification);}
OK,功能介绍完成,现在介绍一些不平常的东西
高级玩法
RemoteViews适配
适配问题
适配问题
我们在使用remoteViews的时候,最怕就是遇到这种情况:因为通知栏的背景色在不同rom上的效果不同,文本颜色就不好确定,你写成白的,那么在白色背景上就有问题,写成黑的,在黑色背景上就有问题。怎么办?之前在网上找的通过style进行处理的方式不可行,我在这里结合hackware大神提供的方法来获取通知的背景色
publicstaticbooleanisDarkNotificationTheme(Context context){return!isSimilarColor(Color.BLACK, getNotificationColor(context));}/** * 获取通知栏颜色 *@paramcontext *@return*/publicstaticintgetNotificationColor(Context context){ NotificationCompat.Builder builder=newNotificationCompat.Builder(context); Notification notification=builder.build();intlayoutId=notification.contentView.getLayoutId(); ViewGroup viewGroup= (ViewGroup) LayoutInflater.from(context).inflate(layoutId,null,false);if(viewGroup.findViewById(android.R.id.title)!=null) {return((TextView) viewGroup.findViewById(android.R.id.title)).getCurrentTextColor(); }returnfindColor(viewGroup);}privatestaticbooleanisSimilarColor(intbaseColor,intcolor){intsimpleBaseColor=baseColor|0xff000000;intsimpleColor=color|0xff000000;intbaseRed=Color.red(simpleBaseColor)-Color.red(simpleColor);intbaseGreen=Color.green(simpleBaseColor)-Color.green(simpleColor);intbaseBlue=Color.blue(simpleBaseColor)-Color.blue(simpleColor);doublevalue=Math.sqrt(baseRed*baseRed+baseGreen*baseGreen+baseBlue*baseBlue);if(value<180.0) {returntrue; }returnfalse;}
这里有几个注意点
TextView textView= (TextView) viewGroup.findViewById(android.R.id.title);可能在有的手机上获取textview为空,所以我想notification的文本区域,系统默认肯定有一个值的,那我就直接遍历找到这个值即可
privatestaticintfindColor(ViewGroup viewGroupSource){intcolor=Color.TRANSPARENT; LinkedList viewGroups=newLinkedList<>(); viewGroups.add(viewGroupSource);while(viewGroups.size()>0) { ViewGroup viewGroup1=viewGroups.getFirst();for(inti =0; i < viewGroup1.getChildCount(); i++) {if(viewGroup1.getChildAt(i)instanceofViewGroup) { viewGroups.add((ViewGroup) viewGroup1.getChildAt(i)); }elseif(viewGroup1.getChildAt(i)instanceofTextView) {if(((TextView) viewGroup1.getChildAt(i)).getCurrentTextColor()!=-1) { color=((TextView) viewGroup1.getChildAt(i)).getCurrentTextColor(); } } } viewGroups.remove(viewGroup1); }returncolor;}
这样你就可以通过
contentView.setInt(R.id.share_content,"setTextColor", NotificationUtils.isDarkNotificationTheme(MainActivity.this)==true?Color.WHITE:Color.BLACK);
实现颜色替换的功能,setInt、setString的功能是通过反射进行操作的
文章到此结束,感谢大家的阅读
参考文章