Skip to content

AndroidターゲットAPIレベル34への移行時のアプリクラッシュ問題の解決

問題の説明

AndroidアプリをターゲットAPI 33から34(Android 14)にアップグレードした際、以下のようなエラーが発生しアプリがクラッシュする現象が発生します:

java.lang.RuntimeException: Unable to create application com.testreactnative.MainApplication:
Caused by: java.lang.SecurityException: com.testreactnative: 
One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified
when a receiver isn't being registered exclusively for system broadcasts

主な症状:

  • API 33エミュレータでは動作するがAPI 34ではクラッシュ
  • ビルド自体は成功するが起動直後に終了
  • Logcatに上記のセキュリティ例外が出力される
  • BridgeDevSupportManager関連のエラーが併記される場合がある

根本的な原因

Android 14(APIレベル34)から導入されたブロードキャストレシーバーのエクスポート制限が主要因です:

  1. 新セキュリティポリシー: システムブロードキャスト以外のレシーバー登録ではRECEIVER_EXPORTEDまたはRECEIVER_NOT_EXPORTEDの明示必須
  2. 非互換ライブラリ: React Native関連モジュール(react-native-orientation等)が新APIに未対応
  3. Gradle/依存関係: 古いビルドツールや互換性のないライブラリバージョンで発生する二次的エラー

解決策

以下に効果的な解決方法を優先度順に紹介します。


🛠️ 方法1: ブロードキャストレシーバーの明示的エクスポート設定(推奨)

MainApplication.java にオーバーライドメソッドを追加:

java
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import org.jetbrains.annotations.Nullable;

public class MainApplication extends Application {
  // ...
  
  @Override
  public Intent registerReceiver(
    @Nullable BroadcastReceiver receiver, 
    IntentFilter filter
  ) {
    if (Build.VERSION.SDK_INT >= 34 && 
        getApplicationInfo().targetSdkVersion >= 34) {
      // Android 14以上でRECEIVER_EXPORTEDを明示
      return super.registerReceiver(
        receiver, 
        filter, 
        Context.RECEIVER_EXPORTED
      );
    } else {
      return super.registerReceiver(receiver, filter);
    }
  }
}

必要な依存関係を追加 (app/build.gradle):

gradle
dependencies {
    implementation 'org.jetbrains:annotations:16.0.2'
}

📦 方法2: サードパーティライブラリのパッチ適用

react-native-orientation 等のライブラリで発生する場合の修正手順:

  1. ライブラリのビルド設定を修正 (node_modules/react-native-orientation/android/build.gradle):
gradle
android {
    compileSdkVersion getExtOrDefault('compileSdkVersion', 33)
    buildToolsVersion getExtOrDefault('buildToolsVersion', "33.0.0")
    defaultConfig {
        minSdkVersion getExtOrDefault('minSdkVersion', 21)
        targetSdkVersion getExtOrDefault('targetSdkVersion', 34)
    }
}
  1. ソースコードを修正 (OrientationModule.java):
java
import android.os.Build;

// ...
if (Build.VERSION.SDK_INT >= 34 && 
    activity.getApplicationInfo().targetSdkVersion >= 34) {
    activity.registerReceiver(
        receiver, 
        new IntentFilter("onConfigurationChanged"), 
        Context.RECEIVER_EXPORTED // 明示的エクスポート
    );
} else {
    activity.registerReceiver(
        receiver,
        new IntentFilter("onConfigurationChanged")
    );
}
  1. 修正を永続化:
bash
yarn add patch-package --dev
yarn patch-package react-native-orientation

⚙️ 方法3: compileSdkVersionとtargetSdkVersionの調整

一時的な回避策として build.gradle を調整:

gradle
ext {
    compileSdkVersion = 33  // 現状維持
    targetSdkVersion = 34   // Android 14をターゲット
    buildToolsVersion = "34.0.0"
}

注意点

これは一時的な回避策です。長期的にはcompileSdkVersionも34に上げる必要があります


🔧 方法4: 依存関係とビルドツールの更新

安定ビルドのための環境アップグレード:

  1. gradle-wrapper.properties:
properties
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
  1. トップレベルのbuild.gradle:
gradle
dependencies {
    classpath 'com.android.tools.build:gradle:7.2.2'
    classpath "com.google.firebase:perf-plugin:1.4.1"
}
  1. React Nativeライブラリの更新例 (package.json):
json
{
  "dependencies": {
    "react-native": "0.66.5",
    "react-native-screens": "3.22.1",
    "react-native-webview": "11.22.7"
  },
  "resolutions": {
    "@react-native-community/cli**": "^7.0.0"
  }
}

Android 14対応のベストプラクティス

  1. テストサイクルの確立:

    • エミュレータ/実機両方での検証
    • targetSdkVersion変更後は必ずフルリグレッションテスト
  2. 権限設定の見直し:

    • ストレージ権限のmaxSdkVersionを確認
    xml
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" 
                   android:maxSdkVersion="32" />
  3. モジュラリティの活用:

    gradle
    // build.gradleに追加
    android {
         useLibrary 'android.test.runner'
         useLibrary 'android.test.base'
    }
  4. 公式ドキュメントの参照:

推奨アップデートフロー

  1. compileSdkVersiontargetSdkVersionを段階的に更新
  2. 各ライブラリの互換性バージョンを確認
  3. パッチ適用が必要なモジュールを抽出
  4. Android 14エミュレータで動作検証
  5. 実機テストで最終確認

まとめ

Android 14対応ではブロードキャストレシーバーの新しいセキュリティ制約が主要課題となりますが:

  • RECEIVER_EXPORTED/RECEIVER_NOT_EXPORTEDの明示的指定
  • 影響を受けるサードパーティライブラリの修正パッチ適用
  • Gradle/React Nativeライブラリの適切なバージョン管理

これらを適切に実施することで安定動作が可能です。APIレベル34への移行は必須要件のため、本ガイドを参考に安全にアップグレードを実施してください。