7

PendingIntent 中的一个新 PendingIntent 字段是 FLAG_IMMUTABLE。

31中,必须指定MUTABLE或IMMUTABLE,否则不能创建PendingIntent,(当然我们不能有默认值,那是给loser的)参考这里

根据(热闹的)Google Javadoc for Pendingintent,您基本上应该始终使用 IMMUTABLE(empasis mine):

强烈建议在创建 PendingIntent 时使用 FLAG_IMMUTABLE。FLAG_MUTABLE 仅应在某些功能依赖于修改底层意图时使用,例如任何需要与内联回复或气泡一起使用的PendingIntent (编辑评论:什么?)。

对,所以我总是为这样的地理围栏创建 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();

它返回空!

所以,我有两个问题。

  1. 为什么 IMMUTABLE 标志导致我没有像过去那样获得触发地理围栏?

  2. 难道我做错了什么?有没有办法用地理围栏触发器设置 IMMUTABLE?

其实我有三个问题:

  1. 为什么 Google 的文档如此混乱、糟糕、矛盾和落后?(这是一个反问句)

非常感谢指针。

4

1 回答 1

12

在这种情况下,地理围栏的待处理意图需要使用FLAG_MUTABLE,而通知待处理意图需要使用FLAG_IMMUTABLE。不幸的是,他们尚未更新针对 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中,更新通知待处理意图,如下所示:

  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
    )
  }
于 2021-10-27T21:22:25.063 回答