Android 12でのManifest merger failedエラー解決方法
問題
Android 12 (APIレベル31) をターゲットとするアプリをビルドする際に、以下のエラーが発生する場合があります:
Manifest merger failed: Apps targeting Android 12 and higher are required to specify an explicit value for `android:exported` when the corresponding component has an intent filter defined.
このエラーは、インテントフィルターを持つアクティビティ、サービス、ブロードキャストレシーバーに対して、android:exported
属性の明示的な宣言が必須となったAndroid 12の新しいセキュリティ要件に起因しています。
android:exported
属性とは
android:exported
属性は、コンポーネント(アクティビティ、サービス、ブロードキャストレシーバーなど)が他のアプリケーションのコンポーネントから起動できるかどうかを制御します:
- true: 任意のアプリがアクティビティにアクセスし、正確なクラス名で起動できます
- false: 同じアプリケーションのコンポーネント、同じユーザーIDを持つアプリケーション、または特権システムコンポーネントのみがアクティビティを起動できます
Android 12以前では、この属性のデフォルト値はコンポーネントの種類やAndroidバージョンによって異なりましたが、Android 12以降ではインテントフィルターを持つすべてのコンポーネントに対して明示的な宣言が必須となりました。
解決方法
1. メインアクティビティの修正
ランチャーアクティビティ(アプリ起動時に最初に表示されるアクティビティ)にはandroid:exported="true"
を設定する必要があります:
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.MyApplication.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
2. 他のアクティビティの修正
ランチャー以外のアクティビティでは、通常android:exported="false"
を設定します:
<activity
android:name=".SecondaryActivity"
android:exported="false" />
3. ブロードキャストレシーバーの修正
インテントフィルターを持つブロードキャストレシーバーにもandroid:exported
属性が必要です:
<receiver
android:name=".BootReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
4. サービスの修正
インテントフィルターを持つサービスも同様に対応が必要です:
<service
android:name=".MyService"
android:exported="true" />
詳細な確認方法
重要
単純にすべてのコンポーネントにandroid:exported="true"
を設定することはセキュリティリスクになる可能性があります。各コンポーネントの役割に応じて適切な値を設定してください。
マージされたマニフェストの確認
Android Studioでは、マージされたマニフェストを確認することで、どのコンポーネントにandroid:exported
属性がないかを特定できます:
AndroidManifest.xml
ファイルを開く- 下部の「Merged Manifest」タブをクリック
- エラーや警告を確認し、該当するコンポーネントを修正する
サードパーティライブラリの問題
場合によっては、サードパーティライブラリが原因でこのエラーが発生することがあります。その場合の対処方法:
- ライブラリの更新: 使用しているライブラリの最新バージョンに更新する
- マニフェストのオーバーライド: メインのマニフェストでライブラリのコンポーネントをオーバーライドする
<!-- ライブラリのコンポーネントをオーバーライドする例 -->
<activity
android:name="com.example.library.SomeActivity"
android:exported="false"
tools:replace="exported" />
ビルド設定の確認
build.gradle
ファイルで正しいターゲットSDKバージョンを設定しているか確認してください:
android {
compileSdkVersion 32
// ...
defaultConfig {
minSdkVersion 21
targetSdkVersion 32
// ...
}
}
まとめ
Android 12の新しいセキュリティ要件に対応するために、すべてのインテントフィルターを持つコンポーネントに明示的にandroid:exported
属性を設定する必要があります。この変更はアプリのセキュリティを強化するためのものなので、各コンポーネントの役割を理解した上で適切な値を設定することが重要です。
ヒント
プロジェクトが大きく複数のマニフェストファイルがある場合、Gradleタスクを利用して自動的にandroid:exported
属性を追加する方法もあります。