Skip to content

React Native Apps Targeting Android 14 (API 34)

Problem Statement

When updating a React Native app to target Android 14 (API level 34), developers may encounter immediate app crashes on API 34 devices while the same app works on older API levels. The crash typically shows two key errors in logcat:

plaintext
java.lang.RuntimeException: Unable to create application com.example.MainApplication: 
java.lang.RuntimeException: Requested enabled DevSupportManager, but BridgeDevSupportManager class was not found

Caused by: java.lang.SecurityException: 
One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts

This occurs due to Android 14's new requirement for explicit broadcast receiver export flags and React Native compatibility issues that surface when targeting API 34.

Solutions

1. Broadcast Receiver Export Fix (Essential)

Android 14 requires specifying broadcast receiver export behavior. Implement this fix immediately to resolve the SecurityException:

In android/app/src/main/java/<your-package>/MainApplication.java:

java
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.content.Context; // Add this import
import org.jetbrains.annotations.Nullable; // Required for annotation

public class MainApplication extends Application implements ReactApplication {
    // ... existing code ...
    
    @Override
    public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {
        if (Build.VERSION.SDK_INT >= 34 && getApplicationInfo().targetSdkVersion >= 34) {
            return super.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED);
        } else {
            return super.registerReceiver(receiver, filter);
        }
    }
    
    // ... rest of your class ...
}

In android/app/build.gradle:

gradle
dependencies {
    implementation 'org.jetbrains:annotations:16.0.2' // Required for annotation
    // ... existing dependencies ...
}

TIP

This fix addresses the core SecurityException. Test your app after implementing this before proceeding.

For long-term stability and compatibility, fully update your development environment:

Update Gradle Configurations

In android/build.gradle:

gradle
buildscript {
    ext {
        buildToolsVersion = "34.0.0"
        minSdkVersion = 23
        compileSdkVersion = 34
        targetSdkVersion = 34
        // ... other ext properties ...
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.2.2' // Update plugin version
        // ... other classpath dependencies ...
    }
}

Update Gradle Wrapper

In gradle/wrapper/gradle-wrapper.properties:

properties
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip

Update React Native and Libraries

In package.json:

json
{
  "dependencies": {
    "react-native": "0.66.5", // Update to compatible version
    "react-native-orientation": "^1.0.0", // Example updated library
    "react-native-screens": "3.22.1",
    "react-native-webview": "11.22.7"
  },
  "resolutions": {
    "@react-native-community/cli": "^7.0.0",
    "@react-native-community/cli-platform-android": "^7.0.0",
    // Add other @react-native-community packages as needed
  }
}

Compatibility Check

Verify library compatibility with React Native 0.67.x+ before upgrading:

bash
yarn why react-native-screens # Check version requirements

3. Troubleshooting Third-Party Libraries

For incompatible libraries (like older react-native-orientation), create patches:

bash
# Install patch-package
yarn add patch-package postinstall-posthack

# In package.json:
"scripts": {
  "postinstall": "patch-package"
}

Example patch for react-native-orientation:

diff
# node_modules/react-native-orientation/android/src/main/java/com/github/yamill/orientation/OrientationModule.java

+ import android.os.Build;
+ import android.content.Context;

  activity.registerReceiver(receiver, new IntentFilter("onConfigurationChanged"));

Replace with:

java
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"));
}

Apply the patch:

bash
npx patch-package react-native-orientation

4. Temporary Workaround (Short-Term Only)

If immediate full updates aren't feasible, use this temporary configuration while planning your migration:

In android/build.gradle:

gradle
ext {
    compileSdkVersion = 33
    targetSdkVersion = 34  // Only update targetSdkVersion
    // Keep existing other versions
}

NOT Recommended For Production

This workaround bypasses compatibility testing and may cause unexpected issues. Use only for testing before applying full updates.

Key Recommendations

  • Prioritize broadcast receiver fix as it's required for any API 34 targeting
  • Update React Native to latest compatible version (0.67.x+ minimum)
  • Test thoroughly on Android 14 physical devices and emulators
  • Verify all permissions (especially storage permissions with scope changes)
  • Remove deprecated permissions:
    xml
    <!-- Remove in AndroidManifest.xml -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" 
                     android:maxSdkVersion="32" /> <!-- No longer needed -->

Following this structured approach ensures your React Native app meets Android 14 requirements while maintaining stability and compatibility with modern Android features.