Android Notification

概要

Notification通知,是一种具有全局效果的通知,它展示在屏幕的顶端,首先会表现为
一个图标的形式,当用户向下滑动的时候,展示出通知具体的内容。比较熟悉的通知有:短
信同事,文件下载通知,以及在音乐播放时,在通知栏有播放通知界面可以控制播放的暂停
播放。

有几点特性:

  • 通知是运行在system server进程中的,由NotificationManagerService管理。
  • Notification的布局并不是支持所有的View控件。
  • 我们使用remoteViews,跨进程通讯更新Notification界面。

Notification的使用

通常的步骤:

  1. 创建一个通知栏的Builder构造类
  2. 定义通知栏的Action
  3. 设置通知栏点击事件
  4. NotificationManager 提交通知

1,一般形式的使用

  • 创建通知,其中setContentIntent方法设置点击意图,在2.3及更低的版本
    中如果未设置,会触发异常。
  • 因为Android的快速发展,而Android的版本也快速的升级导致了一些兼容性
    的问题。对于Notification而言,Android3.0是一个分水岭,在其之前构建
    Notification推荐使用NotificationCompate.Builder,它位于android.support.
    v4.app.NotificationCompat.Builder,是一个Android向下版本的兼容包。
  • 使用闪光灯或者震动效果的通知时,需要添加相关的权限。
    /**
     * 创造默认形式的通知
     * @return
     */
    private Notification createDefault(int prog){
        NotificationCompat.Builder mBuilder
                = new NotificationCompat.Builder(this);
        Notification n = mBuilder
                .setContentTitle("测试标题")
                //设置通知栏标题
                .setContentText("测试内容")
                //设置通知栏显示内容
                .setLargeIcon(BitmapFactory.decodeResource(
                        getResources(),R.drawable.aa2))
                //设置大图标
                .setContentText("测试内容")
                //设置通知栏显示内容
                .setContentIntent(getDefalutIntent(
                        Notification.FLAG_AUTO_CANCEL))
                //设置通知栏点击意图
                //  .setNumber(number) //设置通知集合的数量
                .setTicker("测试通知来啦")
                //通知首次出现在通知栏,带上升动画效果的
                .setWhen(System.currentTimeMillis())
                //通知产生的时间,会在通知信息里显示,一般是系统获
                // 取到的时间
                .setPriority(Notification.PRIORITY_DEFAULT)
                //设置该通知优先级
                .setAutoCancel(true)
                //设置这个标志当用户单击面板就可以让通知将自动取消
                // setOngoing(false)
                // ture,设置他为一个正在进行的通知。他们通常是用来
                // 表示一个后台任务,用户积极参与(如播放音乐)或以某种
                // 方式正在等待,因此占用设备(如一个文件下载,同步操作
                // ,主动网络连接)
                .setDefaults(Notification.DEFAULT_VIBRATE)
                //向通知添加声音、闪灯和振动效果的最简单、最一致的方
                // 式是使用当前的用户默认设置,使用defaults属性,可以
                // 组合
                //Notification.DEFAULT_ALL  Notification.DEFAULT_SOUND 添加声音
                // requires VIBRATE permission
                .setSmallIcon(R.drawable.ic_launcher)
                //设置通知小ICON
                .setProgress(100, prog, false)
                //设置进度
        .build();
        return n;
    }
    private PendingIntent getDefalutIntent(int flags){
        PendingIntent pIntent = PendingIntent.getActivity(this,
                0, new Intent(this, NotificationActivity.class),
                flags);
        return pIntent;
    }

相关权限:

  <!-- 闪光灯权限 -->
  <uses-permission android:name="android.permission.FLASHLIGHT"/>
  <!-- 振动器权限 -->
  <uses-permission android:name="android.permission.VIBRATE"/>

提交通知,(通知的更新,也就是重定义一个notification,以同一个ID提交
就是了)

        Notification notification = createDefault(prog);
        //Notification notification = createCustom();
        NotificationManager nManager = (NotificationManager) 
                getSystemService(Context.NOTIFICATION_SERVICE);
        nManager.notify(Notification_ID, notification);

效果如图:
这里写图片描述

2,自定义样式的使用

使用自定义样式,先看效果图。
分析:有个圆形进度条,实现方式:ImageView + ProgressDrawable(自定义)

这里写图片描述

接着直接上代码:

ProgressDrawable:

package com.example.songbinwang.littledemo.notification;

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;

/**
 * Created by songbinwang on 2017/2/13.
 */

public class ProgressDrawable extends Drawable{

    private Paint mPaint;
    private RectF mRect;
    private int progress = 90;

    public ProgressDrawable(){
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(10);
        mPaint.setColor(Color.YELLOW);
    }

    public void setProgress(int progress) {
        this.progress = progress * 360 / 100;
    }

    @Override
    public void draw(Canvas canvas) {
        float cx = (mRect.right + mRect.left) / 2f;
        float cy = (mRect.top + mRect.bottom) / 2f;
        float radius = Math.min(mRect.width(), mRect.height())/2 -40;
        canvas.drawArc(cx-radius, cy-radius, cx+ radius, cy+ radius, 0, progress, false, mPaint);
    }

    @Override
    public void setBounds(int left, int top, int right, int bottom) {
        super.setBounds(left, top, right, bottom);
        mRect = new RectF(left, top, right, bottom);
    }

    @Override
    public int getIntrinsicWidth() {
        if(mRect != null){
            return (int) mRect.width();
        }
        return 100;
    }

    @Override
    public int getIntrinsicHeight() {
        if(mRect != null){
            return (int) mRect.height();
        }
        return 100;
    }

    @Override
    public void setAlpha(int alpha) {
       mPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        mPaint.setColorFilter(colorFilter);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
}

创建notification(自定义RemoteViews)。

    private Notification createCustom(boolean...b){
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
        Notification n = mBuilder
                .setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL))
                //设置通知栏点击意图
                //  .setNumber(number)
                // 设置通知集合的数量
                .setTicker("测试通知来啦")
                //通知首次出现在通知栏,带上升动画效果的
                .setWhen(System.currentTimeMillis())
                //通知产生的时间,会在通知信息里显示,一般是系统获取到的时间
                .setPriority(Notification.PRIORITY_DEFAULT)
                //设置该通知优先级
                .setAutoCancel(true)
                //设置这个标志当用户单击面板就可以让通知将自动取消
                //.setOngoing(false)
                // ture,设置他为一个正在进行的通知。他们通常是用来表示
                // 一个后台任务,用户积极参与(如播放音乐)或以某种方式正
                // 在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
                .setDefaults(Notification.DEFAULT_VIBRATE)
                //向通知添加声音、闪灯和振动效果的最简单、最一致的方式是
                // 使用当前的用户默认设置,使用defaults属性,可以组合
                //Notification.DEFAULT_ALL  Notification.DEFAULT_SOUND 添加声音
                // requires VIBRATE permission
                .setSmallIcon(R.drawable.ic_launcher)
                //设置通知小ICON
                .build();
        RemoteViews remoteViews = 
                new RemoteViews(this.getPackageName(), R.layout.notification);
        remoteViews.setImageViewResource(R.id.id_icon, R.drawable.aa2);
        remoteViews.setTextViewText(R.id.id_title, "test title");
        remoteViews.setTextViewText(R.id.id_content, "test content");

        if(b == null){
            mBitmap = Bitmap.createBitmap(50, 50, Bitmap.Config.RGB_565);
            drawBitmap(mBitmap);
        }
        remoteViews.setImageViewBitmap(R.id.id_progress, mBitmap);
        n.contentView = remoteViews;
        return n;
    }

更新样式:

    private void updateN(){
        new Thread(){
            private boolean isContinue = true;
            private int progress;
            @Override
            public void run() {
                while(isContinue){
                    if(progress >= 100){
                        isContinue = false;
                    }
                    Message msg = handler.obtainMessage();
                    msg.what = MSG_UPDATE;
                    msg.obj = progress;
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    handler.sendMessage(msg);
                    progress += 5;
                }
            }
        }.start();
    }
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch(msg.what){
                case MSG_UPDATE:
                    int progress = (int) msg.obj;
                    //notifyN(progress);
                    updateProgressDrawable(progress);
                    break;
                case MSG_FINISH:
                    break;
            }
        }
    };

Notification_ID定义了唯一标示符,使用notify后旧通知被取代,起到
更新通知的效果。

    private void updateProgressDrawable(int progress){
        progressDrawable.setProgress(progress);
        int w = dp2px(50);
        int h = dp2px(50);
        Bitmap.Config config = progressDrawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                                 : Bitmap.Config.RGB_565;
        Bitmap bitmap = Bitmap.createBitmap(w, h, config);

        Canvas canvas = new Canvas(bitmap);
        progressDrawable.setBounds(0, 0, w, h);
        progressDrawable.draw(canvas);
        mBitmap = bitmap;

        Notification notification = createCustom(true);
        NotificationManager nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        nManager.notify(Notification_ID, notification);
        mBitmap.recycle();
    }

附上布局文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="64dp">

    <ImageView
        android:id="@+id/id_icon"
        android:padding="6dp"
        android:layout_marginLeft="10dp"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:src="@android:color/holo_blue_bright"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="64dp"
        android:layout_marginLeft="64dp"
        android:layout_marginRight="64dp"
        android:gravity="center_vertical"
        android:paddingLeft="20dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/id_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:textColor="@android:color/black"
            android:text="title"/>

        <TextView
            android:id="@+id/id_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/black"
            android:text="content"/>

    </LinearLayout>

    <ImageView
        android:id="@+id/id_progress"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_gravity="center_vertical|right"/>

</FrameLayout>

开发中可能会碰到的问题:

  • 低版本中的部分方法已经被弃用的
    (1)Notification.Builder(this).getNotification()
    (2)mNotification.setLatestEventInfo(this, “title”, “content”, null);
    这些方法都已经被启用,虽然还有效果,可是不建议使用。所以开发过程中
    尽量使用NotificationCompat.Builder(this)的构建方法去创建一个通知类。

  • 低版本中,自定义的通知栏中如果带有按钮,可能按钮点击事件会失灵
    根据版本号,在低版本都会隐藏掉那些按钮

  • 低版本中mBuilder.setProgress(100, progress, false);没用,不显示进度条
    此方法在4.0及以后版本才有用,如果为早期版本:需要自定义通知布局,其中包含ProgressBar视图

  • 自定义布局的时候,不同版本方法不一样
    2.3之前(包括2.3)
    Notification notify = mBuilder.build();
    notify.contentView = view_custom;
    mNotificationManager.notify(notifyId, notify)
    2.3之后:
    通过Builder以下方法赋于自定义布局。
    mBuilder.setContent(view_custom)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值