软件编程
位置:首页>> 软件编程>> Android编程>> Android 中Notification弹出通知实现代码

Android 中Notification弹出通知实现代码

作者:大魚海棠  发布时间:2021-05-31 14:48:18 

标签:android,notification

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弹出实现代码网站的支持!

来源:http://www.cnblogs.com/zh-yale/archive/2017/08/28/7441244.html

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com