Skip to content

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属性を明示的に設定します。

xml
<!-- ランチャー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

サードパーティライブラリが原因でエラーが発生する場合があります。

  1. マージされたマニフェストの確認

    • Android StudioでAndroidManifest.xmlを開く
    • 下部の「Merged Manifest」タブを選択
    • エラーがあるコンポーネントを特定する
  2. ライブラリのマニフェストをオーバーライド

    xml
    <!-- サードパーティライブラリのコンポーネントをオーバーライド -->
    <receiver
        android:name="com.some.library.ComponentName"
        android:exported="false"
        tools:node="merge"
        tools:overrideLibrary="com.some.library" />

方法3: テスト依存関係の更新

テストライブラリが古い場合にもこの問題が発生することがあります:

gradle
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の場合:

xml
<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の場合:

xml
<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>

デバッグ手順

問題の根本原因を特定するには:

  1. 一時的にターゲットSDKを下げる

    gradle
    android {
        defaultConfig {
            targetSdkVersion 30
        }
    }
  2. マージされたマニフェストを確認

    • ビルド後に生成されるマージされたマニフェストを確認
    • パス: app/build/intermediates/merged_manifest/debug/AndroidManifest.xml
  3. エラーのあるコンポーネントを特定

    • インテントフィルターありでandroid:exported属性なしのコンポーネントを探す
  4. 修正後にターゲットSDKを戻す

    gradle
    android {
        defaultConfig {
            targetSdkVersion 31
        }
    }

ベストプラクティス

  1. セキュリティ原則

    • 必要な場合のみandroid:exported="true"を設定
    • デフォルトはfalseにすることが推奨
  2. ライブラリの更新

    • 定期的に依存ライブラリを更新
    • Android 12対応の最新バージョンを利用
  3. 包括的なテスト

    • エクスポートされたコンポーネントのセキュリティテストを実施
    • 意図しない外部アクセスがないことを確認

よくある質問

Q: すべてのコンポーネントにandroid:exportedを設定する必要がありますか? A: インテントフィルターを持つコンポーネントのみ必須です。それ以外のコンポーネントはオプションですが、明示的な設定が推奨されます。

Q: サードパーティライブラリの問題はどう対処すべきですか? A: 一時的にマニフェストでオーバーライドし、ライブラリの更新版がリリースされたら移行してください。

Q: 一時的にターゲットSDKを下げるのは安全ですか? A: 開発中の一時的な措置として有効ですが、ストアへの提出前にはAndroid 12対応を完了させる必要があります。

まとめ

Android 12のandroid:exported要件はアプリのセキュリティを強化するための重要な変更です。マニフェストファイルのコンポーネントを適切に設定し、サードパーティライブラリの問題に対処することで、この新しい要件に準拠したアプリを開発できます。

詳細はAndroid Developersの公式ドキュメントを参照してください。