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

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

package com.lct.customview.whole

import 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.net.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" //通知渠道ID
    const val mediaChannelName = "影视" //通知渠道名称,显示在手机上该APP的通知管理中
    const val mediaChannelImportance = NotificationManager.IMPORTANCE_HIGH //通知渠道重要性

    //美食类通知渠道
    const val foodChannelId = "0x2" //通知渠道ID
    const 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 NotificationManager
            val 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 -> mediaChannelName
                    foodChannelId -> foodChannelName
                    else -> ""
                }
                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 NotificationManager
        notificationManager.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 NotificationManager
        val channel = notificationManager.getNotificationChannel(channelId)
        return channel.importance != NotificationManager.IMPORTANCE_NONE
    }

    /**
     * 打开通知设置页面
     */
    fun openNotification(context: Context) {
        val packageName = context.packageName
        val uid = context.applicationInfo.uid
        val intent = Intent()
        when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
                intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
                intent.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_SETTINGS
                intent.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.customview

import 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.customview

import 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系统中通知栏的适配

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android通知栏工具是指用于管理和展示Android设备上通知栏的应用程序或服务。通知栏是Android系统中用于显示各种通知的一个区域,用户可以从通知栏中查看和操作通知消息。 通知栏工具通常具有以下功能: 1. 通知管理:可以管理并展示来自各个应用程序的通知消息,包括短信、电话、社交媒体等各种类型的通知。用户可以通过通知栏工具集中查看和处理这些通知,提高管理效率。 2. 快捷操作:通知栏工具可以提供一些快捷操作,例如回复短信、拒接来电、播放音乐等,用户可以直接在通知栏中完成这些操作,无需打开具体的应用程序。 3. 状态显示:通知栏工具可以显示设备的一些状态信息,例如电量、网络连接状态、音量等。用户可以通过通知栏随时查看这些状态信息,方便实时监控设备的运行情况。 4. 个性化设置通知栏工具通常支持各种个性化设置,用户可以自定义通知栏的样式、主题、通知显示方式等,以满足个人需求和喜好。 5. 通知过滤:通知栏工具可以根据用户的设置通知进行过滤,屏蔽一些不重要的通知或者将其归类整理。这样可以减少通知的干扰,提高通知的有效性。 总之,Android通知栏工具为用户提供了一个方便管理和操作通知的工具,帮助用户更高效地处理来自各个应用程序的通知消息,使得使用Android设备更加便捷和舒适。 ### 回答2: Android通知栏工具是一个用于在Android设备上显示通知的功能。通知栏工具可以在应用程序运行时发送各种类型的通知,包括文本、图标、声音、振动等。通过使用通知栏工具,用户可以接收到来自应用程序的重要信息和提示,而无需打开应用程序。 通知栏工具可以帮助应用程序在后台运行或用户退出应用程序后继续发送通知。它提供了一种简单而高效的方式来向用户发送通知,帮助用户及时了解到关键信息。 通知栏工具还可以支持用户与通知进行交互。用户可以通过点击通知打开相关的应用程序或执行其他操作。此外,通知栏工具还提供了通知的展示方式的设置选项,用户可以根据自己的偏好设置通知的显示样式。 在Android开发中,通知栏工具是一个很重要的模块。开发人员可以通过使用Android提供的通知相关的API,轻松地创建和发送通知。他们可以定义通知的标题、内容、图标、声音等属性,并设置通知的行为和交互。 总的来说,Android通知栏工具为应用程序提供了一种方便、快捷的方式来与用户进行沟通和交互。通过使用通知栏工具,应用程序可以将重要信息推送给用户,并提供与用户的实时互动。这使得Android设备的用户体验更加完善和高效。 ### 回答3: Android通知栏工具是一种用于在Android设备上显示通知的工具。在Android操作系统中,通知栏是一个重要的功能,它可以显示各种通知,如消息、提醒、更新等。通知栏工具提供了一种便捷的方式来管理和显示这些通知通知栏工具可以帮助用户及时了解到重要的信息,无论是收到短信、电话、邮件,还是其他应用的通知,都可以通过通知栏工具进行展示。用户可以通过下拉通知栏来查看通知的详细内容,并进行相应的操作,例如回复短信、接听电话、打开邮件等。 通知栏工具还可以提供一些额外的功能,如展示音乐播放器控制按钮、显示天气信息、提供快捷操作按钮等。这些功能可以提升用户体验,让用户方便地控制和获取信息。 通知栏工具还支持通知的管理和设置。用户可以根据自己的喜好和需求,对通知进行分类、过滤和优先级设置。用户还可以通过设置来自定义通知的样式、铃声和震动模式等。 总之,Android通知栏工具是一种非常实用的工具,它可以帮助用户及时了解到各种通知,并提供了方便的操作和管理功能。通过使用通知栏工具,用户可以更好地掌控自己的Android设备和获取重要的信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值