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,因为有些系统只会把应用从后台拉到前台,相关的生命周期和事件并不会触发。不符合需求的预期

相关推荐

  1. android使用通知快捷方式

    2024-06-08 01:16:06       8 阅读
  2. Android使用USB进行通信的4种方式

    2024-06-08 01:16:06       9 阅读
  3. Android 通知使用总结

    2024-06-08 01:16:06       33 阅读
  4. 通过 CLI 引入的方式使用 React:基础入门

    2024-06-08 01:16:06       15 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-08 01:16:06       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-08 01:16:06       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-08 01:16:06       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-08 01:16:06       18 阅读

热门阅读

  1. accelerate 的一个tip:early stopping 处可能存在的bug

    2024-06-08 01:16:06       7 阅读
  2. Go语言中,公司gitlab私有仓库依赖拉取配置

    2024-06-08 01:16:06       9 阅读
  3. 【读脑仪game】

    2024-06-08 01:16:06       5 阅读
  4. 煮粽子(zongzi)

    2024-06-08 01:16:06       9 阅读
  5. WM_COMMAND

    2024-06-08 01:16:06       6 阅读
  6. Python爬虫小练习

    2024-06-08 01:16:06       10 阅读
  7. 【html】简单网页模板源码

    2024-06-08 01:16:06       8 阅读
  8. 语言模型解构——手搓BPE算法

    2024-06-08 01:16:06       8 阅读