From 3ee3041d68c4235420fa727221cd39e2a6609660 Mon Sep 17 00:00:00 2001 From: Aaron Chiu Date: Fri, 30 Oct 2015 16:44:09 -0700 Subject: [PATCH] Hook up onActivityResult into react native and fb4a Differential Revision: D2602975 fb-gh-sync-id: 3b81f059ee4dca2b63ce07304a552e9deaa28909 --- .../facebook/react/ReactInstanceManager.java | 17 +++++++-- .../react/bridge/ActivityEventListener.java | 16 ++++++++ .../facebook/react/bridge/ReactContext.java | 38 ++++++++++++++++++- 3 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/bridge/ActivityEventListener.java diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index e526076e7..5ab2f725a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -14,8 +14,10 @@ import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; +import android.app.Activity; import android.app.Application; import android.content.Context; +import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; @@ -88,6 +90,7 @@ public class ReactInstanceManager { private final Context mApplicationContext; private @Nullable DefaultHardwareBackBtnHandler mDefaultBackButtonImpl; private String mSourceUrl; + private @Nullable Activity mCurrentActivity; private final ReactInstanceDevCommandsHandler mDevInterface = new ReactInstanceDevCommandsHandler() { @@ -317,6 +320,7 @@ public class ReactInstanceManager { mDevSupportManager.setDevSupportEnabled(false); } + mCurrentActivity = null; if (mCurrentReactContext != null) { mCurrentReactContext.onPause(); } @@ -333,7 +337,7 @@ public class ReactInstanceManager { * @param defaultBackButtonImpl a {@link DefaultHardwareBackBtnHandler} from an Activity that owns * this instance of {@link ReactInstanceManager}. */ - public void onResume(DefaultHardwareBackBtnHandler defaultBackButtonImpl) { + public void onResume(Activity activity, DefaultHardwareBackBtnHandler defaultBackButtonImpl) { UiThreadUtil.assertOnUiThread(); mLifecycleState = LifecycleState.RESUMED; @@ -343,8 +347,9 @@ public class ReactInstanceManager { mDevSupportManager.setDevSupportEnabled(true); } + mCurrentActivity = activity; if (mCurrentReactContext != null) { - mCurrentReactContext.onResume(); + mCurrentReactContext.onResume(activity); } } @@ -360,6 +365,12 @@ public class ReactInstanceManager { } } + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mCurrentReactContext != null) { + mCurrentReactContext.onActivityResult(requestCode, resultCode, data); + } + } + public void showDevOptionsDialog() { UiThreadUtil.assertOnUiThread(); mDevSupportManager.showDevOptionsDialog(); @@ -577,7 +588,7 @@ public class ReactInstanceManager { private void moveReactContextToCurrentLifecycleState(ReactApplicationContext reactContext) { if (mLifecycleState == LifecycleState.RESUMED) { - reactContext.onResume(); + reactContext.onResume(mCurrentActivity); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/ActivityEventListener.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/ActivityEventListener.java new file mode 100644 index 000000000..3f45b4ce8 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/ActivityEventListener.java @@ -0,0 +1,16 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.react.bridge; + +import android.content.Intent; + +/** + * Listener for receiving activity events. + */ +public interface ActivityEventListener { + + /** + * Called when host (activity/service) receives an {@link Activity#onActivityResult} call. + */ + void onActivityResult(int requestCode, int resultCode, Intent data); +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java index 27363232b..47486d3c2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java @@ -13,13 +13,16 @@ import javax.annotation.Nullable; import java.util.concurrent.CopyOnWriteArraySet; +import android.app.Activity; import android.content.Context; import android.content.ContextWrapper; +import android.content.Intent; +import android.os.Bundle; import android.view.LayoutInflater; +import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.queue.CatalystQueueConfiguration; import com.facebook.react.bridge.queue.MessageQueueThread; -import com.facebook.infer.annotation.Assertions; /** * Abstract ContextWrapper for Android applicaiton or activity {@link Context} and @@ -29,6 +32,8 @@ public class ReactContext extends ContextWrapper { private final CopyOnWriteArraySet mLifecycleEventListeners = new CopyOnWriteArraySet<>(); + private final CopyOnWriteArraySet mActivityEventListeners = + new CopyOnWriteArraySet<>(); private @Nullable CatalystInstance mCatalystInstance; private @Nullable LayoutInflater mInflater; @@ -36,6 +41,7 @@ public class ReactContext extends ContextWrapper { private @Nullable MessageQueueThread mNativeModulesMessageQueueThread; private @Nullable MessageQueueThread mJSMessageQueueThread; private @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler; + private @Nullable Activity mCurrentActivity; public ReactContext(Context base) { super(base); @@ -116,11 +122,20 @@ public class ReactContext extends ContextWrapper { mLifecycleEventListeners.remove(listener); } + public void addActivityEventListener(ActivityEventListener listener) { + mActivityEventListeners.add(listener); + } + + public void removeActivityEventListener(ActivityEventListener listener) { + mActivityEventListeners.remove(listener); + } + /** * Should be called by the hosting Fragment in {@link Fragment#onResume} */ - public void onResume() { + public void onResume(@Nullable Activity activity) { UiThreadUtil.assertOnUiThread(); + mCurrentActivity = activity; for (LifecycleEventListener listener : mLifecycleEventListeners) { listener.onHostResume(); } @@ -131,6 +146,7 @@ public class ReactContext extends ContextWrapper { */ public void onPause() { UiThreadUtil.assertOnUiThread(); + mCurrentActivity = null; for (LifecycleEventListener listener : mLifecycleEventListeners) { listener.onHostPause(); } @@ -149,6 +165,15 @@ public class ReactContext extends ContextWrapper { } } + /** + * Should be called by the hosting Fragment in {@link Fragment#onActivityResult} + */ + public void onActivityResult(int requestCode, int resultCode, Intent data) { + for (ActivityEventListener listener : mActivityEventListeners) { + listener.onActivityResult(requestCode, resultCode, data); + } + } + public void assertOnUiQueueThread() { Assertions.assertNotNull(mUiMessageQueueThread).assertIsOnThread(); } @@ -199,4 +224,13 @@ public class ReactContext extends ContextWrapper { throw e; } } + + /** + * Same as {@link Activity#startActivityForResult(Intent, int)}, this just redirects the call to + * the current activity. + */ + public void startActivityForResult(Intent intent, int code, Bundle bundle) { + Assertions.assertNotNull(mCurrentActivity); + mCurrentActivity.startActivityForResult(intent, code, bundle); + } }