React-native从startActivityForResult中获取结果

前端之家收集整理的这篇文章主要介绍了React-native从startActivityForResult中获取结果前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

注:以下内容涉及原生的调用逻辑,有必要很清楚。

android端

在这部分发现官方文档的内容并不能调用到module中的activityResult方法,在整理了逻辑以后,觉得应该在包含reactView的activity中写回调,比如我新建了一个MyReactActivit,里边包含一个mReactRootView

  1. public class MyReactActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
  2. protected ReactRootView mReactRootView;
  3. private ReactInstanceManager mReactInstanceManager;
  4. private static final int OVERLAY_PERMISSION_REQ_CODE = 233;
  5. private static final int IMAGE_PICKER_REQUEST = 12345;
  6. private static final String E_PICKER_CANCELLED = "E_PICKER_CANCELLED";
  7. private static final String E_NO_IMAGE_DATA_FOUND = "E_NO_IMAGE_DATA_FOUND";
  8. //构建一个阻塞的单一数据的队列
  9. public static ArrayBlockingQueue<String> mQueue = new ArrayBlockingQueue<String>(1);
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  14. if (!Settings.canDrawOverlays(this)) {
  15. Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,Uri.parse("package:" + getPackageName()));
  16. startActivityForResult(intent,OVERLAY_PERMISSION_REQ_CODE);
  17. }
  18. }
  19. mReactRootView = new ReactRootView(this);
  20. mReactInstanceManager = ReactInstanceManager.builder()
  21. .setApplication(getApplication())
  22. .setBundleAssetName("index.android.bundle")
  23. .setJSMainModuleName("index.android")
  24. .addPackage(new MainReactPackage())
  25. .addPackage(new CustomReactPackage())
  26. .setUseDeveloperSupport(BuildConfig.DEBUG)
  27. .setInitialLifecycleState(LifecycleState.RESUMED)
  28. .build();
  29. mReactRootView.startReactApplication(mReactInstanceManager,"HelloWorld",null);
  30.  
  31. setContentView(mReactRootView);
  32. }

以上是MyReactActivity的部分内容,在里边重写onActivityResult方法,如下:

  1. @Override
  2. protected void onActivityResult(int requestCode,int resultCode,Intent intent) {
  3. if (requestCode == IMAGE_PICKER_REQUEST) {
  4. if (resultCode == Activity.RESULT_CANCELED) {
  5. mQueue.add(E_PICKER_CANCELLED+"Image picker was cancelled");
  6. } else if (resultCode == Activity.RESULT_OK) {
  7. Uri uri = intent.getData();
  8. if (uri == null) {
  9. mQueue.add(E_NO_IMAGE_DATA_FOUND+"No image data found");
  10. } else {
  11. mQueue.add(uri.toString());
  12. }
  13. }
  14. }
  15. if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
  16. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  17. if (!Settings.canDrawOverlays(this)) {
  18. // SYSTEM_ALERT_WINDOW permission not granted...
  19. }
  20. }
  21. }
  22. }

里边用mQueue来存储的回调数据。以上是回调部分,调用的写法如下:

在我的测试module中写了一个pickImage方法代码如下:

  1. @ReactMethod
  2. public void pickImage(Callback successBack,Callback errorBack) {
  3. Activity currentActivity = getCurrentActivity();
  4.  
  5. if (currentActivity == null) {
  6. errorBack.invoke("Activity doesn't exist");
  7. return;
  8. }
  9.  
  10. try {
  11. final Intent galleryIntent = new Intent(Intent.ACTION_PICK);
  12.  
  13. galleryIntent.setType("image/*");
  14. final Intent chooserIntent = Intent.createChooser(galleryIntent,"Pick an image");
  15. currentActivity.startActivityForResult(chooserIntent,IMAGE_PICKER_REQUEST);
  16. successBack.invoke(MyReactActivity.mQueue.take());
  17. } catch (Exception e) {
  18. errorBack.invoke(e.getMessage());
  19. e.printStackTrace();
  20. }
  21. }

以上调用了本机的选择图片功能。然后两个参数successBack和errorBack是js端传来的,用来返回数据到js。可以看到上面使用了MyReactActivity的静态变量mQueue用来获取回调到onActivityResult方法中的值,再返回到js中。

Js端的调用方式:

  1. NativeModules.MyTestModule.pickImage((msg) => {
  2. ToastAndroid.show('JS界面:从Activity中传输过来的数据为:'+msg,ToastAndroid.SHORT);
  3. },(result) => {
  4. ToastAndroid.show('JS界面:错误信息为:'+result,ToastAndroid.SHORT);
  5. });

以上就是从startActivityForResult中获取结果的所有方法,流程和官网的并不相同的,还不清楚官网的调用方式是否可行,但是经过测试并没有成功。当然我写的以上的方式成功了。

以上

猜你在找的React相关文章