【问题标题】:Passing onActivityResult in Cordova在 Cordova 中传递 onActivityResult
【发布时间】:2015-02-01 12:59:55
【问题描述】:

Cordova 是否有任何自动方式将 onActivityResult 传递给其 CordovaPlugin 类?

这是我当前的文件,手动操作:

package com.myapp;

import android.os.Bundle;
import org.apache.cordova.*;

import android.content.Intent;

import com.flyingsoftgames.googleplaytoken.GooglePlayToken;

public class MyApp extends CordovaActivity {

 @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) {
  GooglePlayToken.runOnActivityResult (requestCode, resultCode, data);
 }

 @Override public void onCreate (Bundle savedInstanceState) {
  super.onCreate (savedInstanceState);
  super.init ();
  super.loadUrl(Config.getStartUrl());
 }
}


我尝试使用https://github.com/apache/cordova-plugin-camera/blob/master/src/android/CameraLauncher.java 中使用的相同技术来“自动”传递数据——但它崩溃了。这是目标类的工作(手动和无数据传递)和非工作(自动数据传递)版本。首先工作,然后不工作。

工作,没有数据传递:

// Working, no data pass-through.
package com.flyingsoftgames.googleplaytoken;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.Scopes;

import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;

import com.google.android.gms.common.AccountPicker;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.apache.cordova.PluginResult.Status;

import org.json.JSONArray;
import org.json.JSONException;

import android.content.Context;
import android.content.Intent;

import android.app.Activity;
import android.accounts.AccountManager;

import android.os.AsyncTask;
import android.os.Bundle;

import java.io.IOException;

import android.util.Log;

public class GooglePlayToken extends CordovaPlugin {

 private static final String LOG_TAG = "GooglePlayToken";
 private static final int REQ_SIGN_IN_REQUIRED = 55664;

 public static CordovaInterface cordova           = null;
 public static CallbackContext tryConnectCallback = null;
 public static String          accessToken        = "";

 public static final int REQUEST_CODE_PICK_ACCOUNT = 1000;

 @Override public void initialize (CordovaInterface initCordova, CordovaWebView webView) {
  cordova = initCordova;
  super.initialize (cordova, webView);
 }

 private void pickUserAccount () {
  String[] accountTypes = new String[]{"com.google"};
  Intent intent = AccountPicker.newChooseAccountIntent(null, null, accountTypes, false, null, null, null, null);
  cordova.getActivity().startActivityForResult (intent, REQUEST_CODE_PICK_ACCOUNT);
 }

 public static void runOnActivityResult (int requestCode, int resultCode, Intent data) {
  if ((requestCode == REQUEST_CODE_PICK_ACCOUNT) && (resultCode == Activity.RESULT_OK)) {
   new RetrieveTokenTask().execute (data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME));
  }
 }

 public boolean execute (String action, JSONArray inputs, CallbackContext callbackContext) throws JSONException {
 if ("tryConnect".equals(action)) {
   tryConnect (callbackContext);
  } else if ("getAccessToken".equals(action)) {
   callbackContext.sendPluginResult (new PluginResult (PluginResult.Status.OK, accessToken));
  }
  return true;
 }

 // tryConnect runs the callback with a value of false if Google Play Services isn't available.
 public void tryConnect (CallbackContext callbackContext) {
  tryConnectCallback = callbackContext;
  pickUserAccount ();
 }


 private static class RetrieveTokenTask extends AsyncTask<String, Void, String> {
  @Override protected String doInBackground (String... params) {
   String accountName = params[0];
   String scope = "oauth2:" + Scopes.PROFILE;
   Context context = cordova.getActivity().getApplicationContext();
   try {
    accessToken = GoogleAuthUtil.getToken(context, accountName, scope);
   } catch (IOException e) {
    String errormessage = e.getMessage();
    if (tryConnectCallback != null) tryConnectCallback.error ("Error: " + errormessage + "."); tryConnectCallback = null;
   } catch (UserRecoverableAuthException e) {
    cordova.getActivity().startActivityForResult (e.getIntent(), REQ_SIGN_IN_REQUIRED);
   } catch (GoogleAuthException e) {
    String errormessage = e.getMessage();
    if (tryConnectCallback != null) tryConnectCallback.error ("Error: " + errormessage + "."); tryConnectCallback = null;
   }
   return accessToken;
  }

  @Override protected void onPostExecute (String newAccessToken) {
   super.onPostExecute (newAccessToken);
   accessToken = newAccessToken;
   if (tryConnectCallback != null) {
    tryConnectCallback.sendPluginResult (new PluginResult (PluginResult.Status.OK, accessToken));
    tryConnectCallback = null;
   }
  }
 }
}


非工作,数据传递:

// Crashy / non-working, data pass-through.
package com.flyingsoftgames.googleplaytoken;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.Scopes;

import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;

import com.google.android.gms.common.AccountPicker;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.apache.cordova.PluginResult.Status;

import org.json.JSONArray;
import org.json.JSONException;

import android.content.Context;
import android.content.Intent;

import android.app.Activity;
import android.accounts.AccountManager;

import android.os.AsyncTask;
import android.os.Bundle;

import java.io.IOException;

import android.util.Log;

public class GooglePlayToken extends CordovaPlugin {

 private final String LOG_TAG = "GooglePlayToken";
 private final int REQ_SIGN_IN_REQUIRED = 55664;

 public CordovaInterface cordova           = null;
 public CallbackContext tryConnectCallback = null;
 public String          accessToken        = "";

 public final int REQUEST_CODE_PICK_ACCOUNT = 1000;

 @Override public void initialize (CordovaInterface initCordova, CordovaWebView webView) {
 Log.e (LOG_TAG, "initialize");
  cordova = initCordova;
  super.initialize (cordova, webView);
 }

 private void pickUserAccount () {
  Log.e (LOG_TAG, "pickUserAccount");
  String[] accountTypes = new String[]{"com.google"};
  Intent intent = AccountPicker.newChooseAccountIntent(null, null, accountTypes, false, null, null, null, null);
  //cordova.startActivityForResult ((CordovaPlugin) this, intent, REQUEST_CODE_PICK_ACCOUNT); // Tried this, too.
  cordova.getActivity().startActivityForResult (intent, REQUEST_CODE_PICK_ACCOUNT);
 }

 //public static void runOnActivityResult (int requestCode, int resultCode, Intent data) {
 public void onActivityResult(int requestCode, int resultCode, Intent intent) {
  Log.e (LOG_TAG, "runOnActivityResult");
  if ((requestCode == REQUEST_CODE_PICK_ACCOUNT) && (resultCode == Activity.RESULT_OK)) {
   new RetrieveTokenTask().execute (intent.getStringExtra(AccountManager.KEY_ACCOUNT_NAME));
  }
 }

 public boolean execute (String action, JSONArray inputs, CallbackContext callbackContext) throws JSONException {
 Log.e (LOG_TAG, "execute: " + action);
 if ("tryConnect".equals(action)) {
   tryConnect (callbackContext);
  } else if ("getAccessToken".equals(action)) {
   callbackContext.sendPluginResult (new PluginResult (PluginResult.Status.OK, accessToken));
  }
  return true;
 }

 // tryConnect runs the callback with a value of false if Google Play Services isn't available.
 public void tryConnect (CallbackContext callbackContext) {
  Log.e (LOG_TAG, "tryConnect");
  tryConnectCallback = callbackContext;
  pickUserAccount ();
 }


 private class RetrieveTokenTask extends AsyncTask<String, Void, String> {
  @Override protected String doInBackground (String... params) {
   Log.e (LOG_TAG, "RetrieveTokenTask");
   String accountName = params[0];
   String scope = "oauth2:" + Scopes.PROFILE;
   Context context = cordova.getActivity().getApplicationContext();
   try {
    accessToken = GoogleAuthUtil.getToken(context, accountName, scope);
    GoogleAuthUtil.clearToken (context, accessToken);
    accessToken = GoogleAuthUtil.getToken(context, accountName, scope);
    Log.e (LOG_TAG, accessToken);
   } catch (IOException e) {
    String errormessage = e.getMessage();
    if (tryConnectCallback != null) tryConnectCallback.error ("Error: " + errormessage + "."); tryConnectCallback = null;
   } catch (UserRecoverableAuthException e) {
    cordova.getActivity().startActivityForResult (e.getIntent(), REQ_SIGN_IN_REQUIRED);
   } catch (GoogleAuthException e) {
    String errormessage = e.getMessage();
    if (tryConnectCallback != null) tryConnectCallback.error ("Error: " + errormessage + "."); tryConnectCallback = null;
   }
   return accessToken;
  }

  @Override protected void onPostExecute (String newAccessToken) {
   super.onPostExecute (newAccessToken);
   accessToken = newAccessToken;
   if (tryConnectCallback != null) {
    tryConnectCallback.sendPluginResult (new PluginResult (PluginResult.Status.OK, accessToken));
    tryConnectCallback = null;
   }
  }
 }
}

【问题讨论】:

    标签: java android cordova onactivityresult


    【解决方案1】:

    作者已经回答了这个问题,但如果有人想要一个更简单的例子,这对我有用...

    public final int MY_OP = 11;
    private CallbackContext callback = null;
    
    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException 
    {
        if (action.equals("SERVICE NAME")) 
        {
            String param = "";
            try
            {
                param = args.getString(0);
            }
            catch( Exception e )
            {
            }
    
            callback = callbackContext;
    
            cordova.setActivityResultCallback (this);
    
            Intent intent = new Intent();
            intent.setClassName("com.pkg.drs","com.pkg.drs.ActivityToCall");
            intent.putExtra("my_param", param);
    
            cordova.startActivityForResult (this, intent, MY_OP);
            return true;
        }
    
        return false;
    }
    
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
        if( requestCode == MY_OP )
        {
            if( resultCode == Activity.RESULT_OK && data.hasExtra("return_val") )
            {
                PluginResult result = new PluginResult(PluginResult.Status.OK, data.getStringExtra("return_val"));
                result.setKeepCallback(true);
                callback.sendPluginResult(result);
            }
            else
            {
                PluginResult result = new PluginResult(PluginResult.Status.ERROR, "no params returned successfully" );
                result.setKeepCallback(true);
                callback.sendPluginResult(result);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      结果我需要做的就是在cordova.getActivity().startActivityForResult (intent, REQUEST_CODE_PICK_ACCOUNT); 之前运行cordova.setActivityResultCallback (this);

      【讨论】:

      • 对不起,我不知道。他们一定改变了什么。
      • 来自CordovaInterface.java启动一项您希望在完成后获得结果的活动。当这个活动退出时,你的 onActivityResult() 方法将被调用。 abstract public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode);
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-18
      • 1970-01-01
      • 2020-03-07
      • 1970-01-01
      • 1970-01-01
      • 2013-12-23
      • 2017-06-10
      相关资源
      最近更新 更多