Android通知工具类,含8.0通知适配,打开通知设置页面适配

编程入门 行业动态 更新时间:2024-10-08 22:57:09

Android<a href=https://www.elefans.com/category/jswz/34/1771097.html style=通知工具类,含8.0通知适配,打开通知设置页面适配"/>

Android通知工具类,含8.0通知适配,打开通知设置页面适配

先贴上代码,之后简单分析一下:

package com.lct.customview.wholeimport android.annotation.TargetApi
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.Uri
import android.os.Build
import android.provider.Settings
import android.support.annotation.RequiresApi
import android.support.v4.app.NotificationCompat
import android.support.v4.app.NotificationManagerCompat
import android.support.v7.app.AlertDialog/*** Author:SkySmile* Date:2019/2/28* Description:App的通知渠道配置*/
@TargetApi(Build.VERSION_CODES.N)
object AppNotification {//通知ID//对于通知来说ID相同即为同一条通知,如果通知ID已存在,则更新通知内容,否则发送一条新的通知//这里为了每次都能发送一条新的通知,对ID进行累加private var id = 1//影视类通知渠道const val mediaChannelId = "0x1" //通知渠道IDconst val mediaChannelName = "影视" //通知渠道名称,显示在手机上该APP的通知管理中const val mediaChannelImportance = NotificationManager.IMPORTANCE_HIGH //通知渠道重要性//美食类通知渠道const val foodChannelId = "0x2" //通知渠道IDconst val foodChannelName = "美食" //通知渠道名称,显示在手机上该APP的通知管理中const val foodChannelImportance = NotificationManager.IMPORTANCE_DEFAULT //通知渠道重要性/*** 创建通知渠道** @param applicationContext 上下文* @param channelId 渠道ID* @param channelIdName 渠道名称,显示在手机上该APP的通知管理中* @param channelIdImportance 渠道重要程度*/fun createNotificationChannel(applicationContext: Context, channelId: String,channelIdName: String, channelIdImportance: Int) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagerval notificationChannel = NotificationChannel(channelId, channelIdName,channelIdImportance)notificationManager.createNotificationChannel(notificationChannel)}}/*** 发送通知,根据需要进行扩展** @param context 上下文* @param channelId 渠道ID(必须对应已创建的渠道ID)* @param title 通知标题* @param text 通知内容* @param smallIcon 通知小图标(显示在状态栏中的),必须设置* @param largeIcon 通知大图标(下拉状态栏可见,显示在通知栏中),*         注意:这里的图片ID不能是mipmap文件夹下的,因为BitmapFactory.decodeResource方法只能*         获取到 drawable, sound, and raw resources;* @param pi 点击通知打开的页面**/fun sendNotification(context: Context, channelId: String, title: String,text: String, smallIcon: Int, largeIcon: Int, pi: PendingIntent) {//判断通知是否开启if (!isNotificationEnabled(context)) {AlertDialog.Builder(context).setTitle("提示").setMessage("是否开启通知?").setPositiveButton("确定") { _, _ ->openNotification(context)}.setNegativeButton("取消", null).show()return}//判断某个渠道的通知是否开启if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {if (!isNotificationChannelEnabled(context, channelId)) {val message = when (channelId) {mediaChannelId -> mediaChannelNamefoodChannelId -> foodChannelNameelse -> ""}AlertDialog.Builder(context).setTitle("提示").setMessage("是否开启${message}通知?").setPositiveButton("确定") { _, _ ->openNotificationChannel(context, channelId)}.setNegativeButton("取消", null).show()return}}//发送通知val notification = NotificationCompat.Builder(context, channelId).setContentTitle(title).setContentText(text).setWhen(System.currentTimeMillis()).setSmallIcon(smallIcon).setLargeIcon(BitmapFactory.decodeResource(context.resources, largeIcon)).setContentIntent(pi).setAutoCancel(true).build()val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagernotificationManager.notify(id++, notification)}/*** 判断App通知是否开启* 注意这个方法判断的是通知总开关,如果APP通知被关闭,则其下面的所有通知渠道也被关闭*/fun isNotificationEnabled(context: Context): Boolean {val notificationManagerCompat = NotificationManagerCompat.from(context)return notificationManagerCompat.areNotificationsEnabled()}/*** 判断APP某个通知渠道的通知是否开启*/@RequiresApi(Build.VERSION_CODES.O)fun isNotificationChannelEnabled(context: Context, channelId: String): Boolean {val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagerval channel = notificationManager.getNotificationChannel(channelId)return channel.importance != NotificationManager.IMPORTANCE_NONE}/*** 打开通知设置页面*/fun openNotification(context: Context) {val packageName = context.packageNameval uid = context.applicationInfo.uidval intent = Intent()when {Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGSintent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)intent.putExtra(Settings.EXTRA_CHANNEL_ID, uid)}Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"intent.putExtra("app_package", packageName)intent.putExtra("app_uid", uid)}Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT -> {intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGSintent.addCategory(Intent.CATEGORY_DEFAULT)intent.data = Uri.parse("package:$packageName")}else -> intent.action = Settings.ACTION_SETTINGS}context.startActivity(intent)}/*** 打开通知渠道设置页面*/@RequiresApi(Build.VERSION_CODES.O)fun openNotificationChannel(context: Context, channelId: String) {val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)intent.putExtra(Settings.EXTRA_CHANNEL_ID, channelId)context.startActivity(intent)}
}

通知渠道是在android 8.0加入的。如果有多个渠道,则在手机的通知管理中会显示出每个渠道的名称,并且可以对每个通知渠道进行单独的设置,比如开启或者关闭。如果通知渠道只有一个,则不显示渠道名称。如下图:

                

左侧是只有一个通知渠道显示的页面,右侧是有两个通知渠道显示的页面。

上图使用的是华为android 8.0手机,不同厂商显示的可能不一样(华为手机系统比较接近Android原生)

createNotificationChannel方法的作用是创建通知渠道,渠道只能创建一次,即创建过后渠道名称不能再通过代码更改,除非是卸载APP重新安装,但是可以通过代码删除渠道,不过删除后,在手机的通知管理中会显示出已删除的渠道。

建议在Application的onCreate方法中调用,eg:

package com.lct.customviewimport android.app.Application
import com.lct.customview.whole.AppNotification/*** Author:SkySmile* Date:2019/2/28* Description:Application*/
class MyApplication : Application() {override fun onCreate() {super.onCreate()//创建影视通知渠道AppNotification.createNotificationChannel(this,AppNotification.mediaChannelId,AppNotification.mediaChannelName,AppNotification.mediaChannelImportance)//创建美食通知渠道AppNotification.createNotificationChannel(this,AppNotification.foodChannelId,AppNotification.foodChannelName,AppNotification.foodChannelImportance)}
}

 sendNotification方法的作用是发送通知。方法中首先判断了APP通知是否开启,没开启的话,则跳转到通知设置页面或APP详情页面引导用户开启通知权限。其次判断了(8.0及以上系统)某个通知渠道是否被开启,没开启的话,则跳转到对应的通知渠道页面引导用户开启。满足上述条件,则发送通知。

调用试例:

package com.lct.customviewimport android.app.PendingIntent
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.lct.customview.whole.AppNotification
import kotlinx.android.synthetic.main.activity_notification.*class NotificationActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_notification)btnMedia.setOnClickListener {val intent = Intent(this, MediaActivity::class.java)val pi = PendingIntent.getActivity(this, 0,intent, 0)AppNotification.sendNotification(this, AppNotification.mediaChannelId,"热门影视", "新版倚天屠龙记正式开播",R.mipmap.ic_launcher, R.drawable.ic_launcher_round, pi)}btnFood.setOnClickListener {val intent = Intent(this, MediaActivity::class.java)val pi = PendingIntent.getActivity(this, 0,intent, 0)AppNotification.sendNotification(this, AppNotification.foodChannelId,"露露鲜果", "新摘的大苹果,好吃实惠",R.mipmap.ic_launcher, R.mipmap.ic_launcher, pi)}}
}

注意8.0及以上系统,不设置通知渠道的话,通知无法显示出来。

其它方法代码中已明确注释,此处就不做解释了。

参考博客:

Android通知栏微技巧,8.0系统中通知栏的适配

更多推荐

Android通知工具类,含8.0通知适配,打开通知设置页面适配

本文发布于:2024-03-15 00:26:37,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1737699.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:通知   页面   工具   Android

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!