targetSdkVersionを31にするときの3つの注意点

2022年11月から、GooglePlayストアにアプリのアップデートを公開する場合、targetSdkVersionを31にしないと公開できなくなりました。

機能を追加したし、あとはtargetSdkVersionを上げるだけ・・・
ってビルドできない！動かない！

という事に今回遭遇したので、targetSdkVersionを31にした時の注意点3選を書いていきたいと思います。

# １．Android 12端末でアプリ起動時のIllegalArgumentExceptionに対応する
Android 12端末で起動しようとすると以下のエラーが吐かれてアプリ落ちします。
Android 11以前であれば普通に起動します。
```
Fatal Exception: java.lang.IllegalArgumentException: com.highcom.todolog: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
```
エラー内容と紐づかないのですが調べてみると、`app/build.gradle`に以下のようにandroidx.workのバージョンを明示してあげる事で回避できました。
```gradle
dependencies {
    implementation 'com.google.firebase:firebase-messaging:22.0.0'
・・・
    constraints {
        implementation('androidx.work:work-runtime:2.7.0') {
            because 'previous versions have a bug impacting this application'
        }
    }
・・・
    testImplementation 'junit:junit:4.13.2'
}
```

# 2．RuntimeException: Manifest merger failed with multiple errorsに対応する
`AndroidManifest.xml`に明示的に、`android:exported`の設定をする必要がありました。
これは、インテントフィルタを設定していたり、ブロードキャストレシーバを受信するアクティビティやサービスには、明示的な設定をする必要があります。
自身のアプリ内ではなく、ブロードキャストなど外部から呼び出される場合には、`true`を設定する必要があります。

なので、Widgetなどの機能がある場合には、`true`を設定する必要があります。
```xml
    <application
        android:theme="@style/Theme.ToDoLog">
        <activity android:name=".LogChartActivity"/>
        <activity android:name=".widget.ToDoAppWidgetConfigure"
            android:exported="true">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
            </intent-filter>
        </activity>

        <receiver android:name=".widget.ToDoAppWidgetProvider"
            android:exported="true">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/todo_appwidget_info" />
        </receiver>
    </application>
```

# 3．ウィジェットを配置する時のRuntimeException: Unable to start receiverに対応する
上記２つの対応で起動は出来るようになったのですが、いざウィジェットを配置すると以下のRuntimeExceptionが発生してしまいました。
```
 java.lang.RuntimeException: Unable to start receiver com.highcom.todolog.widget.ToDoAppWidgetProvider: java.lang.IllegalArgumentException: com.highcom.todolog: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
```
PendingIntentを利用する場合、明示的に、`PendingIntent.FLAG_MUTABLE`or`PendingIntent.FLAG_IMMUTABLE`を指定する必要がありました。
アプリを起動するための`intent`に`putExtra`する場合は、`FLAG_MUTABLE`にする必要があります。
```kotlin
    Intent titleIntent = new Intent(context, ToDoMainActivity.class);
    titleIntent.putExtra(ToDoAppWidgetConfigure.SELECT_WIDGET_GROUP_ID, selectGroupId);
    titleIntent.setData(Uri.parse(titleIntent.toUri(Intent.URI_INTENT_SCHEME)));
    PendingIntent titlePendingIntent = TaskStackBuilder.create(context)
            .addNextIntentWithParentStack(titleIntent)
            .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
```


以上、targetSdkVersionを31にした時の３つの注意点でした！