当前位置:   article > 正文

Android Notification 通知的使用,不同版本兼容问题_decoratedcustomviewstyle

decoratedcustomviewstyle

Notification可以让我们在获取消息的时候,在状态栏、锁屏界面来显示相应的信息。由于不同厂商对Notification做了深度定制,导致部分属性设置了没有效果;而且随着Android 版本的不断升级,不得不去解决Notification的兼容问题。

由于目前市场上手机的系统版本基本都在Android4.4以上,所以Android4.4之前版本就不需要考虑了。

参考文章:https://www.jianshu.com/p/cb8426620e74

一、Notification的创建
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//Android4.1+ 谷歌推出了Notification.Builder(建造者模式)方式创建通知
//Notification.Builder builder = new Notification.Builder(this);
//Google后来推出了NotificationCompat.Builder方式,为各种配置做兼容性处理,不过一个参数的方法已过时,
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default");
builder.setSmallIcon(R.drawable.user);
manager.notify(1,builder.build());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这种builder只带一个参数的创建方式,提示已经过时,原因是升级到Android O 版本后,该方法被以下方法取代

NotificationCompat.Builder(Context context, String channelId)
  • 1

即新增一个String参数即可,channelId的作用是将notification进行分类。

二、介绍3种Notification

1、普通Notification

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default");
Intent normalIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.baidu.com/"));
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,normalIntent,0);
builder.setContentIntent(pendingIntent);
builder.setSmallIcon(R.drawable.small_icon);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.big_icon));
builder.setAutoCancel(true);
builder.setContentTitle("普通通知标题");
builder.setContentInfo("这是一条通知信息,请查收");
builder.setContentText("这是一条通知文本,请阅读");
manager.notify(1,builder.build());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2、折叠式Notification

这是一种自定义视图的Notification,用来显示长文本和一些自定义的布局场景。它有两种状态:一种是普通状态下的视图,一种是展开状态下的视图。和普通Notification不同的是,我们需要自定义视图,而这个视图显示的进程和我们创建视图的进程不在一个进程,所以需要使用RemoteViews。

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "fold");
Intent mIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.baidu.com/"));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, mIntent, 0);
builder.setContentIntent(pendingIntent);
builder.setSmallIcon(R.drawable.small_icon);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.big_icon));
builder.setAutoCancel(true);
builder.setContentTitle("折叠式通知标题");
builder.setContentInfo("这是一条通知信息,请查收");
builder.setContentText("这是一条通知文本,请阅读");
Notification notification = builder.build();
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.view_fold);
notification.contentView = remoteViews;
notification.bigContentView = remoteViews;
manager.notify(2, builder.build());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3、悬挂式Notification
这是Android5.0新增的方式。和前两种显示不同的是,前两种需要下拉通知栏才能看到通知,而悬挂式Notification不需要下拉通知栏就直接显示出来悬挂在屏幕上坟,并且焦点不变,仍在用户操作的界面,因此不会打断用户的操作,过几秒就会消失。它需要调用setFullScreenIntent来将Notification变为悬挂式。

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "hang");
Intent hangIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.baidu.com/"));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, hangIntent, 0);
builder.setContentIntent(pendingIntent);
builder.setSmallIcon(R.drawable.small_icon);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.big_icon));
builder.setAutoCancel(true);
builder.setContentTitle("悬挂式通知标题");
builder.setContentInfo("这是一条通知信息,请查收");
builder.setContentText("这是一条通知文本,请阅读");
//设置跳转
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(this, MyNotificationActivity.class);
PendingIntent hangPendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
builder.setFullScreenIntent(hangPendingIntent, true);
manager.notify(3, builder.build());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

三种通知在Android低版本上会有区别,但在Android9.0系统上测试都是以悬挂式展示的。

三、版本兼容问题

1、Android4.1之前的版本,创建Notification方式

Notification notification = new Notification();
  • 1

2、Android5.0+的版本,创建Notification方式

Notification notification = new Notification.Builder(mContext).build();
  • 1

3、Android6.0开始,创建Notification方式

Notification notification = new NotificationCompat.Builder(mContext).build();
  • 1

4、Android8.0开始,创建Notification方式,需要制定channel属性

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel("channel_id", "notice", NotificationManager.IMPORTANCE_HIGH);
manager.createNotificationChannel(channel);
 NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id");
 //如果是通过new Notification.Builder(this)创建Notification,需要通过 .setChannelId("channel_id")属性设置channel
  • 1
  • 2
  • 3
  • 4
  • 5
四、属性介绍

1、setSmallIcon设置小图标

setSmallIcon必须设置,否则通知不会显示
  • 1

2、setContentTitle设置通知标题

3、setContentText设置通知内容

4、setContentIntent 点击通知要跳转的意图,需要用到PendingIntent

5、setAutoCancel 点击通知时是否自动消失,需要重点注意的是,setAutoCancel需要和setContentIntent一起使用,否则无效。

6、setDeleteIntent 左滑或者右滑通知时,删除通知。
一般有两种消失的行为:第一种是点击消失,第二种是滑动消失,可以通过广播监听这两种事件。

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = neNotificationCompat.Builder(this,"delete")
Intent clickIntent = neIntent(this,NotificationBroadcastReceiver.class);
clickIntent.setAction("com.example.click");
PendingIntent clickPI PendingIntent.getBroadcast(this,1,clickIntent,PendingIntent.FLACANCEL_CURRENT)
Intent cancelIntent = neIntent(this,NotificationBroadcastReceiver.class);
cancelIntent.setAction("com.example.cancel");
PendingIntent cancelPI PendingIntent.getBroadcast(this,2,cancelIntent,PendingIntent.FL_CANCEL_CURRENT)
builder.setSmallIcon(R.drawable.small_icon)
        .tContentTitle("我是通知的标题")//设置通知标题
        .setContentText("我是一个通知")//设置通知内容
        .setContentIntent(clickPI)/设置pendingIntent,点击通知时就会用到
        .setAutoCancel(true)//设为true,点击通知栏移除通知
        .setDeleteIntent(cancelPI);//设置pendingIntent,左滑右知时就会用到

manager.notify(0,builder.build());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

//广播接收的类

public class NotificationBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (TextUtils.isEmpty(action)){
            return;
        }
        if (action.equals("com.example.click")){
            System.out.println("click");
        }
        if (action.equals("com.example.cancel")){
            System.out.println("cancel");
        }

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

注册广播

<receiver android:name=".notification.NotificationBroadcastReceiver">
    <intent-filter>
        <action android:name="com.example.click"/>
        <action android:name="com.example.cancel"/>
    </intent-filter>
</receiver>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

7、setLargeIcon 设置大图标

8、setNumber 显示在右边的数字 部分机型没有效果

9、setOngoing 是否是正在进行中的通知,默认是false,如果设置成true,左右滑动的时候就不会被删除了

10、setOnlyAlertOnce 设置是否只通知一次,默认值是false,如果设置成true,则只会通知一次。

11、setProgress 为通知设置设置一个进度条

setProgress(int max, int progress, boolean indeterminate)
max:最大值
progress:当前进度
indeterminate:进度是否确定
  • 1
  • 2
  • 3
  • 4

12、setStyle 为通知设置样式

1)BigPictureStyle 下拉通知完全展开时,会显示大图

NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle();
bigPictureStyle.bigPicture(BitmapFactory.decodeResource(getResoces(),R.drawable.loop));
bigPictureStyle.setBigContentTitle("大图标题");
bigPictureStyle.setSummaryText("这是大图样式内容"

//然后设置样式
builder.setStyle(bigPictureStyle);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2)BigTextStyle 感觉跟普通通知字体没什么区别

NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
bigTextStyle.setBigContentTitle("标题");
bigTextStyle.setSummaryText("这是简要内容");
bigTextStyle.bigText("这是文本内容!!!");
 
//然后设置样式       
builder.setStyle(bigTextStyle);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3)DecoratedCustomViewStyle 功能是自定义通知布局

RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.view_fold);
builder.setCustomContentView(remoteViews);
//setCustomContentView也可以用下面两个替换
//setCustomBigContentView(remoteViews)//设置通知的布局
//setCustomHeadsUpContentView(remoteViews);//设置悬挂通知的布局
  • 1
  • 2
  • 3
  • 4
  • 5

setSmallIcon的属性还是要设置的,不然接收不到通知

4)InboxStyle 添加行

NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.addLine("第一行");
inboxStyle.addLine("第二行");
inboxStyle.addLine("第三行");
inboxStyle.addLine("第四行");
inboxStyle.addLine("第五行");
inboxStyle.addLine("第六行");
inboxStyle.addLine("第七行");
inboxStyle.addLine("第八行");
inboxStyle.addLine("第九行");
inboxStyle.setBigContentTitle("大标题");
inboxStyle.setSummaryText("内容");
 
//然后设置样式
 builder.setStyle(inboxStyle);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

5)MessagingStyle

NotificationCompat.MessagingStyle messagingStyle = new NotificationCompat.MessagingStyle("aaa");
NotificationCompat.MessagingStyle.Message message = new NotificationCompat.MessagingStyle.Message("测试",System.currentTimeMillis(),"发送人");
messagingStyle.addMessage(message);
messagingStyle.setConversationTitle("message标题");
  • 1
  • 2
  • 3
  • 4

13、setDefaults
向通知添加声音、闪灯和震动效果,最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,如果没有设置这个属性通知可能没有声音。

setDefaults(Notification.DEFAULT_ALL);

Notification.DEFAULT_VISIBLE //添加默认震动提醒 需要VIBRATE permission
Notification.DEFAULT_SOUND //添加默认声音提醒
Notification.DEFAULT_LIGHTS //添加默认三色灯提醒 有的机型可能不支持
Notification.DEFAULT_ALL //添加默认以上三种全部提醒
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

14、setVibrate 设置使用震动模式

setVibrate(new long[]{3000,1000,500,700,500,300});//延迟3秒,然后震动1000ms,再延迟500ms,接着震动700ms,最后再延迟500ms,接着震动300ms
  • 1

如果setDefaults的属性设置的是Notification.DEFAULT_ALL或者Notification.DEFAULT_VISIBLE,setVibrate将无效,因为Notification.DEFAULT_ALL或者Notification.DEFAULT_VISIBLE会替代setVibrate。

15、setSubText
在通知上新增一行文本,使原本两行文本变成三行文本

16、setTicker 设置通知在第一次到达时在状态栏中显示的文本
有的机型不生效,用的华为Android4.4.2版本可以生效,Android9.0版本是以悬挂式通知显示的,也不会有效果

17、setUsesChronometer 设置是否显示时间计时,电话通知就会使用到。true 会计时 false 不会计时

18、setWhen 通知产生的时间,会在通知栏信息里显示,一般是系统获取到的时间
如果没有设置,默认是当前时间戳。

19、setShowWhen 设置是否显示当前时间 如果已经设置了setUsesChronometer(true),则当前时间就显示不了。

20、setExtras 为通知设置数据,在Android4.4新增了设置数据的入口。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){//Android4.4以上
    Bundle bundle = new Bundle();
    builder.setExtras(bundle);
}
  • 1
  • 2
  • 3
  • 4

21、setGroup 通知分组,即在同一个应用程序下,如果超过4条通知,会自动把通知进行分组。主要体现在Android7.0以上的手机。

22、setGroupSummary 如果设为false,结合setGroup使用,会取消分组

23、setColor 设置通知栏颜色(Android5.0新增),测试部分机型没有效果,用Android9.0的系统只是把通知的图标改变了颜色。

24、setCategory 设置通知类别

//通知类别
public static final String CATEGORY_CALL = "call";
public static final String CATEGORY_MESSAGE = "msg";
public static final String CATEGORY_EMAIL = "email";
public static final String CATEGORY_EVENT = "event";
public static final String CATEGORY_PROMO = "promo";
public static final String CATEGORY_ALARM = "alarm";
public static final String CATEGORY_PROGRESS = "progress";
public static final String CATEGORY_SOCIAL = "social";
public static final String CATEGORY_ERROR = "err";
public static final String CATEGORY_TRANSPORT = "transport";
public static final String CATEGORY_SYSTEM = "sys";
public static final String CATEGORY_SERVICE = "service";
public static final String CATEGORY_REMINDER = "reminder";
public static final String CATEGORY_RECOMMENDATION = "recommendation";
public static final String CATEGORY_STATUS = "status";
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

25、setPublicVersion 设置安全锁屏下的通知

Android4.4.2的设备没有添加builder.setVisibility(Notification.VISIBILITY_PUBLIC);锁屏状态下也可以收到通知

26、setVisibility 设置通知的显示等级

//Android5.0之后新增
VISIBILITY_PUBLIC 任何情况都会显示通知
VISIBILITY_PRIVATE 只有在没有锁屏时会显示通知 
VISIBILITY_SECRET 在安全锁和没有锁屏的情况下显示通知
  • 1
  • 2
  • 3
  • 4

27、addAction 添加内联回复的通知。支持Android7.0以上的手机

实现方式

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel("reply", "name", NotificationManager.IMPORTANCE_HIGH);
        manager.createNotificationChannel(channel);
    }
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "reply");
    builder.setSmallIcon(R.drawable.small_icon);
    Intent intent = new Intent(this,NotificationBroadcastReceiver.class);
    intent.setAction("com.example.reply");
    intent.putExtra("messageId", 1);
    
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    builder.setRemoteInputHistory(new String[]{"这条通知可以点击下面按钮直接回复"});
    RemoteInput input = new RemoteInput.Builder("key_text_reply")
            .setLabel("回复")
            .build();
    NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.small_icon,"点击直接回复",pendingIntent)
            .addRemoteInput(input)
            .build();
    builder.addAction(action);

    manager.notify(6, builder.build());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在内联输入框中输入想要回复的文字,点击发送之后会收到一个广播,广播的处理如下:

int messageId = intent.getIntExtra("messageId", 0);
        Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
        if (remoteInput != null) {
            NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            CharSequence message = remoteInput.getCharSequence("key_text_reply");
            NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "6");
            builder.setSmallIcon(R.drawable.small_icon)
                    .setContentTitle("内联回复")//设置通知标题
                    .setContentText(message)//设置通知内容
                    .setAutoCancel(true);//设为true,点击通知栏移除通知


            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//Android 8.0以上
                String channelID = "6";
                String channelName = "通知测试";
                NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_DEFAULT );
                manager.createNotificationChannel(channel);
                //创建通知时指定channelID
                builder.setChannelId(channelID);
            }
            Notification notification = builder.build();
            manager.notify(messageId, notification);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

28、setSound 设置铃声

setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.publicnotify))
  • 1

29、设置呼吸灯

setLights(Color.RED,2000,Color.BLUE)
  • 1

参数依次是:灯光颜色,亮持续时间,暗的时间,不是所有颜色都可以,这跟设备有关,有些手机还不带三色灯;另外,还需要为Notification设置flags为Notification.FLAG_SHOW_LIGHTS才支持三色灯提醒!

30、setBadgeIconType 设置角标样式

Notification.BADGE_ICON_LARGE
Notification.BADGE_ICON_SMALL
Notification.BADGE_ICON_NONE
  • 1
  • 2
  • 3

由于Android手机品牌众多,角标兼容问题也越来越多,需要做各种机型的适配。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/228061
推荐阅读
相关标签
  

闽ICP备14008679号