Android通知——Notification

    .addAction(android.R.drawable.ic_media_next, "Next", pendingIntentNext)

    .addAction(android.R.drawable.ic_media_play, "Play", pendingIntentPlay)

    .setLargeIcon(bitmap)

    .setStyle(

        androidx.media.app.NotificationCompat.MediaStyle().setShowActionsInCompactView(0, 1, 2) // .setMediaSession()

    )

    .build()



notificationManager.notify(id++, build)

}




上述代码中`addAction`添加了4个控制按钮,`setShowActionsInCompactView`设置了通知在收起状态下,显示第`0`、`1`、`2`个按钮。



[]( )点击通知跳转Activity

------------------------------------------------------------------------



在`基本样式通知`的基础上举例,只需要`setContentIntent`即可



private fun showBasicNotification3() {

// 创建一个跳转的Intent

val intent = Intent(this, MainActivity::class.java).apply { 

    // ... 其他一些设置信息

}

// 创建 PendingIntent

val jumpIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, 0)



val build = NotificationCompat.Builder(this, CHANNEL_ID_NOTIFICATION_BASIC)

    .setSmallIcon(R.mipmap.ic_launcher)

    .setContentTitle("基本通知")

    .setContentText("我是基本通知内容,点击可以跳转Activity.")

    .setPriority(NotificationCompat.PRIORITY_DEFAULT)

    // 设置跳转,点击打开MainActivity

    .setContentIntent(jumpIntent)

    .build()



notificationManager.notify(id++, build)

}




[]( )添加Action

------------------------------------------------------------------



![](https://img-blog.csdnimg.cn/20200804183419567.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3E0ODc4ODAy,size_16,color_FFFFFF,t_70)



同样在`基本样式通知`的基础上举例,Action可以添加点击跳转行为,也可以添加点击发送广播的行为。



private fun showBasicNotification4() {

// 创建一个跳转的Intent

val intent = Intent(this, MainActivity::class.java).apply {

    // ... 其他一些设置信息

}

// 创建 PendingIntent

val jumpIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, 0)



// 创建发送广播的Intent

val sendBroadcastIntent: PendingIntent = PendingIntent.getBroadcast(this, 0, Intent("com.kongqw.notificationsimple.action"), 0)



val build = NotificationCompat.Builder(this, CHANNEL_ID_NOTIFICATION_BASIC)

    .setSmallIcon(R.mipmap.ic_launcher)

    .setContentTitle("基本通知")

    .setContentText("我是带有Action的基本通知内容")

    .setPriority(NotificationCompat.PRIORITY_DEFAULT)

    // 设置点击跳转的Action

    .addAction(R.mipmap.ic_launcher, "点我打开MainActivity", jumpIntent)

    // 设置点击发送广播的Action

    .addAction(R.mipmap.ic_launcher, "点我发送一条广播", sendBroadcastIntent)

    .build()



notificationManager.notify(id++, build)

}




*   jumpIntent 设置了点击跳转到MainActivity

*   sendBroadcastIntent 设置了发送广播的内容,动态注册一个广播后自行验证即可。



[]( )在通知中直接回复

------------------------------------------------------------------



![](https://img-blog.csdnimg.cn/20200804183446736.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3E0ODc4ODAy,size_16,color_FFFFFF,t_70) ![](https://img-blog.csdnimg.cn/20200804183509655.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3E0ODc4ODAy,size_16,color_FFFFFF,t_70) ![](https://img-blog.csdnimg.cn/20200804183528972.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3E0ODc4ODAy,size_16,color_FFFFFF,t_70) ![](https://img-blog.csdnimg.cn/2020080418355190.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3E0ODc4ODAy,size_16,color_FFFFFF,t_70) ![](https://img-blog.csdnimg.cn/20200804183616617.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3E0ODc4ODAy,size_16,color_FFFFFF,t_70) ![](https://img-blog.csdnimg.cn/20200804183636345.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3E0ODc4ODAy,size_16,color_FFFFFF,t_70)```

private fun showReplayNotification() {

    // 设置回复后的广播

    val replyPendingIntent: PendingIntent = PendingIntent.getBroadcast(applicationContext, 0, Intent("com.kongqw.notificationsimple.reply"), PendingIntent.FLAG_UPDATE_CURRENT)

    // 设置回复输入框

    val remoteInput: RemoteInput = RemoteInput.Builder("KEY_TEXT_REPLY").setLabel("请输入").build()

    // 设置回复按钮

    val replyAction = NotificationCompat.Action.Builder(R.drawable.ic_launcher_background, "回复", replyPendingIntent).addRemoteInput(remoteInput).build()

    // 模拟收到的消息

    val bitmap = BitmapFactory.decodeStream(resources.assets.open("picture.jpg"))

    val message = NotificationCompat.MessagingStyle.Message("你好啊", System.currentTimeMillis(), Person.Builder().setName("张三").setIcon(IconCompat.createWithBitmap(bitmap)).build())



    val build = NotificationCompat.Builder(this, CHANNEL_ID_NOTIFICATION_BASIC)

        .setSmallIcon(R.mipmap.ic_launcher)

        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

        .setStyle(NotificationCompat.MessagingStyle(Person.Builder().setName("kongqw").build()).addMessage(message))

        // 回复

        .addAction(replyAction)

        .build()



    notificationManager.notify(id++, build)

}



  • KEY_TEXT_REPLY 用来标记回复的文字内容,在广播接收者中使用该字段来获取回复的文字

广播接收(代码仅供参考,注册广播请自行处理)


inner class MyBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {

        when (intent?.action) {

            "com.kongqw.notificationsimple.action" -> Toast.makeText(applicationContext, "收到广播", Toast.LENGTH_SHORT).show()

            "com.kongqw.notificationsimple.reply" -> {

                val charSequence = RemoteInput.getResultsFromIntent(intent)?.getCharSequence("KEY_TEXT_REPLY")

                Toast.makeText(applicationContext, "回复:$charSequence", Toast.LENGTH_SHORT).show()

            }

        }

    }

}



自定义样式的通知


最后部分,我们来模拟网易云音乐,实现一个自定义的通知样式(仅实现基础样式、不包含功能),先看图(上:网易云音乐,下:自定义)

因为网易云音乐的通知有一些设置,例如:不能滑动删除、静音、没有震动等,所以我们重新创建一个通道,专门来显示我们的自定义通知。


private fun createNotificationChannel2() {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

        val name = "播放器"

        val descriptionText = "模仿网易云音乐的通知"

        val importance = NotificationManager.IMPORTANCE_DEFAULT

        val channel =

            NotificationChannel(CHANNEL_ID_NOTIFICATION_CUSTOM_MEDIA, name, importance).apply {

                description = descriptionText

                // 禁用呼吸灯

                enableLights(false)

                // 禁止震动

                enableVibration(false)

                vibrationPattern = LongArray(0)

                // 静音

                setSound(null, null)

            }

        notificationManager.createNotificationChannel(channel)

    }

}



直接上代码部分


private fun showCustomNotification() {

    // 自定义的通知页面

    val remoteViewsMedia = RemoteViews(packageName, R.layout.custom_notification_media)

    // 设置通知页面上按钮的点击广播

    remoteViewsMedia.setOnClickPendingIntent(R.id.ib_close, PendingIntent.getBroadcast(applicationContext, 0, Intent("com.kongqw.notification.custom.media.close"), 0))

    remoteViewsMedia.setOnClickPendingIntent(R.id.ib_1, PendingIntent.getBroadcast(applicationContext, 0, Intent("com.kongqw.notification.custom.media.btn1"), 0))

    remoteViewsMedia.setOnClickPendingIntent(R.id.ib_2, PendingIntent.getBroadcast(applicationContext, 0, Intent("com.kongqw.notification.custom.media.btn2"), 0))

    remoteViewsMedia.setOnClickPendingIntent(R.id.ib_3, PendingIntent.getBroadcast(applicationContext, 0, Intent("com.kongqw.notification.custom.media.btn3"), 0))

    remoteViewsMedia.setOnClickPendingIntent(R.id.ib_4, PendingIntent.getBroadcast(applicationContext, 0, Intent("com.kongqw.notification.custom.media.btn4"), 0))

    remoteViewsMedia.setOnClickPendingIntent(R.id.ib_5, PendingIntent.getBroadcast(applicationContext, 0, Intent("com.kongqw.notification.custom.media.btn5"), 0))

    // 设置封面

    remoteViewsMedia.setImageViewBitmap(R.id.iv_cover, BitmapFactory.decodeStream(resources.assets.open("picture.jpg")))



    build = NotificationCompat.Builder(this, CHANNEL_ID_NOTIFICATION_CUSTOM_MEDIA)

        .setSmallIcon(R.mipmap.ic_launcher)

        // .setStyle(NotificationCompat.DecoratedCustomViewStyle())

        .setCustomContentView(remoteViewsMedia)

        .setAutoCancel(false)

        // 禁止滑动删除

        .setOngoing(true)



    build?.priority = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

        NotificationManager.IMPORTANCE_MAX

    } else {

        NotificationCompat.PRIORITY_MAX

    }



    notificationManager.notify(66, build?.build())

}



自定义通知,最核心的的部分就在setCustomContentView,添加了一个自定义的View,这里是一个RemoteViews,因此想到之前的Widget开发,通知的自定义布局和Widget的自定义布局一样,能且仅能使用部分布局和组件,详见Widget

这里在复述一遍,

可使用的布局包括:

  • FrameLayout

  • LinearLayout

  • RelativeLayout

  • GridLayout

可使用的控件包括:

  • AnalogClock

  • Button

  • Chronometer

  • ImageButton

  • ImageView

  • ProgressBar

  • TextView

  • ViewFlipper

  • ListView

  • GridView

  • StackView

  • AdapterViewFlipper

注:如果使用除此之外的布局或控件,通知将无法显示。

布局文件 custom_notification_media.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"

    android:layout_width="match_parent"

    android:layout_height="113dp"

    android:orientation="horizontal">



    <ImageView

        android:id="@+id/iv_cover"

        android:layout_width="113dp"

        android:layout_height="113dp"

        android:background="@drawable/ic_launcher_background"

        android:scaleType="centerCrop" />



    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:orientation="vertical"

        android:weightSum="10">



        <RelativeLayout

            android:layout_width="match_parent"

            android:layout_height="60dp">



            <ImageButton

                android:id="@+id/ib_close"

                android:layout_width="30dp"

                android:layout_height="30dp"

                android:layout_alignParentEnd="true"

                android:layout_alignParentRight="true"

                android:background="@android:color/transparent"

                android:src="@android:drawable/ic_menu_close_clear_cancel" />



            <TextView

                android:id="@+id/tv_title"

                android:layout_width="match_parent"

                android:layout_height="35dp"

                android:layout_toStartOf="@id/ib_close"

                android:layout_toLeftOf="@id/ib_close"

                android:gravity="center_vertical"

                android:paddingStart="10dp"

                android:paddingEnd="10dp"

                android:text="我是歌名"

                android:textColor="#555555"

                android:textSize="15sp" />



            <TextView

                android:id="@+id/tv_des"

                android:layout_width="match_parent"

                android:layout_height="match_parent"

                android:layout_below="@id/tv_title"

                android:layout_toStartOf="@id/ib_close"

                android:layout_toLeftOf="@id/ib_close"

                android:gravity="center_vertical"

                android:paddingStart="10dp"

                android:paddingEnd="10dp"

                android:text="我是歌手名"

                android:textColor="#AAAAAA"

                android:textSize="13sp" />



        </RelativeLayout>



        <TextView

            android:layout_width="match_parent"

            android:layout_height="1dp"

            android:background="#EEEEEE" />



        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            android:orientation="horizontal"

            android:weightSum="5">



            <ImageButton

                android:id="@+id/ib_1"

                android:layout_width="0dp"

                android:layout_height="match_parent"

                android:layout_weight="1"

                android:background="@android:color/transparent"

                android:src="@android:drawable/star_off" />



            <ImageButton

                android:id="@+id/ib_2"

                android:layout_width="0dp"

                android:layout_height="match_parent"

                android:layout_weight="1"

                android:background="@android:color/transparent"

                android:src="@android:drawable/ic_media_previous" />



            <ImageButton

                android:id="@+id/ib_3"

                android:layout_width="0dp"

                android:layout_height="match_parent"

                android:layout_weight="1"

                android:background="@android:color/transparent"

                android:src="@android:drawable/ic_media_play" />



            <ImageButton

                android:id="@+id/ib_4"

                android:layout_width="0dp"

                android:layout_height="match_parent"

                android:layout_weight="1"

                android:background="@android:color/transparent"

                android:src="@android:drawable/ic_media_next" />



            <ImageButton

                android:id="@+id/ib_5"

                android:layout_width="0dp"

                android:layout_height="match_parent"

                android:layout_weight="1"

                android:background="@android:color/transparent"

                android:src="@android:drawable/ic_lock_power_off" />



        </LinearLayout>

    </LinearLayout>

</LinearLayout>



广播的注册


private val mMyBroadcastReceiver = MyBroadcastReceiver()

private val mIntentFilter = IntentFilter().apply {

    addAction("com.kongqw.notification.custom.media.close")

    addAction("com.kongqw.notification.custom.media.btn1")

    addAction("com.kongqw.notification.custom.media.btn2")

    addAction("com.kongqw.notification.custom.media.btn3")

    addAction("com.kongqw.notification.custom.media.btn4")

    addAction("com.kongqw.notification.custom.media.btn5")

}




registerReceiver(mMyBroadcastReceiver, mIntentFilter)



反注册


unregisterReceiver(mMyBroadcastReceiver)



资源分享

  • 最新大厂面试专题

这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等

  • 对应导图的Android高级工程师进阶系统学习视频
    最近热门的,NDK,热修复,MVVM,源码等一系列系统学习视频都有!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

ia.btn4")

addAction("com.kongqw.notification.custom.media.btn5")

}


registerReceiver(mMyBroadcastReceiver, mIntentFilter)




反注册



unregisterReceiver(mMyBroadcastReceiver)




# 资源分享

*   **最新大厂面试专题**

这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等

[外链图片转存中...(img-EiQX4XBn-1714463165525)]

*   **对应导图的Android高级工程师进阶系统学习视频**
    最近热门的,NDK,热修复,MVVM,源码等一系列系统学习视频都有!

[外链图片转存中...(img-DFutbdWv-1714463165526)]



**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android通知栏是一种用于显示应用程序通知的用户界面元素。它可以在屏幕的顶部或底部显示,并且可以包含文本、图像、声音和其他交互元素。通知栏可以帮助用户及时了解应用程序的状态和事件,例如新消息、更新、提醒和警告等。开发人员可以使用Android SDK提供的通知API来创建和管理通知栏,以便更好地与用户进行交互。 ### 回答2: Android 通知栏是一种提供给用户显示有关当前状态和行动的信息的方式,以便用户可以及时地采取必要的行动。通知栏可以显示来自应用程序和系统的通知消息,例如电子邮件、信息和其他事件,可以让用户在不离开当前应用的情况下对这些消息进行响应。 在通知栏中,每个通知都包含一个图标、标题、简短的消息文本和通知时间。用户可以从通知栏中直接打开应用程序或查看通知的详细信息。通知栏还可以显示多个通知,按照时间顺序进行排序。 开发人员可以使用 Android SDK 提供的 Notification 类来创建自定义通知。可以设置通知的图标、文本、声音、震动和延迟时间等属性。还可以指定通知的优先级,以便系统在有限的屏幕空间中为用户先显示最重要的通知通知还可以与 PendingIntent 实例相关联,以便在用户单击通知时执行特定的操作,例如打开应用程序,启动活动或显示通知详细信息的专用活动。 总之,Android 通知栏是一种非常有用的功能,可以让用户及时了解应用程序和系统中的重要事件,并采取及时的行动。开发人员可以使用通知栏来实现更好的用户体验。 ### 回答3: Android 通知栏是一种非常有用的功能,它可以让你的应用程序以一种全新的方式与用户进行交互。在 Android 应用程序中,通知栏是一种特殊的 UI 元素,它显示在屏幕的顶部,并显示当前状态、事件或提示。通知栏通常包含一组小图标,可以展开或折叠以显示更多详细信息。 Android 通知栏有许多不同的用途,例如提醒用户新的消息、电子邮件、电话、提醒等等。发送通知的应用程序无需与用户保持连接,这使得通知栏非常适合后台服务或其他形式的低功耗通信。通知栏还允许用户直接从通知菜单中操作应用程序。例如,当用户收到新的电子邮件时,他们可以在通知栏中选择该电子邮件并立即查看其内容,而无需打开电子邮件应用程序。 Android 通知栏的另一个优点是它的可定制性。可以轻松地修改通知的外观、行为和内容,以满足不同应用程序的需求和设计要求。您可以为通知添加各种元素,如纯文本、小图标、大图标、进度指示器、按钮等等。这样,您可以轻松地创造与您的品牌和应用程序设计语言保持一致的通知。 在实现通知栏之前,您需要确保该应用程序已获得了通知权限。如果您的应用程序需要通知用户任何内容,则必须获得 Android 手机上的通知权限。可以在应用程序设置中找到此选项。 虽然 Android 通知栏很有用,但在某些情况下,它们可能会变得令人分心。因此,应该仔细考虑应用程序通知的数量和类型,以确保用户不会感到困扰。通知栏还可以消耗设备电池,因此也应考虑优化应用程序以最小化资源消耗。 Android 通知栏作为 Android 应用程序非常重要的一部分,可以帮助您在应用程序和用户之间建立更紧密的联系,并提供有关应用程序状态、事件和提示的有用信息。通过努力优化您的应用程序通知,您可以确保用户感到受到了关注,并且同时不会让他们感到困扰。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值