title: Passing onActivityResult in Cordova
body: <p>Does Cordova have any automatic way to pass onActivityResult to its CordovaPlugin classes?</p>
  
  <p>Here's my current file, doing it manually:</p>
  
  <pre><code>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());
   }
  }
  </code></pre>
  
  <p><br/>
  I tried to use the same technique employed in <a href="https://github.com/apache/cordova-plugin-camera/blob/master/src/android/CameraLauncher.java" rel="noreferrer">https://github.com/apache/cordova-plugin-camera/blob/master/src/android/CameraLauncher.java</a> to get the data passed through "automatically" -- but it crashes. Here is a working (manual and no data pass-through) and non-working (automatic data pass-through) version of the target class. First working, then non-working.</p>
  
  <p>Working, no data pass-through:</p>
  
  <pre><code>// 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) &amp;&amp; (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&lt;String, Void, String&gt; {
    @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;
     }
    }
   }
  }
  </code></pre>
  
  <p><br/>
  Non-working, data pass-through:</p>
  
  <pre><code>// 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) &amp;&amp; (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&lt;String, Void, String&gt; {
    @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;
     }
    }
   }
  }
  </code></pre>