在 Android 12/API 31 中,地理围栏不适用于 IMMUTABLE 未决意图。为啥?

Posted

技术标签:

【中文标题】在 Android 12/API 31 中,地理围栏不适用于 IMMUTABLE 未决意图。为啥?【英文标题】:In Android 12/API 31, Geofence doesn't work with IMMUTABLE pendingintent. Why?在 Android 12/API 31 中,地理围栏不适用于 IMMUTABLE 未决意图。为什么? 【发布时间】:2021-12-05 10:58:27 【问题描述】:

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

在 31 中,你必须指定 MUTABLE 或 IMMUTABLE,否则你不能创建 PendingIntent,(当然我们不能有默认值,那是给失败者的)参考here

根据(搞笑的)Google Javadoc for Pendingintent,您基本上应该始终使用 IMMUTABLE(empasis 我的):

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

它返回 null!

所以,我有两个问题。

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

    我做错了吗?有没有办法使用地理围栏触发器设置 IMMUTABLE?

其实我有三个问题:

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

非常感谢指针。

【问题讨论】:

这就是人们不再在 Stack Overflow 上提问的原因。 【参考方案1】:

在这种情况下,地理围栏的待处理意图需要使用FLAG_MUTABLE,而通知待处理意图需要使用FLAG_IMMUTABLE。不幸的是,他们尚未针对 android 12 更新 documentation 或 codelabs example。以下是我修改 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
    )
  

【讨论】:

谢谢。不知道为什么会这样......(没有文档帮助)

以上是关于在 Android 12/API 31 中,地理围栏不适用于 IMMUTABLE 未决意图。为啥?的主要内容,如果未能解决你的问题,请参考以下文章

应用程序卡在 Android 12(API 级别 31)的初始屏幕上

在 Android 12 中使用 WorkManager

在 Android 12 中使用 WorkManager

如何在 Android 设备上处理允许/关闭地理位置弹出窗口

HMS Core地理围栏能力助你实现指定范围人群的精准消息推送

在后台服务中创建地理围栏