如何解决此问题 目标 S+(版本 31 及更高版本)要求 FLAG_IMMUTABLE 或 FLAG_MUTABLE 之一

2024-04-27

一直试图解决这个问题但无法解决。这是 udacity 课程,我尝试使用挂起意图创建通知,但挂起意图可变存在问题,我尝试用这种方式

视图模型

private val REQUEST_CODE = 0
private val TRIGGER_TIME = "TRIGGER_AT"

private val minute: Long = 60_000L
private val second: Long = 1_000L

private val timerLengthOptions: IntArray
private val notifyPendingIntent: PendingIntent

private val alarmManager = app.getSystemService(Context.ALARM_SERVICE) as AlarmManager
private var prefs =
    app.getSharedPreferences("com.shivaConsulting.androidProjects.kotlinnotificatons", Context.MODE_PRIVATE)
private val notifyIntent = Intent(app, AlarmReciever::class.java)

private val _timeSelection = MutableLiveData<Int>()
val timeSelection: LiveData<Int>
    get() = _timeSelection

private val _elapsedTime = MutableLiveData<Long>()
val elapsedTime: LiveData<Long>
    get() = _elapsedTime

private var _alarmOn = MutableLiveData<Boolean>()
val isAlarmOn: LiveData<Boolean>
    get() = _alarmOn


private lateinit var timer: CountDownTimer


init {
    _alarmOn.value = PendingIntent.getBroadcast(
        getApplication(),
        REQUEST_CODE,
        notifyIntent,
        PendingIntent.FLAG_NO_CREATE
    ) != null

    notifyPendingIntent = PendingIntent.getBroadcast(
        getApplication(),
        REQUEST_CODE,
        notifyIntent,
        PendingIntent.FLAG_UPDATE_CURRENT
    )

    timerLengthOptions = app.resources.getIntArray(R.array.minutes_array)

    //If alarm is not null, resume the timer back for this alarm
    if (_alarmOn.value!!) {
        createTimer()
    }

}

/**
 * Turns on or off the alarm
 *
 * @param isChecked, alarm status to be set.
 */
fun setAlarm(isChecked: Boolean) {
    when (isChecked) {
        true -> timeSelection.value?.let { startTimer(it) }
        false -> cancelNotification()
    }
}

/**
 * Sets the desired interval for the alarm
 *
 * @param timerLengthSelection, interval timerLengthSelection value.
 */
fun setTimeSelected(timerLengthSelection: Int) {
    _timeSelection.value = timerLengthSelection
}

/**
 * Creates a new alarm, notification and timer
 */
private fun startTimer(timerLengthSelection: Int) {
    _alarmOn.value?.let {
        if (!it) {
            _alarmOn.value = true
            val selectedInterval = when (timerLengthSelection) {
                0 -> second * 10 //For testing only
                else ->timerLengthOptions[timerLengthSelection] * minute
            }
            val triggerTime = SystemClock.elapsedRealtime() + selectedInterval

            // TODO: Step 1.5 get an instance of NotificationManager and call sendNotification

            // TODO: Step 1.15 call cancel notification

            AlarmManagerCompat.setExactAndAllowWhileIdle(
                alarmManager,
                AlarmManager.ELAPSED_REALTIME_WAKEUP,
                triggerTime,
                notifyPendingIntent
            )

            viewModelScope.launch {
                saveTime(triggerTime)
            }
        }
    }
    createTimer()
}

/**
 * Creates a new timer
 */
private fun createTimer() {
    viewModelScope.launch {
        val triggerTime = loadTime()
        timer = object : CountDownTimer(triggerTime, second) {
            override fun onTick(millisUntilFinished: Long) {
                _elapsedTime.value = triggerTime - SystemClock.elapsedRealtime()
                if (_elapsedTime.value!! <= 0) {
                    resetTimer()
                }
            }

            override fun onFinish() {
                resetTimer()
            }
        }
        timer.start()
    }
}

/**
 * Cancels the alarm, notification and resets the timer
 */
private fun cancelNotification() {
    resetTimer()
    alarmManager.cancel(notifyPendingIntent)
}

/**
 * Resets the timer on screen and sets alarm value false
 */
private fun resetTimer() {
    timer.cancel()
    _elapsedTime.value = 0
    _alarmOn.value = false
}

private suspend fun saveTime(triggerTime: Long) =
    withContext(Dispatchers.IO) {
        prefs.edit().putLong(TRIGGER_TIME, triggerTime).apply()
    }

private suspend fun loadTime(): Long =
    withContext(Dispatchers.IO) {
        prefs.getLong(TRIGGER_TIME, 0)
    }'''

Fragment

class BlankFragment : Fragment() {

companion object {
    fun newInstance() = BlankFragment()
}
private val viewModel : BlankViewModel by lazy {
    ViewModelProvider(this).get(BlankViewModel::class.java)
}

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val binding = FragmentBlankBinding.inflate(inflater)
    binding.lifecycleOwner = this
    binding.blankViewModel = viewModel
  
    return binding.root
} '''

当我正在研究由 gradle 依赖项解决的其他类似问题时,我已经添加了这一点

 implementation 'androidx.work:work-runtime-ktx:2.7.1'  

但显示这个error

E/AndroidRuntime: Caused by: java.lang.IllegalArgumentException: com.shivaconsulting.kotlinnotifications: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
    Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
        at android.app.PendingIntent.checkFlags(PendingIntent.java:378)
        at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:648)
        at android.app.PendingIntent.getBroadcast(PendingIntent.java:635)
        at com.shivaconsulting.kotlinnotifications.ui.BlankViewModel.<init>(BlankViewModel.kt:52)
            ... 44 more

Udacity 起始代码 https://github.com/udacity/android-kotlin-notifications/blob/start/app/src/main/java/com/example/android/eggtimernotifications/ui/EggTimerViewModel.kt


Ref : https://developer.android.com/reference/android/app/PendingIntent#FLAG_MUTABLE https://developer.android.com/reference/android/app/PendingIntent#FLAG_MUTABLE

指示创建的 PendingIntent 应该是可变的标志。该标志不能与FLAG_IMMUTABLE.

直到......为止Build.VERSION_CODES.R,默认情况下,PendingIntents 被假定为可变的,除非设置了 FLAG_IMMUTABLE。从 Build.VERSION_CODES.S 开始,需要在创建时显式指定 PendingIntents 的可变性(@link #FLAG_IMMUTABLE} or FLAG_MUTABLE。强烈建议使用FLAG_IMMUTABLE创建 PendingIntent 时。FLAG_MUTABLE仅当某些功能依赖于修改底层意图时才应使用,例如任何PendingIntent需要与内联回复或气泡一起使用。

    notifyPendingIntent = PendingIntent.getBroadcast(
            getApplication(),
            REQUEST_CODE,
            notifyIntent,
            PendingIntent.FLAG_UPDATE_CURRENT
        )

代码应该是。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
 notifyPendingIntent = PendingIntent.getBroadcast(
            getApplication(),
            REQUEST_CODE,
            notifyIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
        )
    } else {
      notifyPendingIntent = PendingIntent.getBroadcast(
            getApplication(),
            REQUEST_CODE,
            notifyIntent,
            PendingIntent.FLAG_UPDATE_CURRENT
        )
    }

你必须以同样的方式

_alarmOn.value = PendingIntent.getBroadcast(
        getApplication(),
        REQUEST_CODE,
        notifyIntent,
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_NO_CREATE or PendingIntent.FLAG_MUTABLE else PendingIntent.FLAG_NO_CREATE
    ) != null

Edit 2

另外,如果您没有使用 PendingIntent 并且在使用其他组件(例如MediaSessionCompat etc.

implementation 'androidx.work:work-runtime-ktx:RUNTIME-VERSION'

运行时版本:https://developer.android.com/jetpack/androidx/releases/work https://developer.android.com/jetpack/androidx/releases/work

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何解决此问题 目标 S+(版本 31 及更高版本)要求 FLAG_IMMUTABLE 或 FLAG_MUTABLE 之一 的相关文章

  • android studio 和 android SDK 捆绑的 eclipse 版本有什么区别

    我没有 Android 开发经验 我想开始编写应用程序 The 官方开发者工具页面 http developer android com tools index html包含两个不同 IDE 的链接 第一个包含捆绑的 ADT 版本Eclip
  • Firebase FCM 通知图像不会显示

    我在我的项目中使用 FCM 当尝试使用 firebase 撰写通知 功能测试传入通知时 我将标题 正文和图像 URL 添加到消息中 它显示了它应该是什么样子 丰富的通知与图像 但发送给我的通知是正常的 没有任何图像 这是 firebase
  • 安卓多点触控?

    作为一名开发人员 我倾向于先编程 然后再研究 我试图实现一个可以处理多个用户输入的屏幕 基本上映射的不仅仅是一根手指 我尝试了两件事 我有一个实现 OnTouchListener 的 Activity 类 这里我有两个单独的子视图 它们将
  • 在 Android 中使用 Facebook Achievement API

    我知道这可能看起来像一个通用问题 但找到有关该主题的信息似乎非常困难 因此 如果某个地方存在完整的示例 指南 源代码链接 我将不胜感激 我正在开发一款 Android 游戏 希望集成 Facebook 成就 我想要的只是在用户完成某个谜题时
  • 无法解析导航抽屉中片段中的 getSystemService

    我正在尝试实现一个导航抽屉 其中有一个片段中的地图 这是我的代码 这里是fragment map xml
  • Android 中的 ImageView 拖动限制

    我在布局中有一个 ImageView 并在 ImageView 上设置 OnTouchListener 来拖动 ImageView 它工作得很好 我的问题是如何防止将 ImageView 移动到布局范围之外 这是我的代码 活动类别 publ
  • 使用Web蓝牙API时找不到移动设备

    我正在学习 Web 蓝牙 API 使用 google 开发控制台 我无法找到我的移动设备 还尝试了 github 上提供的演示 https github com WebBluetoothCG demos https github com W
  • 带有电子墨水显示屏的 Android

    我有兴趣使用 AndroidE Ink http www eink com technology howitworks html为基础的平台 我知道已经是证明了 http vimeo com 3162590MOTO 曾经使用过 但我有兴趣将
  • ListView 中的焦点控件

    上下文 我想要一个不会获得焦点的 ListView 例如不会 当用户触摸它时突出显示该行 然而每个行小部件都有它自己的 OnClickListener 这是我在布局 xml 中指定的内容 android choiceMode none an
  • React Native:即使文件不存在,也会出现 hprof 文件太大错误

    当我尝试跑步时git push origin master在我的 React Native 应用程序中 我得到 file android java pid60072 hprof is 564 94 MB this exceeds GitHu
  • 如何通过代码改变Android SlidingDrawer的方向?

    当我从横向模式更改为纵向模式时 我无法找到设置 SlidingDrawer 方向的方法 反之亦然 最初我将 xml 的方向设置为垂直 当手机处于横向模式时 我需要将方向更改为水平 因此我将手柄放在左侧 有人有什么想法吗 我认为按照标准这是不
  • 在基本模块中找不到动态功能模块中的 Android 提供程序

    我在动态功能模块中使用了一些库 这些库正在将一些提供程序添加到清单中 例如在我的动态模块中的 build gradle 文件中 dependencies implementation com github esafirm android i
  • 如何从其他 Activity 类访问 Activity 的视图

    我的问题是当我更改文本时TextView在我的主类中 它返回 nullPointerException 这是我的代码 main xml
  • 处理网络视图中的链接

    我有我的WebView加载网络视图中的所有链接 但是当我选择电子邮件链接时 它会尝试将其加载到网络视图中 而不是在手机上启动电子邮件应用程序 我该如何解决这个问题 链接是mailto 电子邮件受保护 cdn cgi l email prot
  • 使用 jenkins.Creating .apk 文件生成 android 版本

    我正在使用 Jenkins 在 mac 上持续集成 android 应用程序 但是我无法使用 Jenkins 生成 apk 文件 就像我们在 iOS 应用程序中创建 ipa 一样 创建用于在 mac 上分发的 apk 文件的配置是什么 您可
  • java.net.ServerSocket.accept () 在 Android 上不返回

    我正在尝试找到一种方法来远程登录到未root的机器人 我有INTERNET权限处于活动状态 我的设备与我的设备连接在同一网络上Mac OS X通过 WiFi 我可以 ping 通我打开的端口 在最初的实验中 我让它在有根测试设备上工作 但我
  • 在 Android 中使用 SQL (JDBC) 数据库

    在旧的 Java 应用程序中 我使用以下代码连接到 SQL 数据库并将其用于某些查询 private Connection dbConnection null System setProperty derby system home C C
  • smoothScrollToPosition() 在 Android ICS 中只能滚动到一半?

    在 Gingerbread 中 我使用 smoothScrollToPosition 一次滚动数十个项目没有任何问题 在我的 Nexus S 升级到 Ice Cream Sandwich 后 我注意到无论我在 smoothScrollToP
  • ContactsContract.CommonDataKinds.Phone.CONTENT_URI 与 ContactsContract.Contacts.CONTENT_URI

    In 如何在android中检索联系人列表 https stackoverflow com questions 16124034 how to retrieve the list of contacts in android我看到代码允许您
  • Android 如何在按下或聚焦时使 TextView 文本变为粗体

    我的布局中有一个文本视图 我的要求是当我按下或聚焦它时 文本应该是粗体 否则应该使用普通字体 我该如何实施 使用下面的代码 TextView name TextView findViewById R id TextView01 name h

随机推荐