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:
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
:
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
:
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.
2. Recommended Full Upgrade Path
For long-term stability and compatibility, fully update your development environment:
Update Gradle Configurations
In android/build.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
:
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
Update React Native and Libraries
In package.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:
yarn why react-native-screens # Check version requirements
3. Troubleshooting Third-Party Libraries
For incompatible libraries (like older react-native-orientation
), create patches:
# Install patch-package
yarn add patch-package postinstall-posthack
# In package.json:
"scripts": {
"postinstall": "patch-package"
}
Example patch for react-native-orientation
:
# 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:
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:
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
:
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.