java - Cordova 和 startResolutionForResult VS。开始 Activity 返回结果

标签 java android cordova google-play-services

我正在为 Google Play 制作 Cordova 插件。目前,我已经通过手动修改我的 CordovaActivity 函数“损坏”了该插件。我需要将所有代码放入插件文件中,而不是在 CordovaActivity 和插件文件之间拆分。

为此,我需要将通过 startResolutionForResult 发起的 onActivityResult 回调传输到特定于插件的函数中。作为比较,我相信 startActivityForResult 确实有这种机制,但我找不到 startResolutionForResult 类似的东西。

有人能想出一种机制来做到这一点吗?

这是我的 CordovaActivity 代码和我的插件代码。

Cordova Activity :

package com.flyingsoft.safari.jigsaw.free;

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

import android.util.Log;

import android.content.Intent;

import com.flyingsoftgames.googleplayservices.GooglePlayServices;

public class MyGame extends CordovaActivity {

 private static final String LOGTAG = "MyGame";

 public void onActivityResult (int requestCode, int responseCode, Intent intent) {
  Log.w (LOGTAG, "onActivityResult");
  if (!GooglePlayServices.mGoogleApiClient.isConnecting()) GooglePlayServices.mGoogleApiClient.connect ();
 }

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


Plugin:

package com.flyingsoftgames.googleplayservices;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.games.Players;
import com.google.android.gms.games.Games;

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.auth.GooglePlayServicesAvailabilityException;
import com.google.android.gms.plus.Account;
import com.google.android.gms.plus.Plus;

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

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

import android.content.Context;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;

import android.app.Activity;

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

import java.io.IOException;

import android.util.Log;

public class GooglePlayServices extends CordovaPlugin implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

 private static final String LOGTAG = "GooglePlayServices";
 private static final int REQ_SIGN_IN_REQUIRED = 55664;

 public CordovaInterface       cordova            = null;
 public CordovaWebView         webView            = null;
 public static GoogleApiClient mGoogleApiClient   = null;
 public CallbackContext        tryConnectCallback = null;
 public String                 accessToken        = "";

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

 @Override public void onConnectionFailed (ConnectionResult result) {
  if (!result.hasResolution()) {Log.w (LOGTAG, "Error: no resolution. Google Play Services connection failed."); return;}
  try {
   result.startResolutionForResult (cordova.getActivity(), result.getErrorCode());
  } catch (SendIntentException e) {
   // There was an error with the resolution intent. Try again.
   mGoogleApiClient.connect ();
  }
 }

 @Override public void onConnected (Bundle connectionHint) {
  String mAccountName = Plus.AccountApi.getAccountName(mGoogleApiClient);
  new RetrieveTokenTask().execute (mAccountName);
  Games.setViewForPopups (mGoogleApiClient, webView);
 }

 public void onActivityResult (int requestCode, int responseCode, Intent intent) {
  if (!mGoogleApiClient.isConnecting()) mGoogleApiClient.connect ();
 }

 @Override public void onConnectionSuspended (int cause) {
  mGoogleApiClient.connect ();
 }

 public boolean execute (String action, JSONArray inputs, CallbackContext callbackContext) throws JSONException {
  if        ("getPlayerId".equals(action)) {
   String playerId = Games.Players.getCurrentPlayerId (mGoogleApiClient);
   callbackContext.sendPluginResult (new PluginResult (PluginResult.Status.OK, playerId));
  } else 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) {
  boolean isGpsAvailable = (GooglePlayServicesUtil.isGooglePlayServicesAvailable(cordova.getActivity()) == ConnectionResult.SUCCESS);
  if (!isGpsAvailable) {
   callbackContext.sendPluginResult (new PluginResult (PluginResult.Status.OK, false));
   return;
  }
  tryConnectCallback = callbackContext;
  mGoogleApiClient = new GoogleApiClient.Builder (cordova.getActivity().getApplicationContext())
   .addConnectionCallbacks (this)
   .addOnConnectionFailedListener (this)
   .addApi (Games.API)
   .addScope (Games.SCOPE_GAMES)
   .addApi(Plus.API)
   .addScope(Plus.SCOPE_PLUS_LOGIN)
   .build ();
  mGoogleApiClient.connect ();
 }


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

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

最佳答案

我实际上找到了解决方案。

在扩展 CordovaPlugin 的类的初始化方法中,只需调用:

cordova.setActivityResultCallback(this);

然后实现该方法:

public void onActivityResult(int requestCode, int resultCode, Intent data)

就像您在 Android 上通常所做的那样。

关于java - Cordova 和 startResolutionForResult VS。开始 Activity 返回结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26725049/

相关文章:

android - Ionic Cordova 构建失败并出现错误无法应用插件

java - 迭代 if 条件

java - 如何检测顶级合法搜索引擎机器人?

java并发: lightweight nonblocking semaphore?

使用安卓摄像头的安卓人脸检测器

java - 为什么除以零会得到 9.223372E+18?

android - 将服务绑定(bind)到多个 Activity

java - 我应该在这里使用什么注释?@OneToMany 还是@OneToOne?

ios - 两个 Cordova WebView 加载不同的 html 页面,如何?

javascript - 在cordova中使用chrome View 而不是默认的webview