Skip to content

android:exported プロパティの設定と Android 12 対応

問題の概要

Android 12 (API 31) 以降をターゲットとするアプリケーションで、<intent-filter> を含む Activity、Service、Broadcast Receiver コンポーネントに android:exported プロパティが明示的に設定されていない場合、Google Play Store へのアップロードが拒否される問題が発生します。

エラーメッセージ: "You uploaded an APK or Android App Bundle which has an activity, activity alias, service or broadcast receiver with intent filter, but without the 'android: exported' property set. This file can't be installed on Android 12 or higher."

この変更は Android 12 のセキュリティ強化の一環で、アプリコンポーネントの公開範囲を明示的に定義することを義務付けるものです。

基本的な解決方法

1. メインの AndroidManifest.xml の修正

<intent-filter> を含むすべての Activity、Service、Broadcast Receiver に 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">
    <intent-filter>
        <action android:name="com.example.app.ACTION_START" />
    </intent-filter>
</service>

<!-- Broadcast Receiver の例 -->
<receiver
    android:name=".MyReceiver"
    android:exported="false">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

exported の値の設定基準

  • exported="true": 他のアプリからもアクセス可能にする場合(LAUNCHER カテゴリを含む Activity など)
  • exported="false": 自アプリ内でのみ使用する場合

サードパーティライブラリの問題と解決策

多くの場合、問題はアプリ自体のマニフェストではなく、使用しているサードパーティライブラリのマニフェストにあります。

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

Android Studio でマージされたマニフェストを確認し、問題のあるコンポーネントを特定します。

  1. AndroidManifest.xml を開く
  2. 下部の Merged Manifest タブを選択
  3. エラーや警告があるコンポーネントを確認する

Merged Manifest タブ

WARNING

マージされたマニフェストが表示されない場合は、build.gradlecompileSdkVersiontargetSdkVersion を 30 以上に設定してプロジェクトを同期してください。

3. サードパーティライブラリのマニフェスト修正

マージされたマニフェストで問題が見つかった場合、該当するライブラリのコンポーネントをメインのマニフェストでオーバーライドします。

例: Razorpay ライブラリの問題対応

xml
<activity
    android:name="com.razorpay.CheckoutActivity"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
    android:theme="@style/CheckoutTheme"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <data
            android:host="rzp.io"
            android:scheme="io.rzp" />
    </intent-filter>
</activity>

<receiver 
    android:name="com.razorpay.RzpTokenReceiver"
    android:exported="true"
    android:permission="android.permission.INTERNET">
    <intent-filter>
        <action android:name="rzp.device_token.share" />
    </intent-filter>
</receiver>

4. フラッターアプリでの一般的な修正例

通知関連のライブラリでの問題

xml
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
    </intent-filter>
</receiver>

フレームワーク別対応方法

Flutter アプリの場合

  1. android/app/src/main/AndroidManifest.xml を編集
  2. 必要な android:exported 属性を追加
  3. サードパーティライブラリを最新版に更新(特に flutter_local_notifications など)

React Native アプリの場合

xml
<!-- メインアクティビティ -->
<activity
    android:name=".MainActivity"
    android:launchMode="singleTask"
    android:label="@string/app_name"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Unity アプリの場合

  1. プロジェクトを Android Studio 用にエクスポート
  2. launcher/build/intermediates/merged_manifests/release/AndroidManifest.xml を確認
  3. 問題のあるコンポーネントを Assets/Plugin/Android/AndroidManifest.xml でオーバーライド

Cordova/Ionic アプリの場合

config.xml に以下を追加:

xml
<platform name="android">
    <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application/activity" xmlns:android="http://schemas.android.com/apk/res/android">
        <activity android:exported="true" />
    </edit-config>
</platform>

トラブルシューティング

非推奨の回避策

targetSdkVersion を 30 以下に下げる方法は一時的な回避策でしかなく、Google Play ポリシー違反となる可能性があります。

ビルド後のマニフェスト確認方法: ビルド後に生成されるマージされたマニフェストを直接確認する場合は、以下のパスを参照してください:

  • build/app/intermediates/merged_manifests/release/AndroidManifest.xml
  • obj/Release/120/android/manifest/AndroidManifest.xml (Xamarin)

まとめ

Android 12 以降では、<intent-filter> を含むすべてのコンポーネントに android:exported 属性の明示的な設定が必須です。この問題の解決には:

  1. メインのマニフェストファイルの確認と修正
  2. マージされたマニフェストでの問題箇所の特定
  3. サードパーティライブラリのコンポーネントオーバーライド
  4. 必要に応じたライブラリのバージョンアップ

これらの手順を踏むことで、Android 12 の新しいセキュリティ要件を満たし、Google Play Store へのアップロードが可能になります。