一直在尝试解决这个问题,但没能解决。这是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)
}'''
片段
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'
但是显示这个错误
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启动器代码
除了@Ashvinsolanki的答案,你可能需要增加版本的实现"androidx.work: work-runtime-ktx: 2.5.0"
到最新的更新
这是更好的方法
private val flags = when{
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ->
PendingIntent.FLAG_MUTABLE
else -> {PendingIntent.FLAG_MUTABLE}
}
裁判:https://developer.android.com/reference/android/app/PendingIntent#FLAG_MUTABLE
指示创建的PendingIntent应该是可变的标志。此标志不能与FLAG_IMMUTABLE
组合。
直到< code >构建。版本代码。R,除非设置了FLAG_IMMUTABLE,否则默认情况下假定PendingIntents是可变的。从构建开始。版本代码。s,则需要在创建时用< code >(@ link # FLAG _ IMMUTABLE } 或< code>FLAG_MUTABLE显式指定PendingIntents的可变性。强烈建议在创建PendingIntent时使用< code>FLAG_IMMUTABLE。< code>FLAG_MUTABLE应仅在某些功能依赖于修改底层意图时使用,例如,任何需要与内联回复或气泡一起使用的< code > pending content 。
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
应用程序在运行时崩溃,出现以下错误: java.lang.非法参数异常:maa.abc:目标 S(版本 31 及更高版本)要求在创建挂起的意外时指定FLAG_IMMUTABLE或FLAG_MUTABLE之一。强烈建议使用FLAG_IMMUTABLE,仅当某些功能依赖于 PendingIntent 是可变的(例如,如果需要将其与内联回复或气泡一起使用)时才使用FLAG_MUTABLE。at andr
需要帮助。我从三星手机用户那里得到标题中描述的崩溃。我已经将< code>FLAG_IMMUTABLE作为< code>myFlags或FLAG_IMMUTABLE添加到我的所有PendingIntents中。我的Pixel 3上的应用程序没有崩溃。我试图添加< code > work manager 2 . 7 . 0版,这是在其他类似问题的答案中推荐的,但它仍然崩溃。 有人对此有什么提示吗?
当我在android 12中启动我的应用程序时,它崩溃了,并给了我这个错误,我的项目已经有了这个依赖 我更新了 firebase消息库 我在我的项目中使用了待处理的意图,就像这样 错误:
应用程序在运行时崩溃并出现以下错误: 以S为目标(31版及更高版本)要求在创建PendingIntent时指定FLAG_IMMUTABLE或FLAG_MUTABLE之一。强烈考虑使用FLAG_IMMUTABLE,仅当某些功能依赖于PendingIntent是可变的时才使用FLAG_MUTABLE,例如,如果它需要与内联回复或气泡一起使用。 我尝试了所有可用的解决方案,但该应用程序在Android
我正在使用Facebook Audience Network通过该应用程序获利,但最近在将targetSdkVersion升级到31后,我在crashlytics中遇到了巨大的问题,我使用此依赖项 我用这个代码片段代码初始化了我的应用程序 应用程序类 但问题只出现在AndroidS中 这是日志报告: 请有人帮帮我