9.2--使用通知

通知(Notification)是Android系统中比较有特色的一个功能,当某个应用程序希望向用户pm发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现。发出一条通知后,手机最上方的状态栏中会显示一个通知的图标,下拉状态栏后可以看到通知的详细内容。Android的通知功能获得了大量用户的认可和喜爱,就连iOS系统也在5.0版本之后加入了类似的功能。

9.2.1 创建通知渠道

然而, 通知这个功的设计初衷是好的,后来却被开发者给玩坏了。

每发出一条通知,都可能意味着自己的应用程序会拥有更高的打开率,因此有太多太多的应用会想尽办法地给用户发送通知,以博取更多的展示机会,站在应用自身的角度来看,这么做或许没有什么错;但是站在用户的角度来看,如果每一个应用程序都这么做的话,那么用户手机的状态栏就会被各样的通知信息堆满,不胜其烦。

虽然Android 系统允许我们将某个应用的通知完全屏蔽,以防止它一直给我们发送垃圾信息,但是在这些信息中,也有可能会有我们所关心的内容。比如说我希望收到某个我所关注的人的微博更新通知,但是却不想让微博一天到晚给我推送一些明星的花边新闻。在过去,用户是没有办法对这些信息做区分的,要么同意接受所有信息,要么屏蔽所有信息,这也是Android 通知功能的痛点。

于是Android8.0 系统引入了通知渠道这个概念。

什么是通知渠道呢?顾名思义,就是每条通知都要属于一个对应的渠道。每个应用程序都可以自由地创建当前应用拥有哪些通知渠道,但是这些通知渠道的控制权是掌握在用户手上的。用户可以自由地选择这些通知渠道的重要程度,是否响铃、是否振动或者是否要关闭这个渠道的通知。

拥有了这些控制权限之后,用户就再也不用害怕那些垃圾通知的打扰了,因为用户可以自主地选择关心那些通知、不关心那些通知。以刚才的场景举例,微博就可以创建两种通知渠道,一个关注,一个推荐。而我作为用户,如果对推荐类的通知不感兴趣,那么我就可以直接将推荐通知渠道关闭,这样既不影响我接收关心的通知,又不会让那些我不关心的通知来打扰我了。

对于每个应用来说,通知渠道的划分是非常考究的,因为通知渠道一旦创建之后就不能再修改了,因此开发者需要仔细分析自己的应用程序一共有哪些类型的通知,然后再去创建相应的通知渠道。这里我们可以参考Twitter的通知渠道划分,如图所示,

可以看到,Twitter 根据自己的通知类型,对通知渠道进行了非常详细的划分。这样用户的自主选择性就比较高了,也就大大降低了用户因不堪其垃圾通知的骚扰而将应用程序写在的概率。

而我们应用如果想要发出通知,也必须创建自己的通知渠道才行,下面我们就来学习一下创建通知渠道的详细步骤。

首先需要一个NotificationManager 对通知进行管理,可以通过调用Context 的 getSystemService() 方法获取。getSystemService() 方法接收一个字符串参数用于确定获取系统的哪个服务,这里我们传入Context.NOTIFACTION_SERVICE 即可。因此,获取NotificationManager 的实例就可以写成:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    }
}

接下来要使用NotificationChannel 类构建一个通知渠道,并调用NotificationManager的createNotificationChannel() 方法完成创建。由于NotificationChannel 类和createNotificationChannel() 方法都是Android8.0 系统中新增的API,因此我们在使用的时候还需要进行版本判断才可以,写法如下:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            val channel = NotificationChannel(channelId,channelName,importance)
            manager.createNotificationChannel(channel)
        }

创建一个通知渠道至少需要渠道ID、渠道名称以及重要等级这3个参数:

其中渠道ID可以随便定义,只要保证全局唯一性就可以;

渠道名称是给用户看的,需要可以清楚地表达这个渠道的用途;

通知的重要等级主要有IMPORTANCE_HIGH、IMPORTANCE_DEFAULT、IMPORTANCE_LOW、IMPORTANCE_MIN这几种,对应的重要程度依次从高到低,不同的重要等级会决定通知的不同行为,当然这里知识初始状态下的重要等级,用户可以随时手动更改某个通知渠道的重要等级,开发者是无法干预的。

 

9.2.2 通知的基本用法

了解了如何创建通知渠道之后,下面我们就来看一下通知的使用方法吧。通知的用法还是比较灵活的,既可以在Activity 里创建,也可以在BroadcastReceiver 里创建,当然还可以在后面我们即将学习的Service里创建。相比于 BroadcastReceiver 和Service ,在Activity 里创建通知的场景还是比较少的,因为一般只有当程序进入后台的时候才需要使用通知。

不过,无论是在哪里创建通知,整体的步骤都是相同的,下面我们就来学习一下创建通知的详细步骤。

首先要使用一个Builder 构造器来创建Notification 对象,问题在于,Android 系统的没一个版本都会对通知功能进行或多或少的修改,API 不稳定的问题在通知上凸显的尤其严重,比方说刚刚介绍的通知渠道功能在Android 8.0 系统之前就是没有的。那么该如何解决这个问题呢?其实解决方案我们之前已经见过好几回了,就是使用AndroidX 库中提供的兼容API。AndroidX 库中提供了一个NotificationCompat 类,使用这个类的构造器创建Notification 对象就可以保证我们的程序在所有Android 系统版本上都能正常工作了,代码如下所示:

        val manager = NotificationCompat.Builder(this,channelId).build()

NotificationCompat.Builder 的构造函数中接收两个参数:

第一个参数是context;

第二个参数是渠道ID,需要和我们创建通知渠道时指定的渠道ID 相匹配才行;

当然,上述代码知识创建了一个空的Notification 对象,并没有什么实际作用,我们可以在最终的build() 方法之前连缀任意多的设置方法来创建一个丰富的Notification 对象,先来看一些基本的设置:

val manager = NotificationCompat.Builder(this,channelId)
            .setContentTitle("This is content Title")
            .setContentText("This is content Text")
            .setSmallIcon(R.drawable.small_icon)
            .setLargeIcon(BitmapFactory.decodeResource(resources,R.drawable.large_icon))
            .build()

上述代码中一共调用了4个设置方法,下面我们来一一解释一下。

setContentTie() 方法用于指定通知的标题内容,下拉系统状态栏就可以看到这部分内容。

setCententText() 方法用于指定通知的正文内容,同样下拉系统状态栏就可以看到这部分内容。

setSmallIcon() 方法用于设置通知的小图标,注意只能使用纯alpha 图层的图片进行设置,小图标会显示在系统状态栏上。

setLargeIcon() 方法用于设置通知的大图标,当下拉系统状态栏时,就可以看到设置的大图标了。

以上工作完成之后,只需要调用NotificationManager 的notify() 方法就可以让通知显示出来了。notify()方法接收两个参数:

第一个参数是id,要保证为每个通知指定的id 都是不相同的;

第二个参数则是Notification 对象,这里直接将我们刚刚创建好的Notification 对象传入即可。因此,显示一个通知就可以写成:

        manager.notify(1,notification)

到这里狙已经把创建通知的每一步骤都分析完了,下面就让我们通过一个具体的例子来看一看通知到底长什么样的。

新建一个NotificationTest 项目,并修改activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/sendNotice"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Send Notice"
        />
</LinearLayout>

布局文件非常简单,里面只有一个Send Notice 按钮,用于发送一条通知。接下来修改MainActivity 中的代码,如下所示:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val manager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            val channel =
                NotificationChannel("normal", "Normal", NotificationManager.IMPORTANCE_DEFAULT)
            manager.createNotificationChannel(channel)
        }

        sendNotice.setOnClickListener {
            val notification = NotificationCompat.Builder(this, "normal")
                .setContentTitle("This is content Title")
                .setContentText("This is content Text")
                .setSmallIcon(R.drawable.small_icon)
                .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.large_icon))
                .build()
            manager.notify(1,notification)
        }
    }
}

可以看到,我们首先获取了NotificationManager 的实例,并创建了一个ID 为normal 通知渠道。创建通知渠道的代码只在第一次执行的时候才会创建,当下次再执行创建代码时,系统就会检测到该通知渠道已经存在了,因此不会重复创建,也并不会影响运行效率。

接下来在“Send Notice” 按钮的点击事件里完成了通知的创建工作,创建的过程正如前面所描述的一样。注意,在NotificationCompat.Builder 的构造函数传入的渠道ID 也必须叫做normal ,如果传入了一个不存在的渠道ID,通知是无法显示出来的。另外,通知上显示的图标你可以使用自己准备的图片。

现在可以来运行一下程序了,其实MainActivity 一旦打开之后,通知渠道就已经创建成功了,我们可以进入应用程序设置当中查看。依次点击设置 →应用和通知 →NotificationTest →通知,可以看到,里面已经出现了一个Normal 通知渠道,就是我们刚刚创建的。

接下来回到NotificationTest 程序中,然后点击 “Send Notice” 按钮 ,你会在系统通知栏的最左边看到一个小图标(就是我们设置的那个小图标),下拉系统栏就可以看到该通知的详细信息。

如果你使用过Android 手机,此时应该会下意识地认为这条通知是可以点击的。但是当你去点击它的时候,会发现没有任何效果。不对啊,每条通知被点击之后都应该有所反应呀。其实要想实现通知的点击效果,我们还需要在代码中进行相应的设置,这就设计了一个新的概念 —— PendingIntent。

PendingIntent从名字上看起来就和Intent有些类似,它们之间也确实存在着不少共同点。比如它们都可以去指明某一个“意图”,都可以用于启动活动、启动服务以及发送广播等。不同的是,Intent更加倾向于去立即执行某个动作,而PendingIntent更加倾向于在某个合适的时机去执行某个动作。所以,也可以把Pendinglntent简单地理解为延迟执行的Intent。

PendingIntent的用法同样很简单,它主要提供了几个静态方法用于获取Pendinglntent的实例,可以根据需求来选择是使用getActivity() 方法、getBroadcast() 方法,还是getService() 方法。这几个方法所接收的参数都是相同的,

第一个参数依旧是Context,不用多做解释。

第二个参数一般用不到,通常都是传入0即可。

第三个参数是一个Intent对象,我们可以通过这个对象构建出PendingIntent的“意图”。

第四个参数用于确定PendingIntent的行为,有 FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT 和FLAG_UPDATE_CURRENT这4种值可选,每种值的具体含义你可以查看文档,通常情况下这个参数传入0就可以了。

  • FLAG_ONE_SHOT
    当前描述的PendingIntent只能被使用一次,然后它就会被自动cancel,如果后续还有相同的PendingIntent,那么它们的send方法就会调用失败。对于通知栏消息来说,如果用此标记位,那么同类的通知也只能使用一次,后续的通知单机后将无法打开。

  • FLAG_NO_CREATE
    当前描述的PendingIntent不会主动创建,如果当前PendingIntent之前不存在,那么getActivitygetServicegetBroadcast方法会直接返回null,即获取PendingIntent失败。这个标记位很少见,它无法单独使用,因此在日常开发中它并没有太多的使用意义

  • FLAG_CANCEL_CURRENT
    当前描述的PendingIntent如果已经存在,那么它们都会被cancle,然后系统会创建一个新的PendingIntent。对于通知栏消息来说,那么被cancel的消息单击后将无法打开。

  • FLAG_UPDATE_CURRENT
    当前描述的PendingIntent如果已经存在,那么它们都会被更新,即它们的Intent中的Extras会被替换成最新的。

对PendingIntent有了一定的了解后,我们再回过头来看一下NotificationCompat.Builder。这个构造器还可以再连缀一个setContentIntent() 方法,接收的参数正是一个PendingIntent对象。因此,这里就可以通过PendingIntent构建出一个延迟执行的“意图”,当用户点击这条通知时就会执行相应的逻辑。

现在我们来优化一下NotificationTest项目,给刚才的通知加上点击功能,让用户点击它的时候可以启动另一个活动。

首先需要准备好另一个活动,右击com.example.notificationtest包→New→Activity→Empty Activity,新建 NotificationActivity,布局起名为notification_layout。然后修改 notification_layout.xml中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".NotificationActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="24sp"
        android:text="This is notification layout"
        />

</LinearLayout>

这样就把NotificationActivity这个活动准备好了,下面我们修改MainActivity中的代码,给通知加入点击功能,如下所示:

  sendNotice.setOnClickListener {
            val intent = Intent(this,NotificationActivity::class.java)
            val pi = PendingIntent.getActivity(this,0,intent,0)
            val notification = NotificationCompat.Builder(this, "normal")
                .setContentTitle("This is content Title")
                .setContentText("This is content Text")
                .setSmallIcon(R.drawable.small_icon)
                .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.large_icon))
                .setContentIntent(pi)    
                .build()
            manager.notify(1,notification)
        }

可以看到,这里先是使用Intent表达出我们想要启动NotificationActivity的“意图”,然后将构建好的Intent 对象传入到Pendinglntent的getActivity()方法里,以得到Pendinglntent的实例,接着在NotificationCompat.Builder中调用setContentIntent()方法,把它作为参数传入即可。

现在重新运行一下程序,并点击 Send Notice按钮,依旧会发出一条通知。然后下拉系统状态栏,点击一下该通知,就会看到NotificationActivity这个活动的界面了。

咦?怎么系统状态上的通知图标还没有消失呢?是这样的,如果我们没有在代码中对该通知进行取消,它就会一直显示在系统的状态栏上。解决的方法有两种,一种是在NotificationCompat.Builder 中再连缀一个setAutocancel()方法,一种是显式地调用NotificationManager的cancel()方法将它取消,两种方法我们都学习一下。

第一种方法写法如下:

sendNotice.setOnClickListener {
            val intent = Intent(this,NotificationActivity::class.java)
            val pi = PendingIntent.getActivity(this,0,intent,0)
            val notification = NotificationCompat.Builder(this, "normal")
                .setContentTitle("This is content Title")
                .setContentText("This is content Text")
                .setSmallIcon(R.drawable.small_icon)
                .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.large_icon))
                .setContentIntent(pi)
                .setAutoCancel(true)    
                .build()
            manager.notify(1,notification)
        }

可以看到,setAutoCancel()方法传入true,就表示当点击了这个通知的时候,通知会自动取消掉。

第二种方法写法如下:

        val manager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        manager.cancel(1)

这里我们在cancel() 方法中传入了1,这个1是什么意思呢?还记得在创建通知的时候给每条通知指定的id吗?当时我们给这条通知设置的id就是1。因此,如果你想取消哪条通知,在cancel()方法中传人该通知的id就行了。

 

9.2.3 通知的进阶技巧

现在你已经掌握了创建和取消通知的方法,并且知道了如何去响应通知的点击事件。不过通知的用法并不仅仅是这些呢,下面我们就来探究一下通知的更多技巧。

上一小节中创建的通知属于最基本的通知,实际上,NotificationCompat.Builder中提供了非常丰富的API来让我们创建出更加多样的通知效果。当然,每一个API都详细地讲一遍不太可能,我们只能从中选一些比较常用的API来进行学习。

先来看看setStyle() 方法,这个方法允许我们构建出富文本的通知内容。也就是说,通知中不光可以有文字和图标,还可以包含更多的东西。setStyle() 方法接收一个NotificationCompat.Style 参数,这个参数就是用来构建具体的富文本信息的,如长文字、图片等。

在开始使用setStyle() 方法之前,我们先来做一个试验吧,之前的通知内容都比较短,如果设置成很长的文字会是什么效果呢?比如这样写:

 val notification = NotificationCompat.Builder(this, "normal")
                .setContentTitle("This is content Title")
                .setContentText("Learn how to build notifications, send and sync data, " +
                        "and use voice actions. Get the official Android IDE and developer tools" +
                        " to build apps for Android.")
                .setSmallIcon(R.drawable.small_icon)
                .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.large_icon))
                .setContentIntent(pi)
                .setAutoCancel(true)
                .build()

现在重新运行程序并触发通知,就会发现,文字超出的部分被... 三个点省略了。。

可以看到,通知内容是无法显示完整的,多余的部分会用省略号来代替。其实这也很正常,因为通知的内容本来就应该言简意赅,详细内容放到点击后打开的活动当中会更加合适。

但是如果你真的非常需要在通知当中显示一段长文字,Android也是支持的,通过 setStyle() 方法就可以做到,具体写法如下:

val notification = NotificationCompat.Builder(this, "normal")
                .setContentTitle("This is content Title")
                .setStyle(NotificationCompat.BigTextStyle().bigText("Learn how to build notifications, " +
                    "send and sync data, " +
                    "and use voice actions. Get the official Android IDE and developer tools" +
                    " to build apps for Android."))
                .setSmallIcon(R.drawable.small_icon)
                .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.large_icon))
                .setContentIntent(pi)
                .setAutoCancel(true)
                .build()

我们在setStyle() 方法中创建了一个NotificationCompat.BigTextStyle对象,这个对象就是用于封装长文字信息的,我们调用它的bigText() 方法并将文字内容传人就可以了。

再次重新运行程序并触发通知,就可以显示全部文字了。

除了显示长文字之外,通知里还可以显示一张大图片,具体用法也是基本相似的:

val notification = NotificationCompat.Builder(this, "normal")
                .setContentTitle("This is content Title")
                .setStyle(NotificationCompat.BigTextStyle().bigText("Learn how to build notifications, " +
                    "send and sync data, " +
                    "and use voice actions. Get the official Android IDE and developer tools" +
                    " to build apps for Android."))
                .setStyle(NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(resources,R.drawable.big_image)))
                .setSmallIcon(R.drawable.small_icon)
                .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.large_icon))
                .setContentIntent(pi)
                .setAutoCancel(true)
                .build()

可以看到,这里仍然是调用的setstyle()方法,这次我们在参数中创建了一个NotificationCompat.BigPictureStyle对象,这个对象就是用于设置大图片的,然后调用它的bigPicture()方法并将图片传入。这里我事先准备好了一张图片,通过BitmapFactory的decodeResource()方法将图片解析成Bitmap对象,再传入到bigPicture()方法中就可以了。

现在重新运行一下程序并触发通知,就可以看到我们的图片了。

这样我们就把 setStyle()方法中的重要内容基本都掌握了。

 

接下来,我们学习一下不同重要等级的通知渠道对通知的行为具体有什么影响。其实简单来讲,就是通知渠道的重要等级越高,发出的通知就越容易获得用户的注意。比如高重要等级的通知渠道发出的通知可以弹出横幅、发出声音,而低重要等级的通知渠道发出的通知不仅可能会在某些情况下被隐藏,而且可能会被改变现实的顺序,将其排在更重要的通知之后。

但需要注意的是,开发者只能在创建通知渠道的时候为它指定初始的重要等级,如果用户不认可这个重要等级的话,可以随时进行修改,开发者对此无权再进行调整和变更,因为通知渠道一旦创建就不能再通过代码改变了。

既然无法修改之前创建的通知渠道,那么我们就只好再创建一个新的通知渠道来测试了。修改MainActivity 中的代码,如下所示:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val manager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            val channel1 =
                NotificationChannel("normal", "Normal", NotificationManager.IMPORTANCE_DEFAULT)
            val channel2 =
                NotificationChannel("important", "Important", NotificationManager.IMPORTANCE_HIGH)
            manager.createNotificationChannel(channel2)
        }
        sendNotice.setOnClickListener {
            val intent = Intent(this,NotificationActivity::class.java)
            val pi = PendingIntent.getActivity(this,0,intent,0)
            val notification = NotificationCompat.Builder(this, "important")
                .setContentTitle("This is content Title")
                .setStyle(NotificationCompat.BigTextStyle().bigText("Learn how to build notifications, " +
                    "send and sync data, " +
                    "and use voice actions. Get the official Android IDE and developer tools" +
                    " to build apps for Android."))
                .setStyle(NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(resources,R.drawable.big_image)))
                .setSmallIcon(R.drawable.small_icon)
                .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.large_icon))
                .setContentIntent(pi)
                .setAutoCancel(true)
                .build()
            manager.notify(2,notification)
        }
    }
}

这里我们将通知渠道的重要等级设置成了“高”,表示这是一条非常重要的通知,要求用户必须立即看到。现在重新运行一下程序,并点击“Send Notice”按钮,可以看到,这次的通知不是在系统状态栏显示一个小图标了,而是弹出了一个横幅,并附带了通知的详细内容,表示这是一条非常重要的通知。不管用户现在是在玩游戏还是看电影,这条通知都会显示在最上方,以此引起用户的注意。当然,使用这类通知时一定要小心,确保你的通知内容的确是至关重要的,不然如果让用户产生反感的话,很可能会导致我们的应用程序被卸载。

接下来再学习一下setPriority()方法,它可以用于设置通知的重要程度。setPriority()方法接收一个整型参数用于设置这条通知的重要程度,一共有5个常量值可选:

PRIORITY_DEFAULT表示默认的重要程度,和不设置效果是一样的;

PRIORITYMIN表示最低的重要程度,系统可能只会在特定的场景才显示这条通知,比如用户下拉状态栏的时候;

PRIORITYLOW表示较低的重要程度,系统可能会将这类通知缩小,或改变其显示的顺序,将其排在更重要的通知之后;

PRIORITY_HIGH表示较高的重要程度,系统可能会将这类通知放大,或改变其显示的顺序,将其排在比较靠前的位置;

PRIORITY_MAX表示最高的重要程度,这类通知消息必须要让用户立刻看到,甚至需要用户做出响应操作。具体写法如下:

 

val notification = NotificationCompat.Builder(this, "important")
                .setContentTitle("This is content Title")
                .setStyle(NotificationCompat.BigTextStyle().bigText("Learn how to build notifications, " +
                    "send and sync data, " +
                    "and use voice actions. Get the official Android IDE and developer tools" +
                    " to build apps for Android."))
                .setStyle(NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(resources,R.drawable.big_image)))
                .setSmallIcon(R.drawable.small_icon)
                .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.large_icon))
                .setContentIntent(pi)
                .setPriority(NotificationManager.IMPORTANCE_HIGH) // 通知等级
                .setAutoCancel(true)
                .build()
            manager.notify(

和上面那个渠道的显示是相同的,这么设置是为了兼容没有渠道的版本。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值