关于低版本Android库通知无法设置ChannelID的问题

Android8.0以上启动一个前台服务需要创建一个通知,通知又需要创建一个通道并获取Channel的Id,在用NotificationCompat创建通知时绑定它,这些都属于相对新的特性,旧的包比如v4、v7这些似乎并不生效。

 Notification notification = new NotificationCompat //v7
                .Builder(this,channelId)	  //v4包的构造器可以设置channelId
                .setSmallIcon(R.drawable.icon)
                .setContentTitle("SampleService")
                .setContentText("Service is running...")
                .setOngoing(true)
                .setAutoCancel(false)
//                .setChannel(notificationManager.getNotificationChannel(BuildConfig.APPLICATION_ID).getId())
                .build();

用NotificationCompat创建通知如何设置ChannelId?总之就两种方法,一个是构造时塞入ChannelId,另一种是用setChannel方法。
但实际上在v4或v7包无论哪种方法的最后结果只有一个,那就是Channel为null没有设置进去。
channel为null
为什么会出现这种问题?
V7的NotificationCompat是继承于V4包的,V7没有重写这个方法。
v7的NotificationCompat继承于v4
所以setChannel这个方法是V4包实现的,虽然v4包的setChannel方法很正常,存储到自身的mChannelId字段上,但是mChannelId这个属性是否被成功设置到Notification里了呢?
setChannel方法存在
最终通知创建方法也是在v4包实现的,从代码可见通知是借助IMPL代理创建的。
IMPL代理创建通知
IMPL是如何被创建的?
IMPL创建过程
运行时NotificationCompat会判断系统的编译版本,比如API21对应安卓5,API24对应安卓7,以此类推,看碟下菜,生成对应版本的NotificationCompatApiXXImpl(XX对应系统api版本)。
创建Api26Impl
但是最高支持的版本也就是26,假设手机的版本是26以上,就调用NotificationCompatApi26Impl的工厂方法创建通知,点进Builder方法看一下。
Api26Impl的Builder方法
Api26Impl的工厂构造方法最终仍然会调用Notification自身的Builder类(mB)。
setChannel报红
setChannel方法在AndroidStudio里是报红的,说明这个方法可能不存在,这也是造成mChannelId没有设置到通知的原因。

如果Builder无法正常设置ChannelId,可以写一个方法直接给Notification设置ChannelId。

public static Notification insertChannelRet(Notification notification,String channelId){
    try {
        Field field = Notification.class.getDeclaredField("mChannelId");    //找到mChannelId字段
        field.setAccessible(true);          //设置字段的可见度
        field.set(notification,channelId);  //通过反射将channelId添加到通知上
    } catch (NoSuchFieldException | IllegalAccessException e) {
        e.printStackTrace();
    }

    return notification;
}

在启动前台服务的地方调用 startForeground(1,insertChannelRet(notification,channelId))就可以了。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Android Studio 中创建通知通道(Channel),可以按照以下步骤进行操作: 1. 在 res/values/strings.xml 文件中添加一个字符串资源,用于表示通知通道的名称。 2. 在 AndroidManifest.xml 文件中添加以下权限: ``` <uses-permission android:name="android.permission.VIBRATE" /> ``` 3. 在应用的 MainActivity 中,创建一个方法来创建通知通道: ``` private void createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { CharSequence name = getString(R.string.channel_name); String description = getString(R.string.channel_description); int importance = NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance); channel.setDescription(description); NotificationManager notificationManager = getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } } ``` 4. 在 onCreate 方法中调用该方法: ``` @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); createNotificationChannel(); } ``` 其中,CHANNEL_ID 变量是一个唯一的字符串,用于标识通知通道。在 res/values/strings.xml 文件中添加一个字符串资源来定义该变量的值。 创建通知通道后,就可以使用 NotificationCompat.Builder 创建通知了,将 CHANNEL_ID 作为构造函数的第一个参数即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值