A new PendingIntent field in PendingIntent is FLAG_IMMUTABLE.
In 31, you must specify MUTABLE or IMMUTABLE, or you can't create the PendingIntent, (Of course we can't have defaults, that's for losers) as referenced here
According to the (hilarious) Google Javadoc for Pendingintent, you should basically always use 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?).
Right, so i've always created PendingIntents for a Geofence like this:
PendingIntent proximityIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_NO_CREATE)
Always worked fine. However, following the docs above, i added the IMMUTABLE flag like this:
PendingIntent proximityIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_IMMUTABLE)
Now, what that results in is that while i still the geofence transitions in my Receiver, if i call
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
It returns null!
So, i have two questions.
Why does the IMMUTABLE flag result in that i don't get the triggering geofence as i have in the past?
Am i doing something wrong? Is there a way to do set IMMUTABLE with Geofence triggers?
Actually, i have three questions:
Pointers much appreciated.
In this case, the pending intent for the geofence needs to use FLAG_MUTABLE
while the notification pending intent needs to use FLAG_IMMUTABLE
. Unfortunately, they have not updated the documentation or the codelabs example for targeting Android 12 yet. Here's how I modified the codelabs geofence example to work.
First, update gradle to target SDK31.
In HuntMainActivity
, change the geofencePendingIntent
to:
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)
}
}
In NotificationUtils.kt
, update the notifications pending intent as follows:
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
)
}