Android cordova插件onActivityResult从未执行,解决方法

本文概述

如果你使用的是使用第三方API的插件, 并且不能随意修改其代码, 则可能会发现使用onActivityResult函数从api检索结果的代码。

好吧, 如果你在任何Android项目上工作, 这根本没有问题, 但是如果你尝试在Cordova插件上完成此任务, 那么你可能现在想杀死自己, 因为它根本不起作用。因此, 请不要这样做, 至少今天不要这样做。

也许你已经注意到(很明显地知道)此问题是由于主Cordova活动(由于某种原因)没有被触发, 并且你无法覆盖此方法。因此, 从理论上讲, 解决方案非常简单, 只需创建一个意图并将事件委托给该意图, 然后使用cordova.startActivityForResult在cordova中检索该事件即可。

在下面的示例中, 我们将以OneDrive文件选择器为例。

如前所述, 你不能简单地在同一Cordova Activity中覆盖onActivityResult, 因此, 我们将创建一个用于启动Filepicker的Empty View(新意图)。为了创建一个空的活动, 在你的plugin.xml文件中添加以下标记以创建一个可用的视图(稍后我们将使用Java类对其进行操作)。在这种情况下, 名称为DialogShowPicker(该Intent必须具有与Java类相同的名称), 请注意, 它必须位于android platform标签内:

<platform name="android">
   <!--This will be the activity, if you want another name change in both of the tags (action and activity) -->
   <config-file target="AndroidManifest.xml" parent="/manifest/application">
      <activity android:name="com.ourcodeworld.plugins.onedrivefilepicker.DialogShowPicker"
        android:label="OneDrive filepicker">
        <intent-filter>
          <!-- We are going to use this name to start the activity later in Java -->
          <action android:name="com.ourcodeworld.plugins.onedrivefilepicker.DialogShowPicker" />
          <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
      </activity>
  </config-file>
</platform>

那应该在项目中创建活动, 我们可以在主类中调用它。你只需要创建一个新的Intent, 指定活动的名称(我们之前在plugin.xml文件中提供的名称), 然后将其作为参数发送给cordova.startActivityForResult, 它将为你解决问题。

转到你的主类的execute函数并处理上述算法。遵循以下示例:

package com.ourcodeworld.plugins.onedrivefilepicker;// Change the package name according to your plugin.

import org.apache.cordova.*;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Intent;
import android.content.Context;// To toast
import android.widget.Toast;// ToToast
import android.os.Bundle;

public class myPluginMainClass extends CordovaPlugin {
    private static final String ACTION_SHOWPICKER = "showpicker";
    private CallbackContext PUBLIC_CALLBACKS = null;

    @Override
    public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {
        final JSONObject arg_object = data.getJSONObject(0);
        String ONEDRIVE_APP_ID = "thisisTheAppIdfortheExample";
        String LINK_MODE = "download";
        PUBLIC_CALLBACKS = callbackContext;
        // If the showpicker action is executed from javascript, start the activity that starts the picker
        if (ACTION_SHOWPICKER.equals(action)) {
            // The intent expects as first parameter the given name for the activity in your plugin.xml
            Intent intent = new Intent("com.ourcodeworld.plugins.onedrivefilepicker.DialogShowPicker");
            // Send some info to the activity to retrieve it later
            intent.putExtra("app_id", ONEDRIVE_APP_ID);
            intent.putExtra("link_mode", LINK_MODE);
            // Now, cordova will expect for a result using startActivityForResult and will be handle by the onActivityResult.
            cordova.startActivityForResult((CordovaPlugin) this, intent, 0);
        }

        // Send no result, to execute the callbacks later
        PluginResult pluginResult = new  PluginResult(PluginResult.Status.NO_RESULT);
        pluginResult.setKeepCallback(true); // Keep callback

        return true;
    }

    @Override
    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        if(resultCode == cordova.getActivity().RESULT_OK){
            Bundle extras = data.getExtras();// Get data sent by the Intent
            String information = extras.getString("data"); // data parameter will be send from the other activity.
            tolog(information); // Shows a toast with the sent information in the other class
            PluginResult resultado = new PluginResult(PluginResult.Status.OK, "this value will be sent to cordova");
            resultado.setKeepCallback(true);
            PUBLIC_CALLBACKS.sendPluginResult(resultado);
            return;
        }else if(resultCode == cordova.getActivity().RESULT_CANCELED){
            PluginResult resultado = new PluginResult(PluginResult.Status.OK, "canceled action, process this in javascript");
            resultado.setKeepCallback(true);
            PUBLIC_CALLBACKS.sendPluginResult(resultado);
            return;
        }
        // Handle other results if exists.
        super.onActivityResult(requestCode, resultCode, data);
    }
    
    // A function to show a toast with some data, just demo
    public void tolog(String toLog){
        Context context = cordova.getActivity();
        int duration = Toast.LENGTH_SHORT;

        Toast toast = Toast.makeText(context, toLog, duration);
        toast.show();
    }
}

现在我们需要处理活动开始时将发生的情况。在你的android代码中创建Java类(DialogShowPicker.java), 不要忘记将其包含在插件中。 java类应如下所示:

package com.ourcodeworld.plugins.onedrivefilepicker;// Change the package name acording to your plugin name

import org.apache.cordova.*;
import android.app.Activity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Intent;
import android.os.Bundle;
import com.microsoft.onedrivesdk.picker.*;

public class DialogShowPicker extends Activity{
    private boolean firstTime = true;

    @Override
    public void onStart() {
        super.onStart();
        // Write your code inside this condition
        // Here should start the process that expects the onActivityResult
        if(firstTime == true){
            // Do something at first initialization
            // And retrieve the parameters that we sent before in the Main file of the plugin
            Bundle extras = getIntent().getExtras();
            if (extras != null) {
               String appId = extras.getString("app_id");
               linkMode = extras.getString("link_mode");
               mPicker = Picker.createPicker(appId);

               // startPicking method will execute onActivityResult whe na file is selected.
               if(linkMode.equals("view")){
                  mPicker.startPicking(this, LinkType.WebViewLink);
               }else if(linkMode.equals("download")){
                  mPicker.startPicking(this, LinkType.DownloadLink);
               }
            }
        }
    }

    @Override
    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        firstTime = false;// There's a result, allow to exit the activity !
        
        // Do something with the result of the Intent data
 
        // Send parameters to retrieve in cordova.
        Intent intent = new Intent();
        intent.putExtra("data", "This is the sent information from the 2 activity :) ");
        setResult(Activity.RESULT_OK, intent);
        finish();// Exit of this activity !
    }
}

并使用将其添加到你的插件中:

<!-- Change target-dir according to your plugin -->
<source-file src="src/android/DialogShowPicker.java" target-dir="src/com/ourcodeworld/plugin/"/>

然后, 只需使用javascript(你应在插件中根据需要自行定义)执行函数即可。你可以查看下图以了解我们刚刚完成的工作:

Android cordova插件onActivityResult从未执行,解决方法1

笔记

  • 你只能在Intent(字符串和数字)之间发送原始值

玩得开心

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?