android - 在 Android 12/API 31 中,地理围栏不适用于 IMMUTABLE 未决 Intent 。为什么?

标签 android android-pendingintent android-geofence android-12

PendingIntent 中的一个新 PendingIntent 字段是 FLAG_IMMUTABLE。
在31中,必须指定MUTABLE或IMMUTABLE,否则不能创建PendingIntent,(当然我们不能有默认值,那是给loser的)引用here
根据(热闹的)Google Javadoc for Pendingintent,您基本上应该始终使用 IMMUTABLE(empasis mine):

It is strongly recommended to use FLAG_IMMUTABLE when creating a PendingIntent. FLAG_MUTABLE should only be used when some functionality relies on modifying the underlying intent, e.g. any PendingIntent that needs to be used with inline reply or bubbles (editor's comment: WHAT?).


对,所以我总是为这样的地理围栏创建 PendingIntents:
PendingIntent proximityIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_NO_CREATE)
一直工作得很好。但是,按照上面的文档,我添加了 IMMUTABLE 标志,如下所示:
PendingIntent proximityIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_IMMUTABLE)

现在,结果是,虽然我仍然在接收器中进行地理围栏转换,但如果我打电话
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
它返回空!
所以,我有两个问题。
  • 为什么 IMMUTABLE 标志导致我没有像过去那样获得触发地理围栏?
  • 难道我做错了什么?有没有办法用地理围栏触发器设置 IMMUTABLE?

  • 其实我有三个问题:
  • 为什么 Google 的文档如此困惑、糟糕、矛盾和落后? (这是一个反问)

  • 非常感谢指针。

    最佳答案

    在这种情况下,地理围栏的待定 Intent 需要使用 FLAG_MUTABLE而通知待处理 Intent 需要使用FLAG_IMMUTABLE .不幸的是,他们没有更新 documentationcodelabs example还针对 Android 12。以下是我修改 codelabs 地理围栏示例以使其工作的方式。
    首先,将 gradle 更新为目标 SDK31。
    HuntMainActivity ,更改geofencePendingIntent至:

      private val geofencePendingIntent: PendingIntent by lazy {
        val intent = Intent(this, GeofenceBroadcastReceiver::class.java)
        intent.action = ACTION_GEOFENCE_EVENT
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
          PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
        } else {
          PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        }
      }
    
    NotificationUtils.kt ,更新通知待定 Intent ,如下所示:
      val contentIntent = Intent(context, HuntMainActivity::class.java)
      contentIntent.putExtra(GeofencingConstants.EXTRA_GEOFENCE_INDEX, foundIndex)
      val contentPendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        PendingIntent.getActivity(
          context,
          NOTIFICATION_ID,
          contentIntent,
          PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
      } else {
        PendingIntent.getActivity(
          context,
          NOTIFICATION_ID,
          contentIntent,
          PendingIntent.FLAG_UPDATE_CURRENT
        )
      }
    

    关于android - 在 Android 12/API 31 中,地理围栏不适用于 IMMUTABLE 未决 Intent 。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69615196/

    相关文章:

    android - 为什么我的接收器收不到广播?

    Android:在同一应用程序中为其他用户测试地理围栏

    android - 触发后移除地理围栏

    java - 如何使用 AChartEngine 绘制双 Y 轴(辅助 Y 轴) - Android

    android - 如何设置EditText的默认键盘

    android - Mvvm协程Mockito测试ViewModel给出错误

    java - A Switch Java 问题 : case expressions must be constant expressions

    android - 从通知栏与 AsyncTask 交互

    android - 无法从 Android 10 上的 BroadcastReceiver 启动 Activity

    android - 当手机靠近监控位置时,Android ProximityAlert 或 Geofence 会消耗更多电池吗?