PendingIntentのFLAG_IMMUTABLEとFLAG_MUTABLE

Target SDK 31(Android 12)から PendingIntent のmutability(可変性)を指定する必要があります。

https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability

指定するときに FLAG_IMMUTABLEFLAG_MUTABLE のどちらかの値を使用することになります。

この2つのフラグの違いについて解説します。

コード例

まずは動作確認用として、Activityから別のActivityにPendingIntentを渡して、そのPendingIntentを実行する例です。

まずはPendingIntentを作って、それを別のActivityに渡すコードです。

次に、起動されたActivity側でPendingIntentを受け取り、PendingIntentに関連付けられてるIntentを実行するコードです。

PendingIntent.send で関連付けられてるIntentを起動することができます。

これを実行すると新しくActivityが表示される感じになります。

これをベースに考えていきます。

FLAG_IMMUTABLE と FLAG_MUTABLE

先程のコードだと、FLAG_IMMUTABLEFLAG_MUTABLE では結果に違いがありません。

PendingIntent.send では関連付けられてるIntentに対してパラメータを追加することが出来ます。以下のように新しくIntentを作り、それを PendingIntent.send に渡してあげます。(Intent.fillIn と同じことが行われています)

これにより、起動される側(今回の例ではMainActivity)で追加されたパラメータが取得できるようになります。

FLAG_IMMUTABLEFLAG_MUTABLEPendingIntent.send に渡された追加のIntentを無視するかどうかのフラグになります。

FLAG_IMMUTABLE を指定すると、パラメータを追加をしたとしても、元々のIntentは変更はされず、起動された側でも取得できずにnullになります。

ほとんどケースで FLAG_IMMUTABLE を指定することになると思います。

FLAG_MUTABLE を指定すると、変更が可能となり、先程のパラメータを追加したときに、起動された側で取得することが出来ます。

あまり自分で実装することは無いですが、通知のDirect reply actionなどのいくつかケースでは FLAG_MUTABLE を指定する必要があります。詳しくはドキュメントを確認してみてください。

Androidのバージョンによる違い

このフラグは Target SDK 31の場合は必須となっているため、実行時にエラーになってしまいます。そのためどちらかを必ず指定する必要があります。

Target SDK 31未満のデフォルトは、FLAG_MUTABLE と同じ挙動となっています。

参考

Programmer / Gamer / Google Developers Expert for Android, Kotlin / @STAR_ZERO