Android 中Notification弹出通知实现代码
程序员文章站
2023-12-10 14:25:22
notificationmanager 是状态栏通知的管理类,负责发通知、清除通知等操作。
notificationmanager 是一个系统service,可通过get...
notificationmanager 是状态栏通知的管理类,负责发通知、清除通知等操作。
notificationmanager 是一个系统service,可通过getsystemservice(notification_service)方法来获取
接下来我想说的是android5.0 后的弹出通知,
网上的方法是:
//第一步:实例化通知栏构造器notification.builder: notification.builder builder =new notification.builder(mainactivity.this);//实例化通知栏构造器notification.builder,参数必填(context类型),为创建实例的上下文 //第二步:获取状态通知栏管理: notificationmanager mnotifymgr = (notificationmanager) getsystemservice(notification_service);//获取状态栏通知的管理类(负责发通知、清除通知等操作) //第三步:设置通知栏pendingintent(点击动作事件等都包含在这里): intent push =new intent(mainactivity.this,mainactivity.class);//新建一个显式意图,第一个参数 context 的解释是用于获得 package name,以便找到第二个参数 class 的位置 //pendingintent可以看做是对intent的包装,通过名称可以看出pendingintent用于处理即将发生的意图,而intent用来用来处理马上发生的意图 //本程序用来响应点击通知的打开应用,第二个参数非常重要,点击notification 进入到activity, 使用到pendingintent类方法,pengdingintent.getactivity()的第二个参数,即请求参数,实际上是通过该参数来区别不同的intent的,如果id相同,就会覆盖掉之前的intent了 pendingintent contentintent = pendingintent.getactivity(mainactivity.this,0,push,0); //第四步:对builder进行配置: builder .setcontenttitle("my notification")//标题 .setcontenttext("hello world!")// 详细内容 .setcontentintent(contentintent)//设置点击意图 .setticker("new message")//第一次推送,角标旁边显示的内容 .setlargeicon(bitmapfactory.decoderesource(getresources(),r.drawable.ic_launcher))//设置大图标 .setdefaults(notification.default_all);//打开呼吸灯,声音,震动,触发系统默认行为 /*notification.default_vibrate //添加默认震动提醒 需要vibrate permission notification.default_sound //添加默认声音提醒 notification.default_lights//添加默认三色灯提醒 notification.default_all//添加默认以上3种全部提醒*/ //.setlights(color.yellow, 300, 0)//单独设置呼吸灯,一般三种颜色:红,绿,蓝,经测试,小米支持黄色 //.setsound(url)//单独设置声音 //.setvibrate(new long[] { 100, 250, 100, 250, 100, 250 })//单独设置震动 //比较手机sdk版本与android 5.0 lollipop的sdk if(android.os.build.version.sdk_int>= android.os.build.version_codes.lollipop) { builder /*android5.0加入了一种新的模式notification的显示等级,共有三种: visibility_public只有在没有锁屏时会显示通知 visibility_private任何情况都会显示通知 visibility_secret在安全锁和没有锁屏的情况下显示通知*/ .setvisibility(notification.visibility_public) .setpriority(notification.priority_default)//设置该通知优先级 .setcategory(notification.category_message)//设置通知类别 //.setcolor(context.getresources().getcolor(r.color.small_icon_bg_color))//设置smallicon的背景色 .setfullscreenintent(contentintent, true)//将notification变为悬挂式notification .setsmallicon(r.drawable.ic_launcher);//设置小图标 } else{ builder .setsmallicon(r.drawable.ic_launcher);//设置小图标 } //第五步:发送通知请求: notification notify = builder.build();//得到一个notification对象 mnotifymgr.notify(1,notify);//发送通知请求 }
但上面的做法并不能在android5.0以下的设备上使通知弹出,因此下面的做法是自己重写notification(网上查找的一些资料,来源忘记了,不好意思)
如果需要使通知自动显示,那么就需要我们在接收到通知后重新定义通知的界面,并使其加载显示在window界面上,这点需要读者了解window的加载机制.
其实简单点来说,就是通过windowmanager的仅有的三个方法(加载,更新,删除)来实现的.如果有大神熟悉这方面的知识可以分享分享.
自定义notification的思路:
1.继承重写notificationcompat,builder来实现类似的notification
2.自定义通知界面
3.自定义notificationmanager,发送显示通知
废话不多说,先上主要代码:
public class headsup { private context context; /** * 出现时间 单位是 second */ private long duration= 3; /** * */ private notification notification; private builder builder; private boolean issticky=false; private boolean activatestatusbar=true; private notification silencernotification; /** * 间隔时间 */ private int code; private charsequence titlestr; private charsequence msgstr; private int icon; private view customview; private boolean isexpand; private headsup(context context) { this.context=context; } public static class builder extends notificationcompat.builder { private headsup headsup; public builder(context context) { super(context); headsup=new headsup(context); } public builder setcontenttitle(charsequence title) { headsup.settitle(title); super.setcontenttitle(title); //状态栏显示内容 return this; } public builder setcontenttext(charsequence text) { headsup.setmessage(text); super.setcontenttext(text); return this; } public builder setsmallicon(int icon) { headsup.seticon(icon); super.setsmallicon(icon); return this; } public headsup buildheadup(){ headsup.setnotification(this.build()); headsup.setbuilder(this); return headsup; } public builder setsticky(boolean issticky){ headsup.setsticky(issticky); return this; } } public context getcontext() { return context; } public long getduration() { return duration; } public notification getnotification() { return notification; } protected void setnotification(notification notification) { this.notification = notification; } public view getcustomview() { return customview; } public void setcustomview(view customview) { this.customview = customview; } public int getcode() { return code; } protected void setcode(int code) { this.code = code; } protected builder getbuilder() { return builder; } private void setbuilder(builder builder) { this.builder = builder; } public boolean issticky() { return issticky; } public void setsticky(boolean issticky) { this.issticky = issticky; } }
public class headsupmanager { private windowmanager wmone; private floatview floatview; private queue<headsup> msgqueue; private static headsupmanager manager; private context context; private boolean ispolling = false; private map<integer, headsup> map; private notificationmanager notificationmanager=null; public static headsupmanager getinstant(context c) { if (manager == null) { manager = new headsupmanager(c); } return manager; } private headsupmanager(context context) { this.context = context; map = new hashmap<integer, headsup>(); msgqueue = new linkedlist<headsup>(); wmone = (windowmanager) context .getsystemservice(context.window_service); notificationmanager= (notificationmanager) context.getsystemservice(context.notification_service); } public void notify(headsup headsup) { if (map.containskey(headsup.getcode())) { msgqueue.remove(map.get(headsup.getcode())); } map.put(headsup.getcode(), headsup); msgqueue.add(headsup); if (!ispolling) { poll(); } } public synchronized void notify(int code,headsup headsup) { headsup.setcode(code); notify(headsup); } public synchronized void cancel(headsup headsup) { cancel(headsup.getcode()); } private synchronized void poll() { if (!msgqueue.isempty()) { headsup headsup = msgqueue.poll(); map.remove(headsup.getcode()); // if ( build.version.sdk_int < 21 || headsup.getcustomview() != null ){ ispolling = true; show(headsup); system.out.println("自定义notification"); // }else { // //当 系统是 lollipop 以上,并且没有自定义布局以后,调用系统自己的 notification // ispolling = false; // notificationmanager.notify(headsup.getcode(),headsup.getbuilder().setsmallicon(headsup.geticon()).build()); // system.out.println("调用系统notification"); // } } else { ispolling = false; } } private void show(headsup headsup) { floatview = new floatview(context, 20); windowmanager.layoutparams params = floatview.winparams; params.flags = windowmanager.layoutparams.flag_not_touch_modal | windowmanager.layoutparams.flag_not_focusable |windowmanager.layoutparams.flag_fullscreen | windowmanager.layoutparams.flag_layout_in_screen; params.type = windowmanager.layoutparams.type_system_error; params.width = windowmanager.layoutparams.match_parent; params.height = windowmanager.layoutparams.wrap_content; params.format = -3; params.gravity = gravity.center | gravity.top; params.x = floatview.originalleft; params.y = 10; params.alpha = 1f; wmone.addview(floatview, params); objectanimator a = objectanimator.offloat(floatview.rootview, "translationy", -700, 0); a.setduration(600); a.start(); floatview.setnotification(headsup); if(headsup.getnotification()!=null){ notificationmanager.notify(headsup.getcode(), headsup.getnotification()); } } public void cancel(){ if(floatview !=null && floatview.getparent()!=null) { floatview.cancel(); } } protected void dismiss() { if (floatview.getparent()!=null) { wmone.removeview(floatview); floatview.postdelayed(new runnable() { @override public void run() { poll(); } }, 200); } } protected void animdismiss(){ if(floatview !=null && floatview.getparent()!=null){ objectanimator a = objectanimator.offloat(floatview.rootview, "translationy", 0, -700); a.setduration(700); a.start(); a.addlistener(new animator.animatorlistener() { @override public void onanimationstart(animator animator) { } @override public void onanimationend(animator animator) { dismiss(); } @override public void onanimationcancel(animator animator) { } @override public void onanimationrepeat(animator animator) { } }); } } protected void animdismiss(headsup headsup){ if(floatview.getheadsup().getcode()==headsup.getcode()){ animdismiss(); } } public void cancel(int code) { if (map.containskey(code)) { msgqueue.remove(map.get(code)); } if(floatview!=null && floatview.getheadsup().getcode()==code){ animdismiss(); } } public void close() { cancelall(); manager = null; } public void cancelall() { msgqueue.clear(); if (floatview!=null && floatview.getparent()!=null) { animdismiss(); } } }
public class floatview extends linearlayout { private float rawx = 0; private float rawy=0; private float touchx = 0; private float starty = 0; public linearlayout rootview; public int originalleft; public int viewwidth; private float validwidth; private velocitytracker velocitytracker; private int maxvelocity; private distance distance; private scrollorientationenum scrollorientationenum=scrollorientationenum.none; public static windowmanager.layoutparams winparams = new windowmanager.layoutparams(); public floatview(final context context, int i) { super(context); linearlayout view = (linearlayout) layoutinflater.from(getcontext()).inflate(r.layout.notification_bg, null); maxvelocity= viewconfiguration.get(context).getscaledmaximumflingvelocity(); rootview = (linearlayout) view.findviewbyid(r.id.rootview); addview(view); viewwidth = context.getresources().getdisplaymetrics().widthpixels; validwidth=viewwidth/2.0f; originalleft = 0; } public void setcustomview(view view) { rootview.addview(view); } @override protected void onfinishinflate() { super.onfinishinflate(); } private headsup headsup; private long cutdown; private handler mhandle=null; private cutdowntime cutdowntime; private class cutdowntime extends thread{ @override public void run() { super.run(); while (cutdown>0){ try { thread.sleep(1000); cutdown--; } catch (interruptedexception e) { e.printstacktrace(); } } if(cutdown==0) { mhandle.sendemptymessage(0); } } }; public headsup getheadsup() { return headsup; } private int pointerid; public boolean ontouchevent(motionevent event) { rawx = event.getrawx(); rawy=event.getrawy(); acquirevelocitytracker(event); cutdown= headsup.getduration(); switch (event.getaction()) { case motionevent.action_down: touchx = event.getx(); starty = event.getrawy(); pointerid=event.getpointerid(0); break; case motionevent.action_move: switch (scrollorientationenum){ case none: if(math.abs((rawx - touchx))>20) { scrollorientationenum=scrollorientationenum.horizontal; }else if(starty-rawy>20){ scrollorientationenum=scrollorientationenum.vertical; } break; case horizontal: updateposition((int) (rawx - touchx)); break; case vertical: if(starty-rawy>20) { cancel(); } break; } break; case motionevent.action_up: velocitytracker.computecurrentvelocity(1000,maxvelocity); int dis= (int) velocitytracker.getyvelocity(pointerid); if(scrollorientationenum==scrollorientationenum.none){ if(headsup.getnotification().contentintent!=null){ try { headsup.getnotification().contentintent.send(); cancel(); } catch (pendingintent.canceledexception e) { e.printstacktrace(); } } break; } int tox; if(preleft>0){ tox= (int) (preleft+math.abs(dis)); }else{ tox= (int) (preleft-math.abs(dis)); } if (tox <= -validwidth) { float prealpha=1-math.abs(preleft)/validwidth; prealpha=prealpha>=0?prealpha:0; translationx(preleft,-(validwidth+10),prealpha,0); } else if (tox <= validwidth) { float prealpha=1-math.abs(preleft)/validwidth; prealpha=prealpha>=0?prealpha:0; translationx(preleft,0,prealpha,1); }else{ float prealpha=1-math.abs(preleft)/validwidth; prealpha=prealpha>=0?prealpha:0; translationx(preleft, validwidth + 10, prealpha, 0); } preleft = 0; scrollorientationenum=scrollorientationenum.none; break; } return super.ontouchevent(event); } /** * * @param event 向velocitytracker添加motionevent * * @see android.view.velocitytracker#obtain() * @see android.view.velocitytracker#addmovement(motionevent) */ private void acquirevelocitytracker( motionevent event) { if(null == velocitytracker) { velocitytracker = velocitytracker.obtain(); } velocitytracker.addmovement(event); } private int preleft; public void updateposition(int left) { float prealpha=1-math.abs(preleft)/validwidth; float leftalpha=1-math.abs(left)/validwidth; prealpha = prealpha>=0 ? prealpha : 0; leftalpha = leftalpha>=0 ? leftalpha : 0; translationx(preleft,left,prealpha,leftalpha); preleft = left; } public void translationx(float fromx,float tox,float formalpha, final float toalpha ){ objectanimator a1=objectanimator.offloat(rootview,"alpha",formalpha,toalpha); objectanimator a2 = objectanimator.offloat(rootview, "translationx", fromx, tox); animatorset animatorset=new animatorset(); animatorset.playtogether(a1,a2); animatorset.addlistener(new animator.animatorlistener() { @override public void onanimationstart(animator animation) { } @override public void onanimationend(animator animation) { if(toalpha==0){ headsupmanager.getinstant(getcontext()).dismiss(); cutdown=-1; if(velocitytracker!=null) { velocitytracker.clear(); try { velocitytracker.recycle(); } catch (illegalstateexception e) { } } } } @override public void onanimationcancel(animator animation) { } @override public void onanimationrepeat(animator animation) { } }); animatorset.start(); } public void setnotification(final headsup headsup) { this.headsup = headsup; mhandle= new handler(){ @override public void handlemessage(message msg) { super.handlemessage(msg); headsupmanager.getinstant(getcontext()).animdismiss(headsup); } }; cutdowntime= new cutdowntime(); if(!headsup.issticky()){ cutdowntime.start(); } cutdown= headsup.getduration(); if (headsup.getcustomview() == null) { view defaultview = layoutinflater.from(getcontext()).inflate(r.layout.notification, rootview, false); rootview.addview(defaultview); imageview imageview = (imageview) defaultview.findviewbyid(r.id.iconim); textview titletv = (textview) defaultview.findviewbyid(r.id.titletv); textview timetv = (textview) defaultview.findviewbyid(r.id.timetv); textview messagetv = (textview) defaultview.findviewbyid(r.id.messagetv); imageview.setimageresource(headsup.geticon()); titletv.settext(headsup.gettitlestr()); messagetv.settext(headsup.getmsgstr()); simpledateformat simpledateformat=new simpledateformat("hh:mm"); timetv.settext( simpledateformat.format(new date())); } else { setcustomview(headsup.getcustomview()); } } protected void cancel(){ headsupmanager.getinstant(getcontext()).animdismiss(); cutdown = -1; cutdowntime.interrupt(); if(velocitytracker!=null) { try { velocitytracker.clear(); velocitytracker.recycle(); } catch (illegalstateexception e) { } } } enum scrollorientationenum { vertical,horizontal,none } }
具体用法:
pendingintent pendingintent=pendingintent.getactivity(mainactivity.this,11,new intent(mainactivity.this,mainactivity.class),pendingintent.flag_update_current); view view=getlayoutinflater().inflate(r.layout.custom_notification, null); view.findviewbyid(r.id.opensource).setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { } }); headsupmanager manage = headsupmanager.getinstant(getapplication()); headsup.builder builder = new headsup.builder(mainactivity.this); builder.setcontenttitle("提醒") //要显示通知栏通知,这个一定要设置 .setsmallicon(r.drawable.icon) .setcontenttext("你有新的消息") //2.3 一定要设置这个参数,负责会报错 .setcontentintent(pendingintent) //.setfullscreenintent(pendingintent, false) headsup headsup = builder.buildheadup(); headsup.setcustomview(view); manage.notify(1, headsup); }
总结
以上所述是小编给大家介绍的android 中notification弹出实现代码,希望对大家有所帮助
推荐阅读