增加google drive支持
This commit is contained in:
parent
dfb689522e
commit
c7a74b07d0
@ -244,6 +244,14 @@ NS_CC_BEGIN
|
||||
});
|
||||
return result == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL JNI_JCFW(decryptPass)(JNIEnv *env, jclass clazz, jstring jaccount, jstring jpass) {
|
||||
std::string pass_encrypted = JniHelper::jstring2string(jpass);
|
||||
std::string account = JniHelper::jstring2string(jaccount);
|
||||
std::string keyStr = account + "0x741482aE1480E552735E44Ff3A733448AcBbeD8d";
|
||||
std::string passDecrypt = decrypt_aes(pass_encrypted, keyStr);
|
||||
return env->NewStringUTF(passDecrypt.c_str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -138,6 +138,7 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="com.googleusercontent.apps.53206975661-asnf3qe4bg29p8h981pgf099osvrjbme" />
|
||||
<data android:scheme="cebg" android:path="/apple_login_result" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
@ -149,20 +150,20 @@
|
||||
<activity
|
||||
android:name=".apple.AppleLoginActivity"
|
||||
android:theme="@style/WebViewTheme" />
|
||||
<activity
|
||||
android:name=".apple.AppleLoginCbActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<!-- <activity-->
|
||||
<!-- android:name=".apple.AppleLoginCbActivity"-->
|
||||
<!-- android:exported="true">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.intent.action.VIEW" />-->
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<!-- <category android:name="android.intent.category.DEFAULT" />-->
|
||||
<!-- <category android:name="android.intent.category.BROWSABLE" />-->
|
||||
|
||||
<data
|
||||
android:scheme="cebg"
|
||||
android:path="/apple_login_result" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- <data-->
|
||||
<!-- android:scheme="cebg"-->
|
||||
<!-- android:path="/apple_login_result" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </activity>-->
|
||||
<activity
|
||||
android:name="com.facebook.FacebookActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
|
||||
|
@ -115,6 +115,17 @@ android {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
packagingOptions {
|
||||
exclude("META-INF/DEPENDENCIES")
|
||||
exclude("META-INF/LICENSE")
|
||||
exclude("META-INF/LICENSE.txt")
|
||||
exclude("META-INF/license.txt")
|
||||
exclude("META-INF/NOTICE")
|
||||
exclude("META-INF/NOTICE.txt")
|
||||
exclude("META-INF/notice.txt")
|
||||
exclude("META-INF/ASL2.0")
|
||||
exclude("META-INF/*.kotlin_module")
|
||||
}
|
||||
}
|
||||
|
||||
android.applicationVariants.all { variant ->
|
||||
@ -171,4 +182,15 @@ dependencies {
|
||||
// end of firebase
|
||||
// google pay
|
||||
implementation "com.android.billingclient:billing:6.0.1"
|
||||
|
||||
// google drive
|
||||
implementation('com.google.api-client:google-api-client-android:2.2.0') {
|
||||
exclude group: 'org.apache.httpcomponents'
|
||||
exclude module: 'guava-jdk5'
|
||||
}
|
||||
implementation 'com.google.http-client:google-http-client-android:1.23.0'
|
||||
implementation('com.google.apis:google-api-services-drive:v3-rev20230815-2.0.0') {
|
||||
exclude group: 'org.apache.httpcomponents'
|
||||
exclude module: 'guava-jdk5'
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package com.cege.games.release;
|
||||
|
||||
import static org.cocos2dx.lib.Cocos2dxHelper.getActivity;
|
||||
|
||||
import android.Manifest;
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
@ -33,6 +33,7 @@ import com.cege.games.release.activity.CustomCaptureActivity;
|
||||
import com.cege.games.release.activity.WebPageActivity;
|
||||
import com.cege.games.release.apple.AppleLoginActivity;
|
||||
import com.cege.games.release.dialog.QRCodeActivity;
|
||||
import com.cege.games.release.wallet.WalletUtil;
|
||||
import com.facebook.AccessToken;
|
||||
import com.facebook.CallbackManager;
|
||||
import com.facebook.FacebookCallback;
|
||||
@ -52,12 +53,13 @@ import com.google.android.gms.common.Scopes;
|
||||
import com.google.android.gms.common.api.ApiException;
|
||||
import com.google.android.gms.common.api.Scope;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
import com.google.api.services.drive.DriveScopes;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.firebase.analytics.FirebaseAnalytics;
|
||||
import com.jc.jcfw.JcSDK;
|
||||
import com.jc.jcfw.appauth.AuthStateManager;
|
||||
import com.jc.jcfw.appauth.JConfiguration;
|
||||
import com.jc.jcfw.google.PayClient;
|
||||
import com.jc.jcfw.util.IDUtils;
|
||||
import com.jc.jcfw.util.JsonUtils;
|
||||
import com.king.zxing.CameraScan;
|
||||
import com.king.zxing.util.CodeUtils;
|
||||
@ -85,10 +87,12 @@ import org.cocos2dx.lib.Cocos2dxHelper;
|
||||
import org.cocos2dx.lib.CocosJSHelper;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
@ -114,6 +118,10 @@ public class MainActivity extends UnityPlayerActivity
|
||||
private static final int RC_AUTH = 0X04;
|
||||
// google signin
|
||||
private static final int RC_SIGN_IN = 0X05;
|
||||
// code for request drive to upload
|
||||
private static final int RC_REQUEST_DRIVE_TO_UPLOAD = 0X051;
|
||||
// code for request drive to download
|
||||
private static final int RC_REQUEST_DRIVE_TO_READ = 0X052;
|
||||
|
||||
public static final int RC_CAMERA = 0X011;
|
||||
|
||||
@ -122,8 +130,6 @@ public class MainActivity extends UnityPlayerActivity
|
||||
public static final int FILE_SELECTOR_CODE = 0X014;
|
||||
private String title;
|
||||
private String funId;
|
||||
private String oid;
|
||||
|
||||
private QRCodeActivity qrCodeActivity;
|
||||
|
||||
// AppAuth
|
||||
@ -151,10 +157,9 @@ public class MainActivity extends UnityPlayerActivity
|
||||
|
||||
private FirebaseAnalytics mFirebaseAnalytics;
|
||||
private AppEventsLogger fbLogger;
|
||||
// store params for request permission or jump to other activity
|
||||
private final Map<Integer, Map<String, String>> paramCache = Maps.newHashMap();
|
||||
|
||||
private AccountManager accountManager;
|
||||
|
||||
private String accountType = "com.cege.games.auth";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -171,9 +176,8 @@ public class MainActivity extends UnityPlayerActivity
|
||||
|
||||
// begin of google sign
|
||||
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||
.requestScopes(new Scope(Scopes.EMAIL))
|
||||
.requestIdToken(getString(R.string.default_web_client_id1))
|
||||
.requestScopes(new Scope(Scopes.EMAIL), new Scope("https://www.googleapis.com/auth/drive.appdata"))
|
||||
// .requestScopes(new Scope("https://www.googleapis.com/auth/drive.appdata"))
|
||||
.build();
|
||||
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
|
||||
// end of google sign
|
||||
@ -197,10 +201,6 @@ public class MainActivity extends UnityPlayerActivity
|
||||
|
||||
PayClient payClient = PayClient.getInstance();
|
||||
payClient.init(this);
|
||||
accountManager = AccountManager.get(this.getApplicationContext());
|
||||
String id = IDUtils.id(this);
|
||||
Log.i(TAG, "custom id:: " + id);
|
||||
Log.i(TAG, "build info::" + IDUtils.getBuildInfo());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -243,9 +243,22 @@ public class MainActivity extends UnityPlayerActivity
|
||||
Uri uri = data.getData();
|
||||
shareToTikTok(funId, uri);
|
||||
break;
|
||||
case RC_REQUEST_DRIVE_TO_UPLOAD:
|
||||
mExecutor.submit(this::saveToDriveAppFolder);
|
||||
break;
|
||||
case RC_REQUEST_DRIVE_TO_READ:
|
||||
mExecutor.submit(this::loadDrivePass);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
boolean next = false;
|
||||
if (requestCode == RC_REQUEST_DRIVE_TO_UPLOAD || requestCode == RC_REQUEST_DRIVE_TO_READ) {
|
||||
Map<String, String> params = paramCache.get(requestCode);
|
||||
if (params != null) {
|
||||
JcSDK.nativeCb(params.get("funid"), "activity result with code: " + resultCode, null);
|
||||
paramCache.remove(requestCode);
|
||||
}
|
||||
}
|
||||
if (requestCode == REQUEST_CODE_SCAN && data != null) {
|
||||
if (data.getBooleanExtra("localImg", false)) {
|
||||
startPhotoCode(this.funId);
|
||||
@ -355,7 +368,6 @@ public class MainActivity extends UnityPlayerActivity
|
||||
runOnUiThread(() -> {
|
||||
this.startActivityForResult(intent, REQUEST_CODE_SCAN, optionsCompat.toBundle());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void asyncThread(Runnable runnable) {
|
||||
@ -417,7 +429,7 @@ public class MainActivity extends UnityPlayerActivity
|
||||
startActivityForResult(signInIntent, RC_SIGN_IN);
|
||||
}
|
||||
} else {
|
||||
Log.i(TAG, "no gms, use app auth");
|
||||
// Log.i(TAG, "no gms, use app auth");
|
||||
AuthState state = mAuthStateManager.getCurrent();
|
||||
if (state.isAuthorized() && state.getIdToken() != null) {
|
||||
Log.w(TAG, "getNeedsTokenRefresh: " + state.getNeedsTokenRefresh());
|
||||
@ -430,7 +442,7 @@ public class MainActivity extends UnityPlayerActivity
|
||||
} else {
|
||||
Log.w(TAG, "already login, accessToken not expired");
|
||||
Log.w(TAG, "id token : " + state.getIdToken());
|
||||
runOnUiThread(() -> successSdkCb(state.getIdToken()));
|
||||
JcSDK.nativeCb(this.funId, null, state.getIdToken());
|
||||
}
|
||||
} else {
|
||||
mExecutor.submit(this::doAuth);
|
||||
@ -450,7 +462,7 @@ public class MainActivity extends UnityPlayerActivity
|
||||
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
|
||||
Log.w(TAG, "signIn success: ");
|
||||
Log.w(TAG, "gsa idToken: " + account.getIdToken());
|
||||
runOnUiThread(() -> successSdkCb(account.getIdToken()));
|
||||
JcSDK.nativeCb(this.funId, null, account.getIdToken());
|
||||
// Signed in successfully, show authenticated UI.
|
||||
} catch (ApiException e) {
|
||||
// The ApiException status code indicates the detailed failure reason.
|
||||
@ -543,6 +555,9 @@ public class MainActivity extends UnityPlayerActivity
|
||||
mClientId.get(),
|
||||
ResponseTypeValues.CODE,
|
||||
mConfiguration.getRedirectUri())
|
||||
// apple need `form_post` when authorization_scope has `name email `
|
||||
// .setResponseMode("form_post")
|
||||
// .setResponseType("code id_token")
|
||||
.setScope(mConfiguration.getScope());
|
||||
|
||||
if (!TextUtils.isEmpty(loginHint)) {
|
||||
@ -709,20 +724,10 @@ public class MainActivity extends UnityPlayerActivity
|
||||
Log.d(TAG, "login success, auth state: " + state.isAuthorized());
|
||||
Log.d(TAG, "app auth idToken: " + state.getIdToken());
|
||||
mAuthStateManager.replace(state);
|
||||
runOnUiThread(() -> successSdkCb(state.getIdToken()));
|
||||
JcSDK.nativeCb(this.funId, null, state.getIdToken());
|
||||
}
|
||||
}
|
||||
|
||||
@MainThread
|
||||
private void successSdkCb(String idToken) {
|
||||
JcSDK.nativeCb(this.funId, null, idToken);
|
||||
}
|
||||
|
||||
@MainThread
|
||||
private void errorSdkCb(String errMsg) {
|
||||
JcSDK.nativeCb(this.funId, errMsg, null);
|
||||
}
|
||||
|
||||
// sign with tiktok
|
||||
public void signWithTiktok(String funId) {
|
||||
this.funId = funId;
|
||||
@ -769,20 +774,20 @@ public class MainActivity extends UnityPlayerActivity
|
||||
AccessToken accessToken = AccessToken.getCurrentAccessToken();
|
||||
Log.d(TAG, "Login Success:: accessToken: " + accessToken.getToken());
|
||||
if (!verifyFbAccessToken(accessToken)) {
|
||||
runOnUiThread(() -> errorSdkCb("access token expired"));
|
||||
JcSDK.nativeCb(MainActivity.app.funId, "access token expired", null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
Log.d(TAG, "Login cancel");
|
||||
runOnUiThread(() -> errorSdkCb("user login cancel"));
|
||||
JcSDK.nativeCb(MainActivity.app.funId, "user login cancel", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(FacebookException exception) {
|
||||
Log.i(TAG, "Login error: " + exception.getMessage());
|
||||
runOnUiThread(() -> errorSdkCb(exception.getMessage()));
|
||||
JcSDK.nativeCb(MainActivity.app.funId, exception.getMessage(), null);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -791,12 +796,9 @@ public class MainActivity extends UnityPlayerActivity
|
||||
Log.i(TAG, "login with facebook: " + funId);
|
||||
this.funId = funId;
|
||||
AccessToken accessToken = AccessToken.getCurrentAccessToken();
|
||||
// Log.d("Success", "Login:: accessToken: " + accessToken.getToken());
|
||||
if (!verifyFbAccessToken(accessToken)) {
|
||||
LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile", "email"));
|
||||
}
|
||||
|
||||
// AccessToken.getCurrentAccessToken();
|
||||
}
|
||||
|
||||
public void shareWithFacebook(String content) {
|
||||
@ -810,7 +812,7 @@ public class MainActivity extends UnityPlayerActivity
|
||||
private boolean verifyFbAccessToken(AccessToken accessToken) {
|
||||
boolean isLoggedIn = accessToken != null && !accessToken.isExpired();
|
||||
if (isLoggedIn) {
|
||||
runOnUiThread(() -> successSdkCb(accessToken.getToken()));
|
||||
JcSDK.nativeCb(this.funId, null, accessToken.getToken());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -852,9 +854,6 @@ public class MainActivity extends UnityPlayerActivity
|
||||
Intent intent = new Intent(this, WebPageActivity.class);
|
||||
intent.putExtra("url", url);
|
||||
startActivity(intent);
|
||||
// picker video file and share to tiktok
|
||||
// openFileSelector();
|
||||
// authenticateToEncrypt("1111");
|
||||
});
|
||||
}
|
||||
|
||||
@ -905,19 +904,48 @@ public class MainActivity extends UnityPlayerActivity
|
||||
Log.i(TAG, "passStorageState with: " + account);
|
||||
}
|
||||
|
||||
private void saveToDriveAppFolder() {
|
||||
Map<String, String> params = paramCache.get(RC_REQUEST_DRIVE_TO_UPLOAD);
|
||||
if (params == null) {
|
||||
return;
|
||||
}
|
||||
WalletUtil.saveToDriveAppFolder(params.get("funid"), params.get("account"), JcSDK::nativeCb);
|
||||
paramCache.remove(RC_REQUEST_DRIVE_TO_UPLOAD);
|
||||
}
|
||||
|
||||
private void loginAndRequestDrivePermission(String funid, String account, int requestCode) {
|
||||
Log.i(TAG, "no drive permission");
|
||||
Map<String, String> params = Maps.newHashMap();
|
||||
params.put("funid", funid);
|
||||
params.put("account", account);
|
||||
paramCache.put(requestCode, params);
|
||||
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||
.requestIdToken(getString(R.string.default_web_client_id1))
|
||||
.requestScopes(new Scope(Scopes.EMAIL), new Scope(DriveScopes.DRIVE_APPDATA))
|
||||
.build();
|
||||
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
|
||||
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
|
||||
startActivityForResult(signInIntent, requestCode);
|
||||
}
|
||||
public void storagePass(String funid, String account, String password) {
|
||||
Log.i(TAG, "storagePass with: " + account + " | " + password);
|
||||
Bundle userData = new Bundle();
|
||||
userData.putString("pass", password);
|
||||
// save to account manage
|
||||
runOnUiThread(() -> {
|
||||
final Account act = new Account(account, accountType);
|
||||
if (accountManager.addAccountExplicitly(act, password, userData)) {
|
||||
Log.i(TAG, "storage pass success");
|
||||
} else {
|
||||
Log.i(TAG, "storage pass error");
|
||||
}
|
||||
});
|
||||
Log.i(TAG, String.format("storagePass with: %s | %s | %s", funid, account, password));
|
||||
String filePath;
|
||||
try {
|
||||
filePath = WalletUtil.savePassToLocal(this, account, password);
|
||||
} catch (JSONException | IOException e) {
|
||||
Log.i(TAG, String.format("error storage pass to local, %s", e.getMessage()));
|
||||
JcSDK.nativeCb(funid, "error storage pass to local", null);
|
||||
return;
|
||||
}
|
||||
if (!GoogleSignIn.hasPermissions(
|
||||
GoogleSignIn.getLastSignedInAccount(getActivity()),
|
||||
new Scope(DriveScopes.DRIVE_APPDATA))) {
|
||||
loginAndRequestDrivePermission(funid, account, RC_REQUEST_DRIVE_TO_UPLOAD);
|
||||
} else {
|
||||
Log.i(TAG, "had drive permission");
|
||||
WalletUtil.saveToDriveAppFolder(funid, account, JcSDK::nativeCb);
|
||||
}
|
||||
|
||||
// runOnUiThread(() -> {
|
||||
// Intent intent = new Intent(this, BiometricActivity.class);
|
||||
// intent.putExtra("action", "encrypt");
|
||||
@ -927,13 +955,30 @@ public class MainActivity extends UnityPlayerActivity
|
||||
// startActivity(intent);
|
||||
// });
|
||||
}
|
||||
|
||||
private void loadDrivePass() {
|
||||
Map<String, String> params = paramCache.get(RC_REQUEST_DRIVE_TO_READ);
|
||||
if (params == null) {
|
||||
return;
|
||||
}
|
||||
WalletUtil.downloadCfgToLocal(params.get("funid"), params.get("account"));
|
||||
WalletUtil.getPassLocal(this, params.get("funid"), params.get("account"));
|
||||
paramCache.remove(RC_REQUEST_DRIVE_TO_READ);
|
||||
}
|
||||
public void authGetStoragePass(String funid, String account) {
|
||||
Log.i(TAG, "authGetStoragePass with: " + account);
|
||||
// Account[] accounts = accountManager.getAccountsByType(accountType);
|
||||
// for (Account act : accounts) {
|
||||
// Log.i(TAG, "authGetStoragePass account: " + act.name + " | " + act.type );
|
||||
// }
|
||||
if (!WalletUtil.localCfgExists(this, account)) {
|
||||
if (!GoogleSignIn.hasPermissions(
|
||||
GoogleSignIn.getLastSignedInAccount(getActivity()),
|
||||
new Scope(DriveScopes.DRIVE_APPDATA))) {
|
||||
loginAndRequestDrivePermission(funid, account, RC_REQUEST_DRIVE_TO_READ);
|
||||
} else {
|
||||
WalletUtil.downloadCfgToLocal(funid, account);
|
||||
WalletUtil.getPassLocal(this, funid, account);
|
||||
}
|
||||
} else {
|
||||
WalletUtil.getPassLocal(this, funid, account);
|
||||
}
|
||||
|
||||
|
||||
// runOnUiThread(() -> {
|
||||
// Intent intent = new Intent(this, BiometricActivity.class);
|
||||
@ -946,6 +991,5 @@ public class MainActivity extends UnityPlayerActivity
|
||||
|
||||
public void getClientId(String funid) {
|
||||
Log.i(TAG, "getClientId ");
|
||||
|
||||
}
|
||||
}
|
138
app/src/com/cege/games/release/wallet/WalletUtil.java
Normal file
138
app/src/com/cege/games/release/wallet/WalletUtil.java
Normal file
@ -0,0 +1,138 @@
|
||||
package com.cege.games.release.wallet;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.cege.games.release.MainActivity;
|
||||
import com.cege.games.release.R;
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignIn;
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
|
||||
import com.google.android.gms.common.api.Scope;
|
||||
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
|
||||
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
|
||||
import com.google.api.services.drive.Drive;
|
||||
import com.google.api.services.drive.DriveScopes;
|
||||
import com.google.common.base.Strings;
|
||||
import com.jc.jcfw.JcSDK;
|
||||
import com.jc.jcfw.NativeResult;
|
||||
import com.jc.jcfw.security.BiometricResult;
|
||||
import com.jc.jcfw.util.DriveUtils;
|
||||
import com.jc.jcfw.util.FileUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class WalletUtil {
|
||||
private static final String TAG = WalletUtil.class.getSimpleName();
|
||||
|
||||
public static String generateFileName(String account) {
|
||||
return String.format("wallet_%s.json", account);
|
||||
}
|
||||
|
||||
public static File getWalletCfgFile(Context context, String account) {
|
||||
String filename = generateFileName(account);
|
||||
File dic = new File(context.getFilesDir() + "/wallets");
|
||||
if (!dic.exists()) {
|
||||
dic.mkdir();
|
||||
}
|
||||
return new File(context.getFilesDir() + "/wallets", filename);
|
||||
}
|
||||
|
||||
public static String savePassToLocal(Context context, String account, String pass) throws IOException, JSONException {
|
||||
File filePath = getWalletCfgFile(context, account);
|
||||
JSONObject content = new JSONObject();
|
||||
content.put("pass", pass);
|
||||
FileUtils.writeFile(filePath, content.toString());
|
||||
return filePath.getAbsolutePath();
|
||||
}
|
||||
|
||||
public static void getPassLocal(Context context, String funId, String account) {
|
||||
try {
|
||||
JSONObject json = loadLocalCfg(context, account);
|
||||
String passEncrypted = json.getString("pass");
|
||||
String passDecrypted = JcSDK.decryptPass(account, passEncrypted);
|
||||
JcSDK.nativeCb(funId, null, passDecrypted);
|
||||
} catch (JSONException e) {
|
||||
JcSDK.nativeCb(funId, "error decode json", null);
|
||||
} catch (IOException e) {
|
||||
JcSDK.nativeCb(funId, "error read cfg file", null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean localCfgExists(Context context, String account) {
|
||||
File filePath = getWalletCfgFile(context, account);
|
||||
return filePath.exists();
|
||||
}
|
||||
|
||||
public static JSONObject loadLocalCfg(Context context, String account) throws JSONException, IOException {
|
||||
File filePath = getWalletCfgFile(context, account);
|
||||
if (!filePath.exists()) {
|
||||
return null;
|
||||
}
|
||||
return FileUtils.readJsonFromFile(filePath);
|
||||
}
|
||||
|
||||
public static void saveToDriveAppFolder(String funid, String account, Consumer<NativeResult> func) {
|
||||
Context context = MainActivity.app;
|
||||
GoogleSignInAccount ga = GoogleSignIn.getLastSignedInAccount(context);
|
||||
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(context,
|
||||
Collections.singletonList(DriveScopes.DRIVE_APPDATA));
|
||||
credential.setSelectedAccount(ga.getAccount());
|
||||
Drive service = DriveUtils.generateService(credential, context.getString(R.string.app_name));
|
||||
try {
|
||||
File file = getWalletCfgFile(MainActivity.app, account);
|
||||
String fileName = file.getName();
|
||||
String fileId = DriveUtils.queryOneAppFile(service, fileName);
|
||||
if (Strings.isNullOrEmpty(fileId)) {
|
||||
Log.i(TAG, String.format("%s not exists in drive, upload...", fileName));
|
||||
fileId = DriveUtils.uploadAppFile(service, file, "application/json");
|
||||
}
|
||||
Log.i(TAG, "File ID: " + fileId);
|
||||
func.accept(new NativeResult(funid, null, fileId));
|
||||
} catch (GoogleJsonResponseException e) {
|
||||
Log.i(TAG, "Unable to create file: " + e.getDetails());
|
||||
func.accept(new NativeResult(funid, e.getMessage(), null));
|
||||
} catch (IOException e) {
|
||||
Log.i(TAG, e.getMessage());
|
||||
func.accept(new NativeResult(funid, e.getMessage(), null));
|
||||
}
|
||||
}
|
||||
|
||||
public static void downloadCfgToLocal(String funid, String account) {
|
||||
Context context = MainActivity.app;
|
||||
GoogleSignInAccount ga = GoogleSignIn.getLastSignedInAccount(context);
|
||||
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(context,
|
||||
Collections.singletonList(DriveScopes.DRIVE_APPDATA));
|
||||
credential.setSelectedAccount(ga.getAccount());
|
||||
Drive service = DriveUtils.generateService(credential, context.getString(R.string.app_name));
|
||||
String fileName = generateFileName(account);
|
||||
String fileId = DriveUtils.queryOneAppFile(service, fileName);
|
||||
|
||||
|
||||
if (Strings.isNullOrEmpty(fileId)) {
|
||||
Log.i(TAG, "file not found in drive");
|
||||
return;
|
||||
}
|
||||
boolean downloadSuccess = false;
|
||||
while (!downloadSuccess) {
|
||||
try {
|
||||
String jsonStr = DriveUtils.downloadFile(service, fileId);
|
||||
File fileLocal = getWalletCfgFile(context, account);
|
||||
FileUtils.writeFile(fileLocal, jsonStr);
|
||||
downloadSuccess = true;
|
||||
} catch (IOException e) {
|
||||
Log.i(TAG, "error download file");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -7,7 +7,9 @@ import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
import com.cege.games.release.MainActivity;
|
||||
import com.google.common.base.Strings;
|
||||
import com.jc.jcfw.google.PayClient;
|
||||
import com.jc.jcfw.util.ThreadUtils;
|
||||
|
||||
import org.cocos2dx.lib.CocosJSHelper;
|
||||
import org.json.JSONException;
|
||||
@ -27,6 +29,8 @@ public class JcSDK {
|
||||
|
||||
private static native int runJS(final String funId, final String methodName, final String params);
|
||||
|
||||
public static native String decryptPass(final String account, final String pass);
|
||||
|
||||
public static void initCommonCB(UnityCallback callBack) {
|
||||
Log.i(TAG, "call init common callback from unity");
|
||||
commonCB = callBack;
|
||||
@ -174,18 +178,15 @@ public class JcSDK {
|
||||
MainActivity.app.getClientId(funid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 回调至js
|
||||
*/
|
||||
public static void nativeCb(String funId, String error, String dataStr) {
|
||||
JSONObject result = new JSONObject();
|
||||
try {
|
||||
if (error != null && !error.isEmpty()) {
|
||||
result.put("errcode", 1);
|
||||
result.put("errmessage", error);
|
||||
} else {
|
||||
if (Strings.isNullOrEmpty(error)) {
|
||||
result.put("errcode", 0);
|
||||
result.put("data", dataStr);
|
||||
} else {
|
||||
result.put("errcode", 1);
|
||||
result.put("errmessage", error);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "JSONException: " + e.getMessage());
|
||||
@ -193,6 +194,17 @@ public class JcSDK {
|
||||
if (funId == null || funId.isEmpty()) {
|
||||
funId = MainActivity.app.getFunId();
|
||||
}
|
||||
JcSDK.runJS(funId, "jniCallback", result.toString());
|
||||
Log.i(TAG, String.format("%s native cb, error: %s, data: %s", funId, error, dataStr ));
|
||||
if (ThreadUtils.isMainThread()) {
|
||||
JcSDK.runJS(funId, "jniCallback", result.toString());
|
||||
} else {
|
||||
String finalFunId = funId;
|
||||
MainActivity.app.runOnUiThread(() -> JcSDK.runJS(finalFunId, "jniCallback", result.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void nativeCb(NativeResult result) {
|
||||
nativeCb(result.getFunid(), result.getError(), result.getDataStr());
|
||||
}
|
||||
}
|
||||
|
37
app/src/com/jc/jcfw/NativeResult.java
Normal file
37
app/src/com/jc/jcfw/NativeResult.java
Normal file
@ -0,0 +1,37 @@
|
||||
package com.jc.jcfw;
|
||||
|
||||
public class NativeResult {
|
||||
private String funid;
|
||||
private String error;
|
||||
private String dataStr;
|
||||
|
||||
public NativeResult(String funid, String error, String dataStr) {
|
||||
this.funid = funid;
|
||||
this.error = error;
|
||||
this.dataStr = dataStr;
|
||||
}
|
||||
|
||||
public String getFunid() {
|
||||
return funid;
|
||||
}
|
||||
|
||||
public void setFunid(String funid) {
|
||||
this.funid = funid;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public String getDataStr() {
|
||||
return dataStr;
|
||||
}
|
||||
|
||||
public void setDataStr(String dataStr) {
|
||||
this.dataStr = dataStr;
|
||||
}
|
||||
}
|
101
app/src/com/jc/jcfw/util/DriveUtils.java
Normal file
101
app/src/com/jc/jcfw/util/DriveUtils.java
Normal file
@ -0,0 +1,101 @@
|
||||
package com.jc.jcfw.util;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.api.client.extensions.android.http.AndroidHttp;
|
||||
import com.google.api.client.extensions.android.json.AndroidJsonFactory;
|
||||
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
|
||||
import com.google.api.client.http.FileContent;
|
||||
import com.google.api.services.drive.Drive;
|
||||
import com.google.api.services.drive.model.File;
|
||||
import com.google.api.services.drive.model.FileList;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class DriveUtils {
|
||||
private static final String TAG = DriveUtils.class.getSimpleName();
|
||||
|
||||
public static Drive generateService(GoogleAccountCredential credential, String appName) {
|
||||
return new Drive.Builder(
|
||||
AndroidHttp.newCompatibleTransport(),
|
||||
AndroidJsonFactory.getDefaultInstance(),
|
||||
credential)
|
||||
.setApplicationName(appName)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* query app file by filename
|
||||
*
|
||||
* @param service
|
||||
* @param fileName
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String queryOneAppFile(Drive service, String fileName) {
|
||||
boolean querySuccess = false;
|
||||
String fileId = "";
|
||||
while (!querySuccess) {
|
||||
try {
|
||||
FileList files = service.files().list()
|
||||
.setSpaces("appDataFolder")
|
||||
.setFields("nextPageToken, files(id, name)")
|
||||
.setPageSize(100)
|
||||
.execute();
|
||||
querySuccess = true;
|
||||
for (File file : files.getFiles()) {
|
||||
Log.i(TAG, String.format("Found file: %s (%s)\n", file.getName(), file.getId()));
|
||||
if (file.getName().equals(fileName)) {
|
||||
fileId = file.getId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.i(TAG, "error query file from drive");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return fileId;
|
||||
}
|
||||
|
||||
/**
|
||||
* download one file from drive
|
||||
*
|
||||
* @param service
|
||||
* @param fileId
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String downloadFile(Drive service, String fileId) throws IOException {
|
||||
OutputStream outputStream = new ByteArrayOutputStream();
|
||||
service.files().get(fileId).executeMediaAndDownloadTo(outputStream);
|
||||
// convert outputStream to JSON string
|
||||
// String json = outputStream.toString();
|
||||
return outputStream.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* upload one file to Drive
|
||||
*
|
||||
* @param service
|
||||
* @param filePath file absolute path
|
||||
* @param fileType application/json
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String uploadAppFile(Drive service, java.io.File filePath, String fileType) throws IOException {
|
||||
String fileName = filePath.getName();
|
||||
File fileMetadata = new File();
|
||||
fileMetadata.setName(fileName);
|
||||
fileMetadata.setParents(Collections.singletonList("appDataFolder"));
|
||||
// "application/json"
|
||||
FileContent mediaContent = new FileContent(fileType, filePath);
|
||||
File file = service.files().create(fileMetadata, mediaContent)
|
||||
.setFields("id")
|
||||
.execute();
|
||||
Log.i(TAG, String.format("%s upload success, File ID: %s", fileName, file.getId()));
|
||||
return file.getId();
|
||||
}
|
||||
}
|
@ -13,10 +13,15 @@ import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public class FileUtils {
|
||||
private static final String TAG = FileUtils.class.getSimpleName();
|
||||
@ -26,7 +31,7 @@ public class FileUtils {
|
||||
* @param fileName path
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
static boolean fileIsExist(String fileName) {
|
||||
public static boolean fileIsExist(String fileName) {
|
||||
File file = new File(fileName);
|
||||
if (file.exists())
|
||||
return true;
|
||||
@ -35,6 +40,20 @@ public class FileUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeFile(File filePath, String content) throws IOException {
|
||||
FileOutputStream out = new FileOutputStream(filePath);
|
||||
out.write(content.getBytes());
|
||||
out.close();
|
||||
}
|
||||
|
||||
public static JSONObject readJsonFromFile(File filePath) throws IOException, JSONException {
|
||||
RandomAccessFile f = new RandomAccessFile(filePath, "r");
|
||||
byte[] bytes = new byte[(int) f.length()];
|
||||
f.readFully(bytes);
|
||||
f.close();
|
||||
return new JSONObject(new String(bytes));
|
||||
}
|
||||
|
||||
/**
|
||||
* get image base path of external storage
|
||||
*/
|
||||
|
@ -9,7 +9,8 @@ import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.cege.games.release.MainActivity;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@ -20,7 +21,7 @@ import java.util.UUID;
|
||||
|
||||
public class IDUtils {
|
||||
private static String sID = null;
|
||||
private static final String WALLET_STATS = "wallets";
|
||||
private static final String WALLET_STATS = "wallet.json";
|
||||
|
||||
public synchronized static String id(Context context) {
|
||||
if (sID == null) {
|
||||
@ -37,18 +38,23 @@ public class IDUtils {
|
||||
return sID;
|
||||
}
|
||||
|
||||
private static String readInstallationFile(File installation) throws IOException {
|
||||
private static String readInstallationFile(File installation) throws IOException, JSONException {
|
||||
RandomAccessFile f = new RandomAccessFile(installation, "r");
|
||||
byte[] bytes = new byte[(int) f.length()];
|
||||
f.readFully(bytes);
|
||||
f.close();
|
||||
return new String(bytes);
|
||||
String jsonStr = new String(bytes);
|
||||
Log.i("IDUtils", jsonStr);
|
||||
JSONObject content = new JSONObject(new String(bytes));
|
||||
return content.getString("id");
|
||||
}
|
||||
|
||||
private static void writeInstallationFile(File installation) throws IOException {
|
||||
private static void writeInstallationFile(File installation) throws IOException, JSONException {
|
||||
FileOutputStream out = new FileOutputStream(installation);
|
||||
String id = UUID.randomUUID().toString();
|
||||
out.write(id.getBytes());
|
||||
JSONObject content = new JSONObject();
|
||||
content.put("id", id);
|
||||
out.write(content.toString().getBytes());
|
||||
out.close();
|
||||
}
|
||||
|
||||
|
14
app/src/com/jc/jcfw/util/ThreadUtils.java
Normal file
14
app/src/com/jc/jcfw/util/ThreadUtils.java
Normal file
@ -0,0 +1,14 @@
|
||||
package com.jc.jcfw.util;
|
||||
|
||||
import android.os.Looper;
|
||||
|
||||
public class ThreadUtils {
|
||||
/**
|
||||
* check if current thread is main thread
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static boolean isMainThread() {
|
||||
return Looper.getMainLooper() == Looper.myLooper();
|
||||
}
|
||||
}
|
12
res/raw/apple_config.json
Normal file
12
res/raw/apple_config.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"client_id": "wallet.cebggame.com",
|
||||
"redirect_uri": "https://wallet.cebggame.com/apple/oauth_redirect",
|
||||
"end_session_redirect_uri": "com.apple.apps.wallet.cebggame.com:/oauth2redirect",
|
||||
"authorization_scope": "name email",
|
||||
"discovery_uri": "https://appleid.apple.com/.well-known/openid-configuration",
|
||||
"authorization_endpoint_uri": "",
|
||||
"token_endpoint_uri": "",
|
||||
"registration_endpoint_uri": "",
|
||||
"user_info_endpoint_uri": "",
|
||||
"https_required": true
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user