首页 > 系统 > Android > 正文

Android 中Notification弹出通知实现代码

2019-12-12 02:09:29
字体:
来源:转载
供稿:网友

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弹出实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表