在Android应用的开发中,必然会遇上通知的开发需求,本文主要讲一下Android中的通知 Notification的简单基本使用,主要包含创建通知渠道、初始化通知、显示通知、显示图片通知、通知点击、以及配合WorkManager发送延迟通知。

Demo下载

创建通知渠道

首先,创建几个常量和变量,其中渠道名是会显示在手机设置-通知里app对应展示的通知渠道名称,一般基于通知作用取名。

    companion object {
        //渠道Id
        private const val CHANNEL_ID = "渠道Id"
        //渠道名
        private const val CHANNEL_NAME = "渠道名-简单通知"
        //渠道重要级
        private const val CHANNEL_IMPORTANCE = NotificationManager.IMPORTANCE_DEFAULT
    }
    private lateinit var context: Context
    //Notification的ID
    private var notifyId = 100
    private lateinit var manager: NotificationManager
    private lateinit var builder: NotificationCompat.Builder

然后获取系统通知服务,创建通知渠道,其中因为通知渠道是Android8.0才有的,所以增加一个版本判断:

        //获取系统通知服务
        manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        //创建通知渠道,Android8.0及以上需要
        createChannel()
    private fun createChannel() {
        //创建通知渠道,Android8.0及以上需要
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            return
        }
        val notificationChannel = NotificationChannel(
            CHANNEL_ID,
            CHANNEL_NAME,
            CHANNEL_IMPORTANCE
        )
        manager.createNotificationChannel(notificationChannel)
    }

初始化通知

先生成NotificationCompat.Builder,然后初始化通知Builder的通用配置:

        builder = NotificationCompat.Builder(context.applicationContext, CHANNEL_ID)
        initNotificationBuilder()
    /**
     * 初始化通知Builder的通用配置
     */
    private fun initNotificationBuilder() {
        builder
            .setAutoCancel(true) //设置这个标志当用户单击面板就可以让通知自动取消
            .setSmallIcon(R.drawable.ic_reminder) //通知的图标
            .setWhen(System.currentTimeMillis()) //通知产生的时间,会在通知信息里显示
            .setDefaults(Notification.DEFAULT_ALL)
    }

此外builder还有setVibrate、setSound、setStyle等方法,按需配置即可。

显示通知

给builder设置需要通知需要显示的title和content,然后通过builder.build()生成生成通知Notification,manager.notify()方法将通知发送出去。

    fun configNotificationAndSend(title: String, content: String){
        builder.setContentTitle(title)
            .setContentText(content)
        val notification = builder.build()
        //发送通知
        manager.notify(notifyId, notification)
        //id自增
        notifyId  
    }

最简单的通知显示至此上面三步就完成了。

效果如下图:

显示图片通知

当通知内容过多一行展示不下时,可以通过设置

builder.setStyle(NotificationCompat.BigTextStyle().bigText(content)) //设置可以显示多行文本

这样通知就能收缩和展开,显示多行文本。

另外setStyle还可以设置图片形式的通知:

setStyle(NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(resources,R.drawable.logo)))//设置图片样式

效果如下图:

通知点击

目前为止的通知还只是显示,因为设置了builder.setAutoCancel(true),点击通知之后通知会自动消失,除此之外还没有其他操作。

给builder设置setContentIntent(PendingIntent)就能有通知点击之后的其他操作了。PendingIntent可以看作是对Intent的一个封装,但它不是立刻执行某个行为,而是满足某些条件或触发某些事件后才执行指定的行为。PendingIntent获取有三种方式:Activity、Service和BroadcastReceiver获取。通过对应方法PendingIntent.getActivity、PendingIntent.getBroadcast、PendingIntent.getService就能获取。

这里就示例一下PendingIntent.getBroadcast和PendingIntent.getActivity

PendingIntent.getBroadcast

首先创建一个BroadcastReceiver:

class NotificationHandleReceiver : BroadcastReceiver() {
    companion object {
        const val NOTIFICATION_HANDLE_ACTION = "notification_handle_action"
        const val NOTIFICATION_LINK = "notificationLink"
        const val TAG = "NotificationReceiver"
    }
    override fun onReceive(context: Context, intent: Intent?) {
        if (intent?.action == NOTIFICATION_HANDLE_ACTION) {
            val link = intent.getStringExtra(NOTIFICATION_LINK)
        }
    }
}

别忘了在清单文件中还需要静态注册BroadcastReceiver:

    <receiver
        android:name=".NotificationHandleReceiver"
        android:exported="false">
        <intent-filter>
            <action android:name="notification_handle_action" />
        </intent-filter>
    </receiver>

然后创建一个上面BroadcastReceiver的Intent,在intent.putExtra传入相应的点击通知之后需要识别的操作:

   fun generateDefaultBroadcastPendingIntent(linkParams: (() -> String)?): PendingIntent {
        val intent = Intent(NotificationHandleReceiver.NOTIFICATION_HANDLE_ACTION)
        intent.setPackage(context.packageName)
        linkParams?.let {
            val params = it.invoke()
            intent.putExtra(NotificationHandleReceiver.NOTIFICATION_LINK, params)
        }
        return PendingIntent.getBroadcast(
            context,
            notifyId,
            intent,
            PendingIntent.FLAG_IMMUTABLE
        )
    }

这样生成的PendingIntent再builder.setContentIntent(pendingIntent),在我们点击通知之后,NotificationHandleReceiver的onReceive里就会收到信息了,根据信息处理后续操作即可。

PendingIntent.getActivity

Activity的PendingIntent用于跳转到指定activity,创建一个跳转activity的Intent(同普通的页面跳转的Intent),也是同上面在intent.putExtra传入相应的点击通知之后需要识别的操作:

        val intent = Intent(this, XXXX::class.java).apply {
            putExtra("title", title).putExtra("content", content)
        }
        return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)

也是这样生成的PendingIntent再builder.setContentIntent(pendingIntent),在我们点击通知之后,就会跳转到对应的activity页面,然后intent里就会收到信息了,根据信息处理后续操作即可。

Android12之PendingIntent特性

行为变更:以 Android 12 为目标平台的应用

查看上面关于Android12的特性

在Android12平台上有关于PendingIntent的两点特性:

一是待处理 intent 可变性,必须为应用创建的每个PendingIntent对象指定可变性,这也是上面创建PendingIntent时需要设置flag为PendingIntent.FLAG_IMMUTABLE。

二是通知 trampoline 限制,以 Android 12 或更高版本为目标平台的应用无法从用作通知 trampoline 的服务或广播接收器中启动 activity。换言之,当用户点按通知或通知中的操作按钮时,您的应用无法在服务或广播接收器内调用startActivity()。所以当需要点击通知实现activity跳转时,需要使用PendingIntent. getActivity,而不是使用PendingIntent.getBroadcast,然后在BroadcastReceiver里实现activity跳转,后者方式在Android 12 或更高版本为目标平台的应用中将被限制。

配合WorkManager发送延迟通知

配合上WorkManager,就能实现发送延迟通知,主要是通过OneTimeWorkRequest的延迟特性。

创建一个延迟的OneTimeWorkRequest,加入WorkManager队列中:

    fun sendWorkRequest(
        context: Context,
        reminderId: Int,
        title: String,
        content: String,
        link: String,
        triggerTime: Long
    ): OneTimeWorkRequest {
        val duration = triggerTime - System.currentTimeMillis()
        val data =
            Data.Builder().putInt(REMINDER_WORKER_DATA_ID, reminderId).putString(REMINDER_WORKER_DATA_TITLE, title)
                .putString(REMINDER_WORKER_DATA_CONTENT, content).putString(REMINDER_WORKER_DATA_LINK, link)
                .build()
        val uniqueWorkName =
            "reminderData_${reminderId}"
        val request = OneTimeWorkRequest.Builder(ReminderWorker::class.java)
            .setInitialDelay(duration, TimeUnit.MILLISECONDS)
            .setInputData(data)
            .build()
        WorkManager.getInstance(context)
            .enqueueUniqueWork(uniqueWorkName, ExistingWorkPolicy.REPLACE, request)
        return request
    }

然后在doWork方法中拿到数据进行我们上面的通知发送显示即可。具体关于OneTimeWorkRequest的使用在本文中就不详细说明了。当需要发送延迟通知时,知道可以通过配合WorkManager实现。

Android13 通知权限

在目前最新的Android 13(API 级别 33)上对于通知增加了权限限制,具体可看官方描述:

通知运行时权限

到此这篇关于Android Notification通知使用详解的文章就介绍到这了,更多相关Android Notification内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Android Notification通知使用详解的更多相关文章

  1. html5 canvas合成海报所遇问题及解决方案总结

    这篇文章主要介绍了html5 canvas合成海报所遇问题及解决方案总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. HTML5中的Web Notification桌面通知功能的实现方法

    这篇文章主要介绍了HTML5中的Web Notification桌面通知功能的实现方法,需要的朋友可以参考下

  3. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  4. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  5. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  6. ios – 从枚举类型’enum UIDeviceOrientation’到不同的枚举类型’UIInterfaceOrientation”enum UIInterfaceOrientation的隐式转换

    我正在使用Xcode5.0.2并在尝试编译我的目标C代码时收到以下警告:Implicitconversionfromenumerationtype‘enumUIDeviceOrientation’todifferentenumerationtype‘UIInterfaceOrientation’(aka‘enumUIInterfaceOrientation’)警告在viewController.m

  7. 扩展iOS 11安全区域以包括键盘

    手动获取工具栏框架并使用其高度?或者是否可以直接从安全区域布局指南中获得差距?问题2:据推测,如果没有键盘改变大小,底栏应该可以改变大小,所以我也应该实现一些方法来监听栏中框架的变化.这是最好的在viewWillTransition中完成?

  8. ios – 检测用户点击本地通知

    我会定期显示这样的本地通知.我需要检测回来的通知,我打算在这里写.无论用户点击通知还是自动在前台呼叫,它总是调用该功能.所以,我分开使用它.当我显示通知中心时,它变为InActive.但是,它仍然调用didReceivelocalnotification.我无法区分用户是否点击通知中心的通知或是因为我的定期发布通知.我怎么才能真正知道我在didReceivelocalnotification中点击

  9. Ionic – Splash Screen适用于iOS,但不适用于Android

    我有一个离子应用程序,其中使用CLI命令离子资源生成的启动画面和图标iOS版本与正在渲染的启动画面完美配合,但在Android版本中,只有在加载应用程序时才会显示白屏.我检查了config.xml文件,所有路径看起来都是正确的,生成的图像出现在相应的文件夹中.(我使用了splash.psd模板来生成它们.我错过了什么?这是config.xml文件供参考,我觉得我在这里做错了–解决方法在config.xml中添加以下键:它对我有用!

  10. ios – 无法启动iPhone模拟器

    /Library/Developer/CoreSimulator/Devices/530A44CB-5978-4926-9E91-E9DBD5BFB105/data/Containers/Bundle/Application/07612A5C-659D-4C04-ACD3-D211D2830E17/ProductName.app/ProductName然后,如果您在Xcode构建设置中选择标准体系结构并再次构建和运行,则会产生以下结果:dyld:lazysymbolbindingFailed:Symbol

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部