android:Notification

2019-03-20  本文已影响0人  sunny635533

转载: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的功能是通过反射进行操作的

文章到此结束,感谢大家的阅读

参考文章

Android自定义通知样式适配

全面了解Android Notification

上一篇下一篇

猜你喜欢

热点阅读