反应本机 onActivityResult 不起作用
Posted
技术标签:
【中文标题】反应本机 onActivityResult 不起作用【英文标题】:React Native onActivityResult not work 【发布时间】:2016-07-20 00:42:56 【问题描述】:我有一个 React Native 的 webview 组件。 webview应该支持输入类型是文件,所以我这样做:
File Upload in WebView
并且 webview 实现了 ActivityEventListener 并覆盖了 onActivityResult。但是 onActivityResult 不起作用。
代码是
class RNWebView extends WebView implements ActivityEventListener
protected class GeoWebChromeClient extends WebChromeClient
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams)
...
mActivity.startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
public RNWebView(ReactContext reactContext, Activity activity)
super(reactContext);
// Add the listener for `onActivityResult`
reactContext.addActivityEventListener(this);
...
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent intent)
// Your logic here
Log.d("Tanck", "requestCode:" + requestCode + "----" + "resultCode:" + resultCode);
【问题讨论】:
我还有一个问题,在 rn 27.0.2 和 android Marshmallow (6.0.1) - Nexus 5 上没有调用 onActivityResult。 【参考方案1】:也许晚了,希望对你有帮助。
native 模块的onActivityResult
被ReactContext
调用,ReactInstanceManagerImpl
在 0.29 中被ReactActivity
调用。在上面的示例中,MyWb
扩展了 Activity 而不是 ReactActivity
,因此永远不会调用 ReactInstanceManagerImpl
。
解决方案只是在您的活动的onActivityResult
调用ReactInstanceManager
的onActivityResult
中,因为您已经拥有自己的 ReactInstanceManager 对象引用。
你启动 React Native 的 Activity 应该有一个这样的覆盖:
// Manually pass along the `onActivityResult` event to React Native event listeners.
// We are not extending from `ReactActivity` so we need to do this manually.
//
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
mReactInstanceManager.onActivityResult( this, requestCode, resultCode, data );
【讨论】:
这就是我需要的!谢谢你。我正在使用 RN 0.33.1。我花了两天的时间才找到这个。 澄清一下,您需要将onActivityResult
放在您要从中启动React Native 的Activity 上并调用mReactInstanceManager.onActivityResult( ... )
(或您所称的任何名称)。或者,您可以从 ReactActivity
扩展该 Activity。
这为我节省了数小时令人沮丧的调试时间。非常感谢!【参考方案2】:
使解决方案完整:
在您的 MainActivity 中(或在 Activity 中,初始化 RN 并使用 mReactInstanceManager 如果它是本机应用程序的一部分):
...
private ReactInstanceManager mReactInstanceManager;
...
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
mReactInstanceManager.onActivityResult(requestCode, resultCode, data);
在您的模块中:
public class MyModule extends ReactContextBaseJavaModule implements ActivityEventListener
static final int REQUEST_VIDEO_CAPTURE = 1;
final ReactApplicationContext reactContext;
Promise promise;
public GeneralIntentModule(ReactApplicationContext reactContext)
super(reactContext);
this.reactContext = reactContext;
this.reactContext.addActivityEventListener(this);
@Override
public String getName()
return "MyModule ";
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
this.promise.resolve(data.getDataString());
【讨论】:
Np 伴侣,我花了一段时间才弄清楚。 :)【参考方案3】:如果有人使用带有 Promise 的 react-native 模块的 kotlin,请参考下面的代码,
import android.app.Activity
import android.content.Intent
import android.util.Log
import com.facebook.react.bridge.*
import com.onboardinglib.HostActivity
class ConsistyOnboarding (reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext)
private val CODE = 999
private var promise: Promise? = null
private val reContext: ReactApplicationContext? = reactContext
fun dumpIntent(intent: Intent)
LogPrint("Bundle data", "Dumping intent start")
val bundleData = intent.extras
if (bundleData != null)
for (key in bundleData.keySet())
LogPrint(
"Bundle data-->",
key + " : " + if (bundleData[key] != null) bundleData[key] else "NULL"
)
override fun getName(): String
return "ConsistyOnboarding"
private val mActivityEventListener: ActivityEventListener =
object : BaseActivityEventListener()
override fun onActivityResult(
activity: Activity,
requestCode: Int,
resultCode: Int,
data: Intent
)
LogPrint("mActivityEventListener", "Started")
if (data == null)
resolve("01", "No action taken", "0")
return
dumpIntent(data)
if (resultCode == Activity.RESULT_OK)
try
val status = data.getBooleanExtra("status", false)
val response = data.getIntExtra("response", 0)
val message = data.getStringExtra("message")
resolve(status.toString(), response.toString(), message.toString())
return
catch (e: Exception)
e.printStackTrace()
resolve("01", "Exception occurred in on-boarding " + e.message, "0")
resolve("01", "No action taken", "0")
init
reContext?.addActivityEventListener(mActivityEventListener)
@ReactMethod
fun Onboarding(
partnerId: String, partnerKey: String prm: Promise
)
promise = prm
val currentActivity = currentActivity
val intent = Intent(currentActivity, HostActivity::class.java)
intent.putExtra("pId", partnerId)
intent.putExtra("ApiKey", partnerKey)
try
currentActivity?.startActivityForResult(intent, CODE)
catch (e: Exception)
e.printStackTrace()
resolve("01", "No action taken", "0")
private fun resolve(
statusCode: String,
response: String,
message: String
)
if (promise == null)
return
val map = Arguments.createMap()
map.putString("statusCode", statusCode)
map.putString("response", response)
map.putString("message", message)
promise!!.resolve(map)
promise = null
private fun LogPrint(key: String?, value: String?)
if (key == null || value == null)
return
Log.i(key, value)
主要是需要添加事件监听器,
init
reContext?.addActivityEventListener(mActivityEventListener)
【讨论】:
以上是关于反应本机 onActivityResult 不起作用的主要内容,如果未能解决你的问题,请参考以下文章