Android消息通知栏

日常生活中,相信很多人都会有这样的经历,每天手机都会收到一些来自不同来源app的一些消息,显示与状态栏,下拉即可查看,甚至可以点击进行调转到相应app界面,
鉴于这样的功能和效果非常常见,也非常适合推送用于显示,所以有必要对这个知识总结一下。实现起来其实也不复杂,联系实际生活,我们需要发布一个通知,首先需要发布者然后就是发布的内容,
跟Android中的api结合起来,通知消息的发布者就是 NotificationManager和 通知消息Notification .
NotificationManager : 是状态栏通知的管理类,负责发通知、清楚通知等。
Notification:状态栏通知对象,可以设置icon、文字、提示声音、振动等等参数。
通常发布一个通知包含四个步骤:
1.获取 NotificationManager 实例管理通知;
2.实例 Notification 对象; 创建一个消息对象
3.发送通知。
4.管理事件 Intent(额外)

—1.创建消息管理其

 //创建一个通知管理器
        NotificationManager   notificationManager= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

—2.获取Notification实例 获取Notification实例有很多方法处理 在此我只展示通用的方法(虽然这种方式是属于api16以上,但是已经可以了,毕竟16以下的Android机很少了。如果非要全面兼容可以用)

 Notification  notification = new Notification.Builder(context)
            .setContentTitle("标题")
            .setContentText("内容")
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.mipmap.ic_small)
            .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.icon_notify))
            .build();

如果非要全面兼容可以用,可以用以下代码

Notification notification=new NotificationCompat.Builder(context)
                .setContentTitle("标题")
                .setContentText("内容")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_small)
                .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.icon_notify))
                .build();

—3. 发送通知

 int  notifiId=1;
notificationManager.notify(notifiId,notification);

以上代码非常简单,但是其实已经可以实现了消息通知栏了。可能有人不相信,拿我这里就贴图为证。
下图为状态栏显示结果:
Android消息通知栏_第1张图片
下图为下拉之后的结果:
Android消息通知栏_第2张图片

既然已经实现了消息通知栏,接着我们继续探究,以上结果是我运行在4.4系统上的结果,下面我相继对5.x系统,6.0系统,7.x系统分别做出测试。
5.1系统运行结果如下:
状态栏显示结果:
Android消息通知栏_第3张图片

下拉后显示结果:
Android消息通知栏_第4张图片

通过上图我们会发现在5.0手机上消息通知未下拉之前图标显示为白色,这个时候就很奇怪啦,明明设置了小图标,为什么会显示白色?经过查阅相关资料,是因为我们的图片资源的原因,我们小图标一定要是透明状态的.png格式图片,否则在状态栏显示成白色或者灰色。于是我就去找了一张透明背景的png图片,5.1运行结果如下;
Android消息通知栏_第5张图片

Android消息通知栏_第6张图片

此处我为了显示区别,设置小图标和大图标是两个不同的图片(正常情况下,我们应该要UI做两张不同大小的logo图片,分别用来显示状态栏图标和下拉之后的大图标),我们可以发现在大图片右下角有会自动多一个灰色背景的小图标,其实为了看着更和谐我们是可以设置右下角圆圈的背景色的。

Notification notification=new NotificationCompat.Builder(context)
                .setContentTitle("通知栏标题")
                .setContentText("这是消息通过通知栏的内容")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.drawable.ic_small)
                .setColor(Color.parseColor("#8161F6"))
                .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.icon_notify))
                .build();

运行再看拉下之后的结果:
Android消息通知栏_第7张图片
是不是现在已经很好看啦。
6.0运行结果跟5.x类似,只需要注意的就是小图标一定要透明背景的png格式图片,大图标没有要求,下拉之后圆圈部分背景色直接设置跟大图标整体颜色相近即可。
接着在7.0手机上运行,跟之前的结果又会有点差别,这个差别是在从通知栏拉下来显示之后如下图:
Android消息通知栏_第8张图片
这个其实就是我们的app_name,就是我们在清单文件中配置的app_name.

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".activity.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            intent-filter>
        activity>
        <activity android:name=".activity.WebViewActivity" />
        <activity android:name=".activity.StatusBarActivity" />
        <activity android:name=".activity.NotificationActivity">activity>
    application>

到此可以说5.0至7.x的配置基本完成,再次总结一下,我们需要注意一下几个地方:
1.对于5.0以上的手机设置的小图标要求必须是透明背景的.png格式图片,大图标无要求 2.消息通知从状态栏下拉之后,大图标的右下角的圆圈部分是可以更改背景色的,我们可以将其设置成跟大图标本体色相近的颜色看着会比较和谐
3.对于7.0手机,从状态栏下拉之后,标题上方显示的是app_name是可以通过清单文件进行更改的。
接着就剩下8.0的适配,我们还是重新运行下以上代码,结果非常令人困扰,居然报错,报什么错列,请看下图:
Android消息通知栏_第9张图片

错误原因其实就是:消息发布的时候 我们的通道是空的,经过相关资料查阅,发现8.0以上系统有一个消息通道的概念,在需要发布消息通知之前必须需要一个消息通道。接下来创建消息通道

 if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
            //创建 通知通道  channelid和channelname是必须的(自己命名就好)
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
            channel.enableLights(true);//是否在桌面icon右上角展示小红点
            channel.setLightColor(Color.GREEN);//小红点颜色
            channel.setShowBadge(false); //是否在久按桌面图标时显示此渠道的通知
        }

通道对象创建之后,紧接着我们发送消息之前就必须先创建通道,即征对于8.0以上手机在发布消息前先创建好通道,代码如下:

//发送通知
        int  notifiId=1;
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
           notificationManager.createNotificationChannel(channel);
        }
        notificationManager.notify(notifiId,notification);

重写运行,我们发现仍然会提示之前的错误,之所以出现这个错误,其实是因为8.0以上手机要求,在构建消息对象时需要传入我们的通道渠道ID,所以我们构造消息对象的方法需要改变一下,代码如下:

Notification notification;
        //获取Notification实例   获取Notification实例有很多方法处理    在此我只展示通用的方法(虽然这种方式是属于api16以上,但是已经可以了,毕竟16以下的Android机很少了,如果非要全面兼容可以用)
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
            //向上兼容 用Notification.Builder构造notification对象
            notification = new Notification.Builder(context,CHANNEL_ID)
                    .setContentTitle("通知栏标题")
                    .setContentText("这是消息通过通知栏的内容")
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.drawable.ic_small)
                    .setColor(Color.parseColor("#FEDA26"))
                    .setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_cpu))
                    .setTicker("巴士门")
                    .build();
        }else {
            //向下兼容 用NotificationCompat.Builder构造notification对象
            notification = new NotificationCompat.Builder(context)
                    .setContentTitle("通知栏标题")
                    .setContentText("这是消息通过通知栏的内容")
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.drawable.ic_small)
                    .setColor(Color.parseColor("#FEDA26"))
                    .setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_cpu))
                    .setTicker("巴士门")
                    .build();
        }

其实就是在构造时多传一个通道ID;
到此我们的8.0适配也结束啦。
为了方便大家查看,我把自己写的demo也在此贴出来

public class NotificationHelper {
    private static final String CHANNEL_ID="channel_id";   //通道渠道id
    public static final String  CHANEL_NAME="chanel_name"; //通道渠道名称


    @TargetApi(Build.VERSION_CODES.O)
    public static  void  show(Context context){
        NotificationChannel channel = null;
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
            //创建 通知通道  channelid和channelname是必须的(自己命名就好)
            channel = new NotificationChannel(CHANNEL_ID, CHANEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
            channel.enableLights(true);//是否在桌面icon右上角展示小红点
            channel.setLightColor(Color.GREEN);//小红点颜色
            channel.setShowBadge(false); //是否在久按桌面图标时显示此渠道的通知
        }
         Notification notification;
        //获取Notification实例   获取Notification实例有很多方法处理    在此我只展示通用的方法(虽然这种方式是属于api16以上,但是已经可以了,毕竟16以下的Android机很少了,如果非要全面兼容可以用)
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
            //向上兼容 用Notification.Builder构造notification对象
            notification = new Notification.Builder(context,CHANNEL_ID)
                    .setContentTitle("通知栏标题")
                    .setContentText("这是消息通过通知栏的内容")
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.drawable.ic_small)
                    .setColor(Color.parseColor("#FEDA26"))
                    .setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_cpu))
                    .setTicker("巴士门")
                    .build();
        }else {
            //向下兼容 用NotificationCompat.Builder构造notification对象
            notification = new NotificationCompat.Builder(context)
                    .setContentTitle("通知栏标题")
                    .setContentText("这是消息通过通知栏的内容")
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.drawable.ic_small)
                    .setColor(Color.parseColor("#FEDA26"))
                    .setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_cpu))
                    .setTicker("巴士门")
                    .build();
        }


        //发送通知
        int  notifiId=1;
        //创建一个通知管理器
        NotificationManager   notificationManager= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
           notificationManager.createNotificationChannel(channel);
        }
        notificationManager.notify(notifiId,notification);

    }

}

你可能感兴趣的:(Android基础)