android使用通知和快捷方式

1.权限

android 13版本 将通知改为运行时权限,需要向用户动态申请权限。

// 权限请求
    implementation 'com.guolindev.permissionx:permissionx:1.7.1'
2.通知工具类

通知了解:官网

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import com.choryan.quan.videowzproject.R
import com.choryan.quan.videowzproject.activity.ActivityHome
import com.choryan.quan.videowzproject.activity.ActivityStart
import com.choryan.quan.videowzproject.base.AppBase
import com.choryan.quan.videowzproject.extension.ExtensionLog.log
import com.choryan.quan.videowzproject.net.ApiUtlis
import com.permissionx.guolindev.PermissionX

/**
 * 描述:
 * 作者: shawn
 * 时间: 2024/6/311:55
 */
object UtilNotification {
    const val scene_code_cid = "cid"
    const val scene_code_red = "getRedPackage"
    const val scene_code_custom = "custom"
    const val key_from = "fromNotification"

    private val context = AppBase.instance
    private const val notification_id = 123
    private const val notification_channel_id = "channel_reward_user"
    private const val notification_channel_name = "channel_reward"
    private const val notification_channel_description = "让您获取更多奖励的通道"
    private var preSendTime: Long = 0L

    private fun isFastSend(): Boolean {
        if (System.currentTimeMillis() - preSendTime < 500){
            return true
        }
        preSendTime = System.currentTimeMillis()
        return false
    }

    fun requestNotification(activityHome: ActivityHome,action: (Boolean) -> Unit) {
        PermissionX.init(activityHome)
            .permissions(PermissionX.permission.POST_NOTIFICATIONS)
            .onExplainRequestReason { scope, deniedList ->
                val message = "授予通知权限,防止您错过重要消息"
                scope.showRequestReasonDialog(deniedList, message, "允许", "拒绝")
            }
            .request { allGranted, grantedList, deniedList ->
                if (allGranted) {
                    "通知权限已获取".log()
                } else {
                    "通知权限被拒绝 $deniedList".log()
                }
                action.invoke(allGranted)
            }
    }

    fun createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is not in the Support Library.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = notification_channel_name
            val descriptionText = notification_channel_description
            val importance = NotificationManager.IMPORTANCE_HIGH
            val channel = NotificationChannel(notification_channel_id, name, importance).apply {
                description = descriptionText
            }
            channel.enableVibration(true)
            channel.vibrationPattern = longArrayOf(0)
            // Register the channel with the system.
            val notificationManager: NotificationManager =
                context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }

    fun sendNotification(sceneCode:String) {
        if (isFastSend()) {
            return
        }
        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        // Get the layouts to use in the custom notification.
        val notificationLayout = getRemoteView(sceneCode)
        val notificationLayoutExpanded = getRemoteView(sceneCode)

        // Create an explicit intent for an Activity in your app.
        val intent = Intent(context, ActivityStart::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }
        intent.putExtra(key_from, sceneCode)
        val pendingIntent: PendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
        } else {
            val flag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_UPDATE_CURRENT else 0
            PendingIntent.getActivity(context, 0, intent, flag)
        }
        // Apply the layouts to the notification.
        val customNotification =
            NotificationCompat.Builder(context, notification_channel_id)
                .setSmallIcon(R.mipmap.app_icon_yghj)
                .setStyle(NotificationCompat.DecoratedCustomViewStyle())
                .setCustomContentView(notificationLayout)
                .setCustomBigContentView(notificationLayoutExpanded)
                .setContentIntent(pendingIntent)// Set the intent that fires when the user taps the notification.
                .setAutoCancel(true)
                .setPriority(NotificationManager.IMPORTANCE_HIGH)
                .setCategory(NotificationCompat.CATEGORY_RECOMMENDATION)
                .build()

        if (PermissionX.isGranted(context, PermissionX.permission.POST_NOTIFICATIONS)) {
            notificationManager.notify(notification_id, customNotification)
        } else {
            "发送通知,但是没有权限".log()
        }
    }

    private fun getRemoteView(sceneCode: String): RemoteViews {
        val remoteViews = RemoteViews(ApiUtlis.packageName, R.layout.notification_layout)
        when (sceneCode) {
            scene_code_cid -> {
                remoteViews.setImageViewResource(R.id.iv, R.drawable.ic_notification_1)
            }
            scene_code_red -> {
                remoteViews.setImageViewResource(R.id.iv, R.drawable.ic_notification_2)
            }
            else -> {
                remoteViews.setImageViewResource(R.id.iv, R.drawable.ic_notification_3)
            }
        }
        return remoteViews
    }
}
关于通知需要注意的地方:
  1. android 8.0以上需要创建通知渠道
  2. pendingIntent创建的flag,需要适配不同版本。传的flag不对,导致intent携带的数据不能获取到,从而无法处理额外的逻辑
  3. 从onCreate中获取点击通知传递的数据:val from = intent.getStringExtra(key)
 3.快捷方式
import android.content.Intent
import android.os.Build
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat
import com.choryan.quan.videowzproject.R
import com.choryan.quan.videowzproject.activity.ActivityStart
import com.choryan.quan.videowzproject.base.AppBase

/**
 * 描述:快捷方式
 * 作者: shawn
 * 时间: 2024/6/312:04
 */
object UtilShortcut {
    val context = AppBase.instance
    const val action_key = "shortcut_action_key"
    const val action_id_1 = "shortcut_action_1"
    const val action_id_2 = "shortcut_action_2"

    fun initShortcut() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
            val id1 = action_id_1
            val intent1 = Intent(Intent.ACTION_MAIN, null, context, ActivityStart::class.java).apply {
                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                putExtra(action_key, id1)
            }
            val short1 = ShortcutInfoCompat.Builder(context, id1)//唯一标识id
                .setShortLabel(context.getString(R.string.shortcut_label_1))//短标签
                .setIcon(IconCompat.createWithResource(context, R.drawable.ic_shortcut_1))//图标
                //跳转的目标,定义Activity
                .setIntent(intent1)
                .build()
            val id2 = action_id_2
            val intent2 = Intent(Intent.ACTION_MAIN, null, context, ActivityStart::class.java).apply {
                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                putExtra(action_key, id2)
            }
            val short2 = ShortcutInfoCompat.Builder(context, id2)//唯一标识id
                .setShortLabel(context.getString(R.string.shortcut_label_2))//短标签
                .setIcon(IconCompat.createWithResource(context, R.drawable.ic_shortcut_2))//图标
                // 跳转的目标,定义Activity
                .setIntent(intent2)
                .build()
            // 执行添加操作
            ShortcutManagerCompat.addDynamicShortcuts(context, mutableListOf(short1, short2))
        }
    }
}
点击快捷方式跳转:
//在onCreate中获取数据
val value = _intent.extras?.getString(UtilShortcut.action_key)
注意:
  • 给intent添加flags:Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK,因为有些系统只会把应用从后台拉到前台,相关的生命周期和事件并不会触发。不符合需求的预期
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值