diff --git a/Libraries/Linking/Linking.js b/Libraries/Linking/Linking.js index a59fa72973a3a2..76d187988ff6e2 100644 --- a/Libraries/Linking/Linking.js +++ b/Libraries/Linking/Linking.js @@ -11,7 +11,6 @@ import type {EventSubscription} from '../vendor/emitter/EventEmitter'; import NativeEventEmitter from '../EventEmitter/NativeEventEmitter'; -import InteractionManager from '../Interaction/InteractionManager'; import Platform from '../Utilities/Platform'; import NativeIntentAndroid from './NativeIntentAndroid'; import NativeLinkingManager from './NativeLinkingManager'; @@ -96,9 +95,7 @@ class Linking extends NativeEventEmitter { */ getInitialURL(): Promise { return Platform.OS === 'android' - ? InteractionManager.runAfterInteractions().then(() => - nullthrows(NativeIntentAndroid).getInitialURL(), - ) + ? nullthrows(NativeIntentAndroid).getInitialURL() : nullthrows(NativeLinkingManager).getInitialURL(); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java index 7b532d4975b7bf..c0da2164e435fb 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java @@ -17,6 +17,7 @@ import androidx.annotation.Nullable; import com.facebook.fbreact.specs.NativeIntentAndroidSpec; import com.facebook.react.bridge.JSApplicationIllegalArgumentException; +import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReadableArray; @@ -30,6 +31,8 @@ public class IntentModule extends NativeIntentAndroidSpec { public static final String NAME = "IntentAndroid"; + private @Nullable LifecycleEventListener mInitialURLListener = null; + private static final String EXTRA_MAP_KEY_FOR_VALUE = "value"; public IntentModule(ReactApplicationContext reactContext) { @@ -41,6 +44,15 @@ public String getName() { return NAME; } + @Override + public void invalidate() { + if (mInitialURLListener != null) { + getReactApplicationContext().removeLifecycleEventListener(mInitialURLListener); + mInitialURLListener = null; + } + super.invalidate(); + } + /** * Return the URL the activity was started with * @@ -50,18 +62,20 @@ public String getName() { public void getInitialURL(Promise promise) { try { Activity currentActivity = getCurrentActivity(); - String initialURL = null; + if (currentActivity == null) { + waitForActivityAndGetInitialURL(promise); + return; + } - if (currentActivity != null) { - Intent intent = currentActivity.getIntent(); - String action = intent.getAction(); - Uri uri = intent.getData(); + Intent intent = currentActivity.getIntent(); + String action = intent.getAction(); + Uri uri = intent.getData(); - if (uri != null - && (Intent.ACTION_VIEW.equals(action) - || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))) { - initialURL = uri.toString(); - } + String initialURL = null; + if (uri != null + && (Intent.ACTION_VIEW.equals(action) + || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))) { + initialURL = uri.toString(); } promise.resolve(initialURL); @@ -72,6 +86,33 @@ public void getInitialURL(Promise promise) { } } + private void waitForActivityAndGetInitialURL(final Promise promise) { + if (mInitialURLListener != null) { + promise.reject( + new IllegalStateException( + "Cannot await activity from more than one call to getInitialURL")); + return; + } + + mInitialURLListener = + new LifecycleEventListener() { + @Override + public void onHostResume() { + getInitialURL(promise); + + getReactApplicationContext().removeLifecycleEventListener(this); + mInitialURLListener = null; + } + + @Override + public void onHostPause() {} + + @Override + public void onHostDestroy() {} + }; + getReactApplicationContext().addLifecycleEventListener(mInitialURLListener); + } + /** * Starts a corresponding external activity for the given URL. *