android 12のandroid:exportedエラー解決方法
Android 12(APIレベル31)以降をターゲットとするアプリケーションでは、マニフェストファイルのコンポーネント(Activity、Service、Receiverなど)がインテントフィルターを含む場合、android:exported
属性の明示的な指定が必須となりました。この新しい要件により、多くの開発者がビルドエラーに直面しています。
問題の概要
Android 12以降では、以下のようなエラーメッセージが表示されます:
"Manifest merger failed with multiple errors, see logs"
"Merging Errors: Error: android:exported needs to be explicitly specified for <activity>. 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
属性は、コンポーネントが他のアプリからアクセス可能かどうかを制御します。
true
: 他のアプリからアクセス可能false
: 同一アプリ内でのみアクセス可能
解決方法
方法1: マニフェストファイルの直接修正
すべてのActivity、Service、Receiver、Providerコンポーネントでandroid:exported
属性を明示的に設定します。
<!-- ランチャーActivity(外部からアクセス可能) -->
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 内部専用Service(外部からアクセス不可) -->
<service
android:name=".MyService"
android:exported="false" />
<!-- ブロードキャストレシーバー -->
<receiver
android:name=".MyReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
方法2: マージされたマニフェストの確認と修正
WARNING
サードパーティライブラリが原因でエラーが発生する場合があります。
マージされたマニフェストの確認
- Android Studioで
AndroidManifest.xml
を開く - 下部の「Merged Manifest」タブを選択
- エラーがあるコンポーネントを特定する
- Android Studioで
ライブラリのマニフェストをオーバーライド
xml<!-- サードパーティライブラリのコンポーネントをオーバーライド --> <receiver android:name="com.some.library.ComponentName" android:exported="false" tools:node="merge" tools:overrideLibrary="com.some.library" />
方法3: テスト依存関係の更新
テストライブラリが古い場合にもこの問題が発生することがあります:
dependencies {
androidTestImplementation 'androidx.test:core:1.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
方法4: 特定のライブラリの問題に対するワークアラウンド
INFO
よく問題が報告されるライブラリとその解決策:
Razorpayの場合:
<receiver
android:name="com.razorpay.RzpTokenReceiver"
android:exported="false">
<intent-filter>
<action android:name="rzp.device_token.share" />
</intent-filter>
</receiver>
<activity
android:name="com.razorpay.CheckoutActivity"
android:exported="true"
android:theme="@style/CheckoutTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<data
android:host="rzp.io"
android:scheme="io.rzp" />
</intent-filter>
</activity>
OneSignalの場合:
<receiver android:name="com.onesignal.BootUpReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<receiver android:name="com.onesignal.UpgradeReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
デバッグ手順
問題の根本原因を特定するには:
一時的にターゲットSDKを下げる
gradleandroid { defaultConfig { targetSdkVersion 30 } }
マージされたマニフェストを確認
- ビルド後に生成されるマージされたマニフェストを確認
- パス:
app/build/intermediates/merged_manifest/debug/AndroidManifest.xml
エラーのあるコンポーネントを特定
- インテントフィルターありで
android:exported
属性なしのコンポーネントを探す
- インテントフィルターありで
修正後にターゲットSDKを戻す
gradleandroid { defaultConfig { targetSdkVersion 31 } }
ベストプラクティス
セキュリティ原則
- 必要な場合のみ
android:exported="true"
を設定 - デフォルトは
false
にすることが推奨
- 必要な場合のみ
ライブラリの更新
- 定期的に依存ライブラリを更新
- Android 12対応の最新バージョンを利用
包括的なテスト
- エクスポートされたコンポーネントのセキュリティテストを実施
- 意図しない外部アクセスがないことを確認
よくある質問
Q: すべてのコンポーネントにandroid:exportedを設定する必要がありますか? A: インテントフィルターを持つコンポーネントのみ必須です。それ以外のコンポーネントはオプションですが、明示的な設定が推奨されます。
Q: サードパーティライブラリの問題はどう対処すべきですか? A: 一時的にマニフェストでオーバーライドし、ライブラリの更新版がリリースされたら移行してください。
Q: 一時的にターゲットSDKを下げるのは安全ですか? A: 開発中の一時的な措置として有効ですが、ストアへの提出前にはAndroid 12対応を完了させる必要があります。
まとめ
Android 12のandroid:exported
要件はアプリのセキュリティを強化するための重要な変更です。マニフェストファイルのコンポーネントを適切に設定し、サードパーティライブラリの問題に対処することで、この新しい要件に準拠したアプリを開発できます。
詳細はAndroid Developersの公式ドキュメントを参照してください。