Skip to content

Commit 39ede95

Browse files
lukmccallmeta-codesync[bot]
authored andcommitted
Fix request permission is not always resolving in Android 16 (#53898)
Summary: Fixes: #53887 Fixes: expo/expo#39480 In the latest Android 16 update, requesting permissions does not always change the app's state (the `onPause` and `onResume` functions aren't called). For instance, when you deny permission 3 times, the last promise won't resolve until you move the app to the background. The current logic inside the `ReactActivityDelegate` assumes that Android will call `onResume` after receiving permission state information from the system, which is no longer the case. Probably connected with [this commit](https://android.googlesource.com/platform/packages/modules/Permission/%2B/5dca0ccb26f2b99d706a1d3e9402f851e849c913) ## Changelog: [ANDROID] [FIXED] - Fix request permission not always resolving in Android 16 Pull Request resolved: #53898 Test Plan: - I've tested it in the RNTester by denying the camera permission three times. - I've also checked if the patch works with the Expo permissions code. Reviewed By: javache Differential Revision: D83059478 Pulled By: cortinico fbshipit-source-id: 7bf33b379a1b6606ad2da2f75d337bf951e3986b
1 parent d7bcaf6 commit 39ede95

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.facebook.infer.annotation.Nullsafe;
2222
import com.facebook.react.bridge.Callback;
2323
import com.facebook.react.bridge.ReactContext;
24+
import com.facebook.react.common.LifecycleState;
2425
import com.facebook.react.interfaces.fabric.ReactSurface;
2526
import com.facebook.react.internal.featureflags.ReactNativeNewArchitectureFeatureFlags;
2627
import com.facebook.react.modules.core.PermissionListener;
@@ -248,14 +249,37 @@ public void requestPermissions(
248249

249250
public void onRequestPermissionsResult(
250251
final int requestCode, final String[] permissions, final int[] grantResults) {
251-
mPermissionsCallback =
252+
Callback permissionsCallback =
252253
args -> {
253254
if (mPermissionListener != null
254255
&& mPermissionListener.onRequestPermissionsResult(
255256
requestCode, permissions, grantResults)) {
256257
mPermissionListener = null;
257258
}
258259
};
260+
261+
LifecycleState lifecycle;
262+
if (isFabricEnabled()) {
263+
ReactHost reactHost = getReactHost();
264+
lifecycle = reactHost != null ? reactHost.getLifecycleState() : LifecycleState.BEFORE_CREATE;
265+
} else {
266+
ReactNativeHost reactNativeHost = getReactNativeHost();
267+
if (!reactNativeHost.hasInstance()) {
268+
lifecycle = LifecycleState.BEFORE_CREATE;
269+
} else {
270+
lifecycle = reactNativeHost.getReactInstanceManager().getLifecycleState();
271+
}
272+
}
273+
274+
// If the permission request didn't show a dialog to the user, we can call the callback
275+
// immediately.
276+
// Otherwise, we need to wait until onResume to call it.
277+
if (lifecycle == LifecycleState.RESUMED) {
278+
permissionsCallback.invoke();
279+
return;
280+
}
281+
282+
mPermissionsCallback = permissionsCallback;
259283
}
260284

261285
protected Context getContext() {

0 commit comments

Comments
 (0)