反应本机 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 模块的onActivityResultReactContext 调用,ReactInstanceManagerImpl 在 0.29 中被ReactActivity 调用。在上面的示例中,MyWb 扩展了 Activity 而不是 ReactActivity,因此永远不会调用 ReactInstanceManagerImpl

解决方案只是在您的活动的onActivityResult 调用ReactInstanceManageronActivityResult 中,因为您已经拥有自己的 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 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

水平滚动视图在本机反应中不起作用

视频在本机反应(android)中不起作用

反应本机即时电话不起作用

反应本机抽屉导航在按钮单击时不起作用

在本机反应中安排本地通知不起作用

反应本机 NavigationDrawer navigation.toggleDrawer() 不起作用