Skip to content

Commit e335ca0

Browse files
jpshelleyMartin Konicek
authored and
Martin Konicek
committed
Android - Fix Overlay for Marshmallow 23+
Summary: Currently any React Native apps that target API 23 or greater will crash on the first initial debug/dev build due to the overlay permission. Sadly there isn't a concrete "request permission" baked into the Marshmallow permission system. However, we can launch the overlay screen without starting the react app and once its turned on start the app. - #10454 - targetSdkVersion 23 lead crash / App crash for targeting 23+ - #10479 - Add the overlay permission information / Larger discussion around targeting API 23+ - Intent to Overlay permission goes directly to the app in question, rather then the general full listing of applications. This allows a developer who is not familiar with the system to easily toggle the overlay without getting confused. **Test plan (required)** * Ran UIExplorer App on fresh install with Target 23 ``` cd react-native ./gradlew :Examples:UI Closes #11316 Differential Revision: D4286351 fbshipit-source-id: 024e97c08c40ee23646dd153794fcde7127b2308
1 parent fd144a2 commit e335ca0

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java

+22-6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import android.app.Activity;
77
import android.content.Context;
88
import android.content.Intent;
9+
import android.net.Uri;
910
import android.os.Build;
1011
import android.os.Bundle;
1112
import android.provider.Settings;
@@ -29,6 +30,10 @@
2930
* class doesn't implement {@link ReactApplication}.
3031
*/
3132
public class ReactActivityDelegate {
33+
34+
private final int REQUEST_OVERLAY_PERMISSION_CODE = 1111;
35+
private static final String REDBOX_PERMISSION_GRANTED_MESSAGE =
36+
"Overlay permissions have been granted.";
3237
private static final String REDBOX_PERMISSION_MESSAGE =
3338
"Overlay permissions needs to be granted in order for react native apps to run in dev mode";
3439

@@ -79,17 +84,19 @@ public ReactInstanceManager getReactInstanceManager() {
7984
}
8085

8186
protected void onCreate(Bundle savedInstanceState) {
82-
if (getReactNativeHost().getUseDeveloperSupport() && Build.VERSION.SDK_INT >= 23) {
87+
boolean needsOverlayPermission = false;
88+
if (getReactNativeHost().getUseDeveloperSupport() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
8389
// Get permission to show redbox in dev builds.
8490
if (!Settings.canDrawOverlays(getContext())) {
85-
Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
86-
getContext().startActivity(serviceIntent);
91+
needsOverlayPermission = true;
92+
Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getContext().getPackageName()));
8793
FLog.w(ReactConstants.TAG, REDBOX_PERMISSION_MESSAGE);
8894
Toast.makeText(getContext(), REDBOX_PERMISSION_MESSAGE, Toast.LENGTH_LONG).show();
95+
((Activity) getContext()).startActivityForResult(serviceIntent, REQUEST_OVERLAY_PERMISSION_CODE);
8996
}
9097
}
9198

92-
if (mMainComponentName != null) {
99+
if (mMainComponentName != null && !needsOverlayPermission) {
93100
loadApp(mMainComponentName);
94101
}
95102
mDoubleTapReloadRecognizer = new DoubleTapReloadRecognizer();
@@ -140,6 +147,16 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
140147
if (getReactNativeHost().hasInstance()) {
141148
getReactNativeHost().getReactInstanceManager()
142149
.onActivityResult(getPlainActivity(), requestCode, resultCode, data);
150+
} else {
151+
// Did we request overlay permissions?
152+
if (requestCode == REQUEST_OVERLAY_PERMISSION_CODE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
153+
if (Settings.canDrawOverlays(getContext())) {
154+
if (mMainComponentName != null) {
155+
loadApp(mMainComponentName);
156+
}
157+
Toast.makeText(getContext(), REDBOX_PERMISSION_GRANTED_MESSAGE, Toast.LENGTH_LONG).show();
158+
}
159+
}
143160
}
144161
}
145162

@@ -191,8 +208,7 @@ public void onRequestPermissionsResult(
191208
mPermissionsCallback = new Callback() {
192209
@Override
193210
public void invoke(Object... args) {
194-
if (mPermissionListener != null &&
195-
mPermissionListener.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
211+
if (mPermissionListener != null && mPermissionListener.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
196212
mPermissionListener = null;
197213
}
198214
}

0 commit comments

Comments
 (0)