Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
60bd02b5a4 | ||
![]() |
d7dd12c0d9 | ||
![]() |
258d19f620 | ||
![]() |
035ef84a24 | ||
![]() |
f98a1076c4 | ||
![]() |
039b7da4f0 | ||
![]() |
1cd508af00 |
1
.idea/gradle.xml
generated
1
.idea/gradle.xml
generated
@ -12,6 +12,7 @@
|
|||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
<option value="$PROJECT_DIR$/app" />
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
<option value="$PROJECT_DIR$/../../crypto/cocos_js/cocos/platform/android/libcocos2dx" />
|
||||||
<option value="$PROJECT_DIR$/../../game/wallet-test/target/android/UnityDataAssetPack" />
|
<option value="$PROJECT_DIR$/../../game/wallet-test/target/android/UnityDataAssetPack" />
|
||||||
<option value="$PROJECT_DIR$/../../game/wallet-test/target/android/unityLibrary" />
|
<option value="$PROJECT_DIR$/../../game/wallet-test/target/android/unityLibrary" />
|
||||||
</set>
|
</set>
|
||||||
|
File diff suppressed because one or more lines are too long
@ -409,30 +409,30 @@ function verifyEmail(funId, email, code) {
|
|||||||
promiseCb(funId, jc.wallet.emailVerifySvr.updateEmailVerify(email, code));
|
promiseCb(funId, jc.wallet.emailVerifySvr.updateEmailVerify(email, code));
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * check if email had already been registed
|
* check if email had already been registed
|
||||||
// * @param {string} email
|
* @param {string} email
|
||||||
// */
|
*/
|
||||||
// function checkEmailExists(funId, email) {
|
function checkEmailExists(funId, email) {
|
||||||
// promiseCb(funId, jc.wallet.emailVerifySvr.isEmailRegister(email));
|
promiseCb(funId, jc.wallet.emailVerifySvr.isEmailRegister(email));
|
||||||
// }
|
}
|
||||||
// /**
|
/**
|
||||||
// * regist with email
|
* regist with email
|
||||||
// * @param {*} email
|
* @param {*} email
|
||||||
// * @param {*} password
|
* @param {*} password
|
||||||
// * @param {*} code
|
* @param {*} code
|
||||||
// */
|
*/
|
||||||
// function emailRegist(funId, email, password, code) {
|
function emailRegist(funId, email, password, code) {
|
||||||
// promiseCb(funId, jc.wallet.emailVerifySvr.registByEmail(email, password, code));
|
promiseCb(funId, jc.wallet.emailVerifySvr.registByEmail(email, password, code));
|
||||||
// }
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* login with email
|
* login with email
|
||||||
* @param {*} email
|
* @param {*} email
|
||||||
* @param {*} password
|
* @param {*} password
|
||||||
*/
|
*/
|
||||||
function emailLogin(funId, email, password, account) {
|
function emailLogin(funId, email, password) {
|
||||||
promiseCb(funId, jc.wallet.emailLogin(email, password, account));
|
promiseCb(funId, jc.wallet.emailLogin(email, password));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -851,8 +851,3 @@ function getLocalPassState(funId, key) {
|
|||||||
promiseCb(funId, jc.wallet.nativeSvr.passStorageState(key));
|
promiseCb(funId, jc.wallet.nativeSvr.passStorageState(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
function createShareCode(funId, type) {
|
|
||||||
type = parseInt(type || '1');
|
|
||||||
promiseCb(funId, jc.wallet.generateShareCode(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
android:extractNativeLibs="true"
|
android:extractNativeLibs="true"
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||||
|
<!-- Tell Cocos2dxActivity the name of our .so -->
|
||||||
|
<meta-data
|
||||||
|
android:name="android.app.lib_name"
|
||||||
|
android:value="cocos2djs" />
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="firebase_crashlytics_collection_enabled"
|
android:name="firebase_crashlytics_collection_enabled"
|
||||||
android:value="true" />
|
android:value="true" />
|
||||||
@ -25,9 +29,20 @@
|
|||||||
android:value="@string/facebook_client_token" />
|
android:value="@string/facebook_client_token" />
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:authorities="com.facebook.app.FacebookContentProvider927390338872834"
|
android:authorities="com.facebook.app.FacebookContentProvider1204701000119770"
|
||||||
android:name="com.facebook.FacebookContentProvider"
|
android:name="com.facebook.FacebookContentProvider"
|
||||||
android:exported="true" />
|
android:exported="true" />
|
||||||
|
<provider
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:authorities="com.cege.games.release.provider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true"
|
||||||
|
tools:replace="android:authorities">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/app_files"
|
||||||
|
tools:replace="android:resource" />
|
||||||
|
</provider>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
@ -88,6 +103,38 @@
|
|||||||
android:path="/relay_cb" />
|
android:path="/relay_cb" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.king.zxing.CaptureActivity"
|
||||||
|
android:theme="@style/CaptureTheme" />
|
||||||
|
<activity
|
||||||
|
android:name=".activity.WebPageActivity"
|
||||||
|
android:screenOrientation="sensorLandscape"
|
||||||
|
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout"
|
||||||
|
android:theme="@style/WebViewTheme" />
|
||||||
|
<activity
|
||||||
|
android:name=".activity.BiometricActivity"
|
||||||
|
android:theme="@style/DayNightActivity"
|
||||||
|
android:screenOrientation="sensorLandscape"
|
||||||
|
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|layoutDirection"
|
||||||
|
/>
|
||||||
|
<activity
|
||||||
|
android:name=".activity.CustomCaptureActivity"
|
||||||
|
android:theme="@style/CaptureTheme" />
|
||||||
|
<!--
|
||||||
|
This activity declaration is merged with the version from the library manifest.
|
||||||
|
It demonstrates how an https redirect can be captured, in addition to or instead of
|
||||||
|
a custom scheme.
|
||||||
|
|
||||||
|
Generally, this should be done in conjunction with an app link declaration for Android M
|
||||||
|
and above, for additional security and an improved user experience. See:
|
||||||
|
|
||||||
|
https://developer.android.com/training/app-links/index.html
|
||||||
|
|
||||||
|
The declaration from the library can be completely replaced by adding tools:node="replace"
|
||||||
|
|
||||||
|
To the list of attributes on the activity element.
|
||||||
|
-->
|
||||||
<activity
|
<activity
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:name="net.openid.appauth.RedirectUriReceiverActivity"
|
android:name="net.openid.appauth.RedirectUriReceiverActivity"
|
||||||
@ -118,6 +165,12 @@
|
|||||||
<data android:pathPrefix="/google"/>
|
<data android:pathPrefix="/google"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".tiktokapi.TikTokEntryActivity"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:taskAffinity="com.cege.games.release"
|
||||||
|
android:exported="true" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".oauth.OAuthLoginCbActivity"
|
android:name=".oauth.OAuthLoginCbActivity"
|
||||||
tools:node="replace"
|
tools:node="replace"
|
||||||
@ -131,21 +184,22 @@
|
|||||||
<data android:scheme="cfoauthcb" android:path="/login_result" />
|
<data android:scheme="cfoauthcb" android:path="/login_result" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name="com.facebook.FacebookActivity"
|
||||||
|
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
|
||||||
|
android:label="@string/app_name" />
|
||||||
|
<activity
|
||||||
|
android:name="com.facebook.CustomTabActivity"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
<!--
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
This activity declaration is merged with the version from the library manifest.
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
It demonstrates how an https redirect can be captured, in addition to or instead of
|
|
||||||
a custom scheme.
|
|
||||||
|
|
||||||
Generally, this should be done in conjunction with an app link declaration for Android M
|
<data android:scheme="@string/fb_login_protocol_scheme" />
|
||||||
and above, for additional security and an improved user experience. See:
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
https://developer.android.com/training/app-links/index.html
|
|
||||||
|
|
||||||
The declaration from the library can be completely replaced by adding tools:node="replace"
|
|
||||||
|
|
||||||
To the list of attributes on the activity element.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name="com.youme.voiceengine.VoiceEngineService"
|
android:name="com.youme.voiceengine.VoiceEngineService"
|
||||||
@ -203,6 +257,7 @@
|
|||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="29" />
|
android:maxSdkVersion="29" />
|
||||||
|
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||||
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
|
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
|
||||||
<queries>
|
<queries>
|
||||||
|
@ -32,6 +32,29 @@ android {
|
|||||||
versionCode 46
|
versionCode 46
|
||||||
versionName "1.0.46"
|
versionName "1.0.46"
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
if (!project.hasProperty("PROP_NDK_MODE") || PROP_NDK_MODE.compareTo('none') != 0) {
|
||||||
|
// skip the NDK Build step if PROP_NDK_MODE is none
|
||||||
|
targets 'cocos2djs'
|
||||||
|
arguments 'NDK_TOOLCHAIN_VERSION=clang'
|
||||||
|
|
||||||
|
def module_paths = [project.file(rootProject.ext.cfgs.cocos2dxBasePath),
|
||||||
|
project.file(rootProject.ext.cfgs.cocos2dxBasePath+"/cocos"),
|
||||||
|
project.file(rootProject.ext.cfgs.cocos2dxBasePath+"/external")]
|
||||||
|
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||||
|
arguments 'NDK_MODULE_PATH=' + module_paths.join(";")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
arguments 'NDK_MODULE_PATH=' + module_paths.join(':')
|
||||||
|
}
|
||||||
|
|
||||||
|
arguments '-j' + Runtime.runtime.availableProcessors()
|
||||||
|
abiFilters.addAll(PROP_APP_ABI.split(':').collect{it as String})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
'appAuthRedirectScheme': 'com.googleusercontent.apps.53206975661-asnf3qe4bg29p8h981pgf099osvrjbme'
|
'appAuthRedirectScheme': 'com.googleusercontent.apps.53206975661-asnf3qe4bg29p8h981pgf099osvrjbme'
|
||||||
]
|
]
|
||||||
@ -46,6 +69,10 @@ android {
|
|||||||
|
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
ndkBuild {
|
ndkBuild {
|
||||||
|
if (!project.hasProperty("PROP_NDK_MODE") || PROP_NDK_MODE.compareTo('none') != 0) {
|
||||||
|
// skip the NDK Build step if PROP_NDK_MODE is none
|
||||||
|
path "jni/Android.mk"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,8 +111,6 @@ android {
|
|||||||
// This flag must be enabled to see properly-symbolicated native
|
// This flag must be enabled to see properly-symbolicated native
|
||||||
// stack traces in the Crashlytics dashboard.
|
// stack traces in the Crashlytics dashboard.
|
||||||
nativeSymbolUploadEnabled true
|
nativeSymbolUploadEnabled true
|
||||||
strippedNativeLibsDir 'build/intermediates/stripped_native_libs/release/out/lib'
|
|
||||||
unstrippedNativeLibsDir 'build/intermediates/merged_native_libs/release/out/lib'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,6 +131,24 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
android.applicationVariants.all { variant ->
|
||||||
|
// delete previous files first
|
||||||
|
delete "${buildDir}/intermediates/merged_assets/${variant.dirName}"
|
||||||
|
|
||||||
|
variant.mergeAssetsProvider.get().doLast {
|
||||||
|
def sourceDir = rootProject.ext.cfgs.jsFilePath
|
||||||
|
|
||||||
|
copy{
|
||||||
|
from "${sourceDir}"
|
||||||
|
include "Data/js/**"
|
||||||
|
into outputDir
|
||||||
|
}
|
||||||
|
copy {
|
||||||
|
from "${sourceDir}/cert/cacert.pem"
|
||||||
|
into outputDir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -114,11 +157,13 @@ dependencies {
|
|||||||
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
|
||||||
implementation project(':unityLibrary')
|
implementation project(':unityLibrary')
|
||||||
implementation fileTree(dir: project(':unityLibrary').getProjectDir().toString() + ('\\libs'), include: ['*.jar'])
|
implementation fileTree(dir: project(':unityLibrary').getProjectDir().toString() + ('\\libs'), include: ['*.jar'])
|
||||||
|
implementation fileTree(dir: rootProject.ext.cfgs.cocos2dxBasePath + "/cocos/platform/android/java/libs", include: ['*.jar'])
|
||||||
|
implementation project(':libcocos2dx')
|
||||||
|
|
||||||
implementation "androidx.appcompat:appcompat:1.0.2"
|
implementation "androidx.appcompat:appcompat:1.0.2"
|
||||||
implementation "androidx.biometric:biometric:1.1.0"
|
implementation "androidx.biometric:biometric:1.1.0"
|
||||||
|
|
||||||
implementation 'com.google.android.gms:play-services-auth:21.2.0'
|
implementation 'com.google.android.gms:play-services-auth:20.3.0'
|
||||||
|
|
||||||
// implementation 'com.xm.permissions:XmPermissions:1.0.1'
|
// implementation 'com.xm.permissions:XmPermissions:1.0.1'
|
||||||
implementation 'pub.devrel:easypermissions:3.0.0'
|
implementation 'pub.devrel:easypermissions:3.0.0'
|
||||||
@ -127,7 +172,7 @@ dependencies {
|
|||||||
implementation "com.squareup.okio:okio:2.10.0"
|
implementation "com.squareup.okio:okio:2.10.0"
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
implementation 'com.bytedance.ies.ugc.aweme:opensdk-oversea-external:0.2.1.0'
|
implementation 'com.bytedance.ies.ugc.aweme:opensdk-oversea-external:0.2.1.0'
|
||||||
implementation 'com.google.android.play:core:1.10.3' //PAD资源分发
|
implementation 'com.google.android.play:core:1.10.0' //PAD资源分发
|
||||||
implementation 'com.facebook.android:facebook-core:latest.release'
|
implementation 'com.facebook.android:facebook-core:latest.release'
|
||||||
implementation 'com.facebook.android:facebook-login:latest.release'
|
implementation 'com.facebook.android:facebook-login:latest.release'
|
||||||
implementation 'com.facebook.android:facebook-share:latest.release'
|
implementation 'com.facebook.android:facebook-share:latest.release'
|
||||||
|
@ -1,16 +1,43 @@
|
|||||||
package com.cege.games.release;
|
package com.cege.games.release;
|
||||||
|
|
||||||
|
import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG;
|
||||||
|
import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||||
|
import static org.cocos2dx.lib.Cocos2dxHelper.getActivity;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.biometric.BiometricManager;
|
||||||
|
|
||||||
import com.cege.games.release.oauth.AppAuthSvr;
|
import com.bytedance.sdk.open.tiktok.TikTokOpenApiFactory;
|
||||||
|
import com.bytedance.sdk.open.tiktok.api.TikTokOpenApi;
|
||||||
|
import com.bytedance.sdk.open.tiktok.authorize.model.Authorization;
|
||||||
|
import com.bytedance.sdk.open.tiktok.base.MediaContent;
|
||||||
|
import com.bytedance.sdk.open.tiktok.base.VideoObject;
|
||||||
|
import com.bytedance.sdk.open.tiktok.share.Share;
|
||||||
|
import com.cege.games.release.activity.WebPageActivity;
|
||||||
|
import com.cege.games.release.appauth.AppAuthSvr;
|
||||||
import com.cege.games.release.oauth.OAuthUtil;
|
import com.cege.games.release.oauth.OAuthUtil;
|
||||||
import com.cege.games.release.ui.UIManager;
|
import com.cege.games.release.ui.UIManager;
|
||||||
|
import com.cege.games.release.wallet.WalletUtil;
|
||||||
|
import com.facebook.AccessToken;
|
||||||
|
import com.facebook.CallbackManager;
|
||||||
|
import com.facebook.FacebookCallback;
|
||||||
|
import com.facebook.FacebookException;
|
||||||
import com.facebook.appevents.AppEventsLogger;
|
import com.facebook.appevents.AppEventsLogger;
|
||||||
|
import com.facebook.login.LoginManager;
|
||||||
|
import com.facebook.login.LoginResult;
|
||||||
|
import com.facebook.share.model.ShareLinkContent;
|
||||||
|
import com.facebook.share.widget.ShareDialog;
|
||||||
import com.google.android.gms.auth.api.signin.GoogleSignIn;
|
import com.google.android.gms.auth.api.signin.GoogleSignIn;
|
||||||
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
|
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
|
||||||
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
|
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
|
||||||
@ -21,6 +48,7 @@ import com.google.android.gms.common.Scopes;
|
|||||||
import com.google.android.gms.common.api.ApiException;
|
import com.google.android.gms.common.api.ApiException;
|
||||||
import com.google.android.gms.common.api.Scope;
|
import com.google.android.gms.common.api.Scope;
|
||||||
import com.google.android.gms.tasks.Task;
|
import com.google.android.gms.tasks.Task;
|
||||||
|
import com.google.api.services.drive.DriveScopes;
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics;
|
import com.google.firebase.analytics.FirebaseAnalytics;
|
||||||
import com.jc.jcfw.JcSDK;
|
import com.jc.jcfw.JcSDK;
|
||||||
import com.jc.jcfw.google.PayClient;
|
import com.jc.jcfw.google.PayClient;
|
||||||
@ -29,31 +57,56 @@ import com.unity3d.player.UnityPlayerActivity;
|
|||||||
|
|
||||||
import net.openid.appauth.AuthState;
|
import net.openid.appauth.AuthState;
|
||||||
|
|
||||||
|
import org.cocos2dx.lib.Cocos2dxHelper;
|
||||||
|
import org.cocos2dx.lib.CocosJSHelper;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
|
||||||
public class MainActivity extends UnityPlayerActivity {
|
public class MainActivity extends UnityPlayerActivity
|
||||||
|
implements Cocos2dxHelper.Cocos2dxHelperListener {
|
||||||
private static final String TAG = MainActivity.class.getSimpleName();
|
private static final String TAG = MainActivity.class.getSimpleName();
|
||||||
|
|
||||||
public static MainActivity app;
|
public static MainActivity app;
|
||||||
|
|
||||||
// AppAuth
|
// AppAuth
|
||||||
private static final int RC_AUTH = 0X04;
|
private static final int RC_AUTH = 0X04;
|
||||||
// google sign
|
// google sign
|
||||||
private static final int RC_SIGN_IN = 0X05;
|
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 FILE_SELECTOR_CODE = 0X014;
|
||||||
|
private String title;
|
||||||
private String mFunID;
|
private String mFunID;
|
||||||
|
|
||||||
private FirebaseAnalytics mFirebaseAnalytics;
|
|
||||||
private AppEventsLogger fbLogger;
|
|
||||||
private OAuthUtil mOAuthUtil;
|
|
||||||
|
|
||||||
// AppAuth
|
// AppAuth
|
||||||
private AppAuthSvr mAppAuthSvr;
|
private AppAuthSvr mAppAuthSvr;
|
||||||
private ExecutorService mExecutor;
|
private ExecutorService mExecutor;
|
||||||
|
|
||||||
|
|
||||||
|
private TikTokOpenApi tiktokOpenApi;
|
||||||
|
|
||||||
|
public String getFunId() {
|
||||||
|
return mFunID;
|
||||||
|
}
|
||||||
|
|
||||||
private GoogleSignInClient mGoogleSignInClient;
|
private GoogleSignInClient mGoogleSignInClient;
|
||||||
|
// facebook login
|
||||||
|
private CallbackManager mCallbackManager;
|
||||||
|
|
||||||
|
private FirebaseAnalytics mFirebaseAnalytics;
|
||||||
|
private AppEventsLogger fbLogger;
|
||||||
|
private WalletUtil mWalletUtil;
|
||||||
|
private OAuthUtil mOAuthUtil;
|
||||||
|
|
||||||
public boolean isGooglePlayServicesAvailable() {
|
public boolean isGooglePlayServicesAvailable() {
|
||||||
return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS;
|
return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS;
|
||||||
@ -67,26 +120,59 @@ public class MainActivity extends UnityPlayerActivity {
|
|||||||
// Obtain the FirebaseAnalytics instance.
|
// Obtain the FirebaseAnalytics instance.
|
||||||
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
|
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
|
||||||
|
|
||||||
|
onLoadNativeLibraries();
|
||||||
app = this;
|
app = this;
|
||||||
|
Cocos2dxHelper.init(this);
|
||||||
|
CocosJSHelper.initJSEnv(getApplicationContext());
|
||||||
|
|
||||||
|
// begin of google sign
|
||||||
|
// mGoogleSignInClient = initGsiClient();
|
||||||
|
// end of google sign
|
||||||
|
|
||||||
// begin of google oauth sign
|
// begin of google oauth sign
|
||||||
mAppAuthSvr = new AppAuthSvr(this);
|
mAppAuthSvr = new AppAuthSvr(this);
|
||||||
mExecutor = Executors.newSingleThreadExecutor();
|
mExecutor = Executors.newSingleThreadExecutor();
|
||||||
mAppAuthSvr.init(mExecutor);
|
mAppAuthSvr.init(mExecutor);
|
||||||
|
// end of google oauth sign
|
||||||
|
|
||||||
|
// begin of facebook login
|
||||||
|
initFacebookSDK();
|
||||||
|
// end of facebook login
|
||||||
|
tiktokOpenApi = TikTokOpenApiFactory.create(this);
|
||||||
|
|
||||||
PayClient payClient = PayClient.getInstance();
|
PayClient payClient = PayClient.getInstance();
|
||||||
payClient.init(this);
|
payClient.init(this);
|
||||||
|
mWalletUtil = new WalletUtil(this);
|
||||||
fbLogger = AppEventsLogger.newLogger(this);
|
// JSTimers timer = new JSTimers(Looper.getMainLooper());
|
||||||
|
// timer.sendEmptyMessage(JSTimers.JS_TICK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override protected void onResume(){
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
String[] paramArr = new String[0];
|
||||||
|
JcSDK.callNativeJS("", "onGameResume", paramArr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class JSTimers extends Handler {
|
||||||
|
public static final int JS_TICK = 0;
|
||||||
|
|
||||||
|
public JSTimers(@NonNull Looper looper) {
|
||||||
|
super(looper);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
if (msg.what == JS_TICK) {
|
||||||
|
JcSDK.tick(0.033f);
|
||||||
|
sendEmptyMessageDelayed(JS_TICK, 33);
|
||||||
|
} else {
|
||||||
|
removeMessages(JS_TICK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
mCallbackManager.onActivityResult(requestCode, resultCode, data);
|
||||||
UIManager.getSingleton().onActivityResult(this, requestCode, resultCode, data);
|
UIManager.getSingleton().onActivityResult(this, requestCode, resultCode, data);
|
||||||
if (resultCode == RESULT_OK && data != null) {
|
if (resultCode == RESULT_OK && data != null) {
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
@ -96,8 +182,20 @@ public class MainActivity extends UnityPlayerActivity {
|
|||||||
case RC_SIGN_IN:
|
case RC_SIGN_IN:
|
||||||
handleSignInResult(GoogleSignIn.getSignedInAccountFromIntent(data));
|
handleSignInResult(GoogleSignIn.getSignedInAccountFromIntent(data));
|
||||||
break;
|
break;
|
||||||
|
case FILE_SELECTOR_CODE:
|
||||||
|
shareToTikTok(mFunID, data.getData());
|
||||||
|
break;
|
||||||
|
case RC_REQUEST_DRIVE_TO_UPLOAD:
|
||||||
|
mExecutor.submit(() -> mWalletUtil.uploadCfgWithGPS(_result -> {}));
|
||||||
|
break;
|
||||||
|
case RC_REQUEST_DRIVE_TO_READ:
|
||||||
|
mExecutor.submit(() -> mWalletUtil.downloadCfgWithGPS(_file -> mWalletUtil.getPassLocal()));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (requestCode == RC_REQUEST_DRIVE_TO_UPLOAD || requestCode == RC_REQUEST_DRIVE_TO_READ) {
|
||||||
|
mWalletUtil.errorCB("activity result with code: " + resultCode);
|
||||||
|
}
|
||||||
if (requestCode == RC_SIGN_IN) {
|
if (requestCode == RC_SIGN_IN) {
|
||||||
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
|
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
|
||||||
handleSignInResult(task);
|
handleSignInResult(task);
|
||||||
@ -111,8 +209,41 @@ public class MainActivity extends UnityPlayerActivity {
|
|||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
UIManager.getSingleton().onStartActivity(this);
|
UIManager.getSingleton().onStartActivity(this);
|
||||||
|
if (mExecutor.isShutdown()) {
|
||||||
|
mExecutor = Executors.newSingleThreadExecutor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// begin for unity
|
||||||
|
|
||||||
|
protected void onLoadNativeLibraries() {
|
||||||
|
try {
|
||||||
|
ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
|
||||||
|
Bundle bundle = ai.metaData;
|
||||||
|
String libName = bundle.getString("android.app.lib_name");
|
||||||
|
System.loadLibrary(libName);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showDialog(String pTitle, String pMessage) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runOnGLThread(Runnable pRunnable) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private GoogleSignInClient initGsiClient() {
|
||||||
|
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||||
|
.requestScopes(new Scope(Scopes.EMAIL))
|
||||||
|
.requestIdToken(getString(R.string.default_web_client_id1))
|
||||||
|
.build();
|
||||||
|
return GoogleSignIn.getClient(this, gso);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
@ -122,28 +253,6 @@ public class MainActivity extends UnityPlayerActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void logEvent(String content) {
|
|
||||||
try {
|
|
||||||
Bundle bundle = JsonUtils.convertJsonToBundle(content);
|
|
||||||
String eventName = bundle.getString("name", "custom_event");
|
|
||||||
mFirebaseAnalytics.logEvent(eventName, bundle);
|
|
||||||
fbLogger.logEvent(eventName, bundle);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(TAG, "log event JSONException: " + e.getMessage());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "log event Exception: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// begin google sign in
|
|
||||||
private GoogleSignInClient initGsiClient() {
|
|
||||||
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
|
||||||
.requestScopes(new Scope(Scopes.EMAIL))
|
|
||||||
.requestIdToken(getString(R.string.default_web_client_id1))
|
|
||||||
.build();
|
|
||||||
return GoogleSignIn.getClient(this, gso);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void signWithGoogle(String funId) {
|
public void signWithGoogle(String funId) {
|
||||||
this.mFunID = funId;
|
this.mFunID = funId;
|
||||||
if (isGooglePlayServicesAvailable()) {
|
if (isGooglePlayServicesAvailable()) {
|
||||||
@ -203,7 +312,83 @@ public class MainActivity extends UnityPlayerActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// general oauth login
|
|
||||||
|
// sign with tiktok
|
||||||
|
public void signWithTiktok(String funId) {
|
||||||
|
this.mFunID = funId;
|
||||||
|
Log.i(TAG, "login with tiktok: " + funId);
|
||||||
|
// STEP 1: Create an instance of TiktokOpenApi
|
||||||
|
|
||||||
|
// STEP 2: Create an instance of Authorization.Request and set parameters
|
||||||
|
Authorization.Request request = new Authorization.Request();
|
||||||
|
request.scope = "user.info.basic,video.list";
|
||||||
|
request.state = funId;
|
||||||
|
tiktokOpenApi.authorize(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// begin of facebook login
|
||||||
|
private void initFacebookSDK() {
|
||||||
|
mCallbackManager = CallbackManager.Factory.create();
|
||||||
|
fbLogger = AppEventsLogger.newLogger(this);
|
||||||
|
LoginManager.getInstance().registerCallback(mCallbackManager,
|
||||||
|
new FacebookCallback<LoginResult>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(LoginResult loginResult) {
|
||||||
|
AccessToken accessToken = AccessToken.getCurrentAccessToken();
|
||||||
|
Log.d(TAG, "Login Success:: accessToken: " + accessToken.getToken());
|
||||||
|
if (!verifyFbAccessToken(accessToken)) {
|
||||||
|
JcSDK.nativeCb(MainActivity.app.mFunID, "access token expired", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel() {
|
||||||
|
Log.d(TAG, "Login cancel");
|
||||||
|
JcSDK.nativeCb(MainActivity.app.mFunID, "user login cancel", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(FacebookException exception) {
|
||||||
|
Log.i(TAG, "Login error: " + exception.getMessage());
|
||||||
|
JcSDK.nativeCb(MainActivity.app.mFunID, exception.getMessage(), null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void signWithFacebook(String funId) {
|
||||||
|
Log.i(TAG, "login with facebook: " + funId);
|
||||||
|
this.mFunID = funId;
|
||||||
|
AccessToken accessToken = AccessToken.getCurrentAccessToken();
|
||||||
|
if (!verifyFbAccessToken(accessToken)) {
|
||||||
|
LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile", "email"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shareWithFacebook(String content) {
|
||||||
|
ShareLinkContent linkContent = new ShareLinkContent.Builder()
|
||||||
|
.setContentUrl(Uri.parse("https://www.google.com"))
|
||||||
|
.setQuote(content)
|
||||||
|
.build();
|
||||||
|
ShareDialog.show(this, linkContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean verifyFbAccessToken(AccessToken accessToken) {
|
||||||
|
boolean isLoggedIn = accessToken != null && !accessToken.isExpired();
|
||||||
|
if (isLoggedIn) {
|
||||||
|
JcSDK.nativeCb(this.mFunID, null, accessToken.getToken());
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// end of facebook login
|
||||||
|
|
||||||
|
public void signWithTwitter(String funId) {
|
||||||
|
Log.i(TAG, "login with twitter: " + funId);
|
||||||
|
this.mFunID = funId;
|
||||||
|
}
|
||||||
|
|
||||||
public void oauthLogin(String funId, String jsonData) {
|
public void oauthLogin(String funId, String jsonData) {
|
||||||
if (this.mOAuthUtil == null) {
|
if (this.mOAuthUtil == null) {
|
||||||
this.mOAuthUtil = new OAuthUtil(this);
|
this.mOAuthUtil = new OAuthUtil(this);
|
||||||
@ -215,4 +400,178 @@ public class MainActivity extends UnityPlayerActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void logEvent(String content) {
|
||||||
|
try {
|
||||||
|
Bundle bundle = JsonUtils.convertJsonToBundle(content);
|
||||||
|
String eventName = bundle.getString("name", "custom_event");
|
||||||
|
mFirebaseAnalytics.logEvent(eventName, bundle);
|
||||||
|
fbLogger.logEvent(eventName, bundle);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "log event JSONException: " + e.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "log event Exception: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showPage(String fid, final String url) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
Intent intent = new Intent(this, WebPageActivity.class);
|
||||||
|
intent.putExtra("url", url);
|
||||||
|
startActivity(intent);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shareToTikTok(String funId, Uri uriToImage) {
|
||||||
|
this.mFunID = funId;
|
||||||
|
grantUriPermission("com.zhiliaoapp.musically",
|
||||||
|
uriToImage, Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
grantUriPermission("com.ss.android.ugc.trill",
|
||||||
|
uriToImage, Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
Log.i(TAG, "share to tiktok: " + uriToImage.toString());
|
||||||
|
if (tiktokOpenApi.isShareSupportFileProvider()) {
|
||||||
|
Share.Request request = new Share.Request();
|
||||||
|
ArrayList<String> mUri = new ArrayList<>();
|
||||||
|
mUri.add(uriToImage.toString());
|
||||||
|
VideoObject videoObject = new VideoObject();
|
||||||
|
videoObject.mVideoPaths = mUri;
|
||||||
|
MediaContent content = new MediaContent();
|
||||||
|
content.mMediaObject = videoObject;
|
||||||
|
|
||||||
|
// 3.set required parameters
|
||||||
|
request.mMediaContent = content;
|
||||||
|
request.mState = funId;
|
||||||
|
request.mShareFormat = Share.Format.DEFAULT;
|
||||||
|
tiktokOpenApi.share(request);
|
||||||
|
}
|
||||||
|
// share with Android ShareSheet
|
||||||
|
// runOnUiThread(() -> {
|
||||||
|
// Log.i(TAG, "share to tiktok: " + uriToImage);
|
||||||
|
// Intent shareIntent = new Intent();
|
||||||
|
// shareIntent.setAction(Intent.ACTION_SEND);
|
||||||
|
// shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
|
||||||
|
// shareIntent.setType("video/*");
|
||||||
|
// startActivity(Intent.createChooser(shareIntent, "share"));
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
private void openFileSelector() {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||||
|
intent.setType("video/*");
|
||||||
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
startActivityForResult(intent, FILE_SELECTOR_CODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void passStorageState(String funID, String account) {
|
||||||
|
Log.i(TAG, "passStorageState with: " + account);
|
||||||
|
int touchIDState = BiometricManager.from(this)
|
||||||
|
.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS ? 1 : 0;
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
try {
|
||||||
|
result.put("biometrics", touchIDState);
|
||||||
|
JcSDK.nativeCb(funID, null, result.toString());
|
||||||
|
} catch (JSONException e) {
|
||||||
|
JcSDK.nativeCb(funID, "JSON error", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loginAndRequestDrivePermission(int requestCode) {
|
||||||
|
Log.i(TAG, "no drive permission");
|
||||||
|
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, String.format("storagePass with: %s | %s", funID, account));
|
||||||
|
this.mFunID = funID;
|
||||||
|
mWalletUtil.updateParams(funID, account);
|
||||||
|
mWalletUtil.savePassToLocal(password, _file -> {
|
||||||
|
if (isGooglePlayServicesAvailable()) {
|
||||||
|
if (!GoogleSignIn.hasPermissions(
|
||||||
|
GoogleSignIn.getLastSignedInAccount(getActivity()),
|
||||||
|
new Scope(DriveScopes.DRIVE_APPDATA))) {
|
||||||
|
loginAndRequestDrivePermission(RC_REQUEST_DRIVE_TO_UPLOAD);
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "had drive permission");
|
||||||
|
mWalletUtil.uploadCfgWithGPS(_result -> {});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
AuthState state = mAppAuthSvr.getCurrentState();
|
||||||
|
if (state.isAuthorized()) {
|
||||||
|
if (state.getNeedsTokenRefresh()) {
|
||||||
|
Log.d(TAG, "need refresh accessToken");
|
||||||
|
mAppAuthSvr.refreshToken(funID, _result -> mWalletUtil.uploadCfgWithApi(state.getAccessToken(), _r->{}));
|
||||||
|
} else {
|
||||||
|
mWalletUtil.uploadCfgWithApi(state.getAccessToken(), _r->{});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "not login");
|
||||||
|
mExecutor.submit(() -> mAppAuthSvr.doAuth(funID, _result -> mWalletUtil.uploadCfgWithApi(state.getAccessToken(), _r->{})));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// runOnUiThread(() -> {
|
||||||
|
// Intent intent = new Intent(this, BiometricActivity.class);
|
||||||
|
// intent.putExtra("action", "encrypt");
|
||||||
|
// intent.putExtra("funID", funId);
|
||||||
|
// intent.putExtra("account", account);
|
||||||
|
// intent.putExtra("password", password);
|
||||||
|
// startActivity(intent);
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
public void authGetStoragePass(String funID, String account) {
|
||||||
|
Log.i(TAG, "authGetStoragePass with: " + account);
|
||||||
|
this.mFunID = funID;
|
||||||
|
mWalletUtil.updateParams(funID, account);
|
||||||
|
if (isGooglePlayServicesAvailable()) {
|
||||||
|
if (!mWalletUtil.localCfgExists(account)) {
|
||||||
|
if (!GoogleSignIn.hasPermissions(
|
||||||
|
GoogleSignIn.getLastSignedInAccount(getActivity()),
|
||||||
|
new Scope(DriveScopes.DRIVE_APPDATA))) {
|
||||||
|
loginAndRequestDrivePermission(RC_REQUEST_DRIVE_TO_READ);
|
||||||
|
} else {
|
||||||
|
mWalletUtil.downloadCfgWithGPS(_file -> mWalletUtil.getPassLocal());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mWalletUtil.getPassLocal();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!mWalletUtil.localCfgExists(account)) {
|
||||||
|
AuthState state = mAppAuthSvr.getCurrentState();
|
||||||
|
// 1. check whether the google account has been logged in, this situation occurs when non-google login
|
||||||
|
// 2. check if already had permission of drive appdata, add permission of drive appdata to auth_config
|
||||||
|
// 3. check if need refresh access token
|
||||||
|
if (state.isAuthorized()) {
|
||||||
|
if (state.getNeedsTokenRefresh()) {
|
||||||
|
Log.d(TAG, "need refresh accessToken");
|
||||||
|
mAppAuthSvr.refreshToken(funID, _result -> mWalletUtil.downloadCfgWithApi(state.getAccessToken(), _file -> mWalletUtil.getPassLocal()));
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "access token no need refresh");
|
||||||
|
mWalletUtil.downloadCfgWithApi(state.getAccessToken(), _file -> mWalletUtil.getPassLocal());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "not login");
|
||||||
|
mExecutor.submit(() -> mAppAuthSvr.doAuth(funID, _result -> mWalletUtil.downloadCfgWithApi(state.getAccessToken(), _file -> mWalletUtil.getPassLocal())));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mWalletUtil.getPassLocal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// runOnUiThread(() -> {
|
||||||
|
// Intent intent = new Intent(this, BiometricActivity.class);
|
||||||
|
// intent.putExtra("action", "decrypt");
|
||||||
|
// intent.putExtra("funID", funId);
|
||||||
|
// intent.putExtra("account", account);
|
||||||
|
// startActivity(intent);
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getClientId(String funID) {
|
||||||
|
Log.i(TAG, "getClientId ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,96 @@
|
|||||||
|
package com.cege.games.release.activity;
|
||||||
|
|
||||||
|
import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG;
|
||||||
|
import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
||||||
|
import static androidx.biometric.BiometricPrompt.ERROR_USER_CANCELED;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.security.keystore.KeyInfo;
|
||||||
|
import android.util.Base64;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.biometric.BiometricManager;
|
||||||
|
import androidx.biometric.BiometricPrompt;
|
||||||
|
|
||||||
|
import com.cege.games.release.R;
|
||||||
|
import com.jc.jcfw.security.BiometricHelper;
|
||||||
|
import com.jc.jcfw.security.CryptographyManager;
|
||||||
|
import com.jc.jcfw.security.CryptographyManagerImpl;
|
||||||
|
import com.jc.jcfw.security.EncryptedData;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
|
||||||
|
public class BiometricActivity extends AppCompatActivity {
|
||||||
|
private static final String TAG = BiometricActivity.class.getSimpleName();
|
||||||
|
private BiometricPrompt.PromptInfo promptInfo;
|
||||||
|
private CryptographyManager cryptographyManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_biometric);
|
||||||
|
Log.i(TAG, "onCreate: " + getIntent().getDataString());
|
||||||
|
promptInfo = BiometricHelper.createPromptInfo(this);
|
||||||
|
cryptographyManager = new CryptographyManagerImpl();
|
||||||
|
Intent intent = getIntent();
|
||||||
|
String action = intent.getStringExtra("action");
|
||||||
|
String funId = intent.getStringExtra("funid");
|
||||||
|
String account = intent.getStringExtra("account");
|
||||||
|
// check if action is exists
|
||||||
|
if ("encrypt".equals(action)) {
|
||||||
|
String password = intent.getStringExtra("password");
|
||||||
|
authenticateToEncrypt(funId, password);
|
||||||
|
} else if ("decrypt".equals(action)) {
|
||||||
|
String iv = intent.getStringExtra("iv");
|
||||||
|
authenticateToDecrypt(account, iv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void authenticateToEncrypt(String funId, String text) {
|
||||||
|
if (BiometricManager.from(this)
|
||||||
|
.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS) {
|
||||||
|
Cipher cipher = cryptographyManager.getInitializedCipherForEncryption("cebg_wallet_key");
|
||||||
|
BiometricPrompt biometricPrompt = BiometricHelper.createBiometricPrompt(this, _result -> {
|
||||||
|
if (_result.isError()) {
|
||||||
|
if (_result.getErrcode() == ERROR_USER_CANCELED) {
|
||||||
|
// close current activity
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EncryptedData encryptedData = cryptographyManager.encryptData(text, _result.getCipher());
|
||||||
|
String encryptedString = Base64.encodeToString(encryptedData.getCiphertext(), Base64.DEFAULT);
|
||||||
|
String ivString = Base64.encodeToString(encryptedData.getInitializationVector(), Base64.DEFAULT);
|
||||||
|
Log.i(TAG, "encrypted msg: " + encryptedString);
|
||||||
|
Log.i(TAG, "encrypted iv: " + ivString);
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
biometricPrompt.authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void authenticateToDecrypt(String text, String iv) {
|
||||||
|
if (BiometricManager.from(this)
|
||||||
|
.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS) {
|
||||||
|
byte[] ivData = Base64.decode(iv, Base64.DEFAULT);
|
||||||
|
byte[] textData = Base64.decode(text, Base64.DEFAULT);
|
||||||
|
Cipher cipher = cryptographyManager.getInitializedCipherForDecryption("cebg_wallet_key", ivData);
|
||||||
|
BiometricPrompt biometricPrompt = BiometricHelper.createBiometricPrompt(this, _result -> {
|
||||||
|
if (_result.isError()) {
|
||||||
|
if (_result.getErrcode() == ERROR_USER_CANCELED) {
|
||||||
|
// close current activity
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String decryptedMsg = cryptographyManager.decryptData(textData, _result.getCipher());
|
||||||
|
Log.i(TAG, "decrypted msg: " + decryptedMsg);
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
biometricPrompt.authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
244
app/src/com/cege/games/release/activity/WebPageActivity.java
Normal file
244
app/src/com/cege/games/release/activity/WebPageActivity.java
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
package com.cege.games.release.activity;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.webkit.ConsoleMessage;
|
||||||
|
import android.webkit.CookieManager;
|
||||||
|
import android.webkit.WebChromeClient;
|
||||||
|
import android.webkit.WebResourceError;
|
||||||
|
import android.webkit.WebResourceRequest;
|
||||||
|
import android.webkit.WebResourceResponse;
|
||||||
|
import android.webkit.WebSettings;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
import android.webkit.WebViewClient;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.cege.games.release.MainApplication;
|
||||||
|
import com.cege.games.release.R;
|
||||||
|
import com.cege.games.release.ui.UIManager;
|
||||||
|
import com.cege.games.release.webpage.events.CallJSEvent;
|
||||||
|
import com.cege.games.release.webpage.events.ProxyCBEvent;
|
||||||
|
import com.cege.games.release.webpage.events.WebPageEvent;
|
||||||
|
import com.cege.games.release.webpage.WalletInterface;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.jc.jcfw.JcSDK;
|
||||||
|
import com.jc.jcfw.util.UIUtils;
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
|
import org.greenrobot.eventbus.ThreadMode;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
|
||||||
|
public class WebPageActivity extends Activity {
|
||||||
|
private WebView mWebView;
|
||||||
|
private final String FUNID_PREFIX = "webpage_";
|
||||||
|
private final Map<String, Consumer<JSONObject>> actionMap = Maps.newHashMap();
|
||||||
|
private static final String TAG = WebPageActivity.class.getSimpleName();
|
||||||
|
|
||||||
|
@SuppressLint({ "SetJavaScriptEnabled", "DefaultLocale" })
|
||||||
|
@Override
|
||||||
|
protected void onCreate(android.os.Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
resistActions();
|
||||||
|
setContentView(R.layout.activity_web_page);
|
||||||
|
WebView.setWebContentsDebuggingEnabled(true);
|
||||||
|
mWebView = findViewById(R.id.web_view);
|
||||||
|
WebSettings webSettings = mWebView.getSettings();
|
||||||
|
webSettings.setJavaScriptEnabled(true);
|
||||||
|
webSettings.setDomStorageEnabled(true);
|
||||||
|
webSettings.setDatabaseEnabled(true);
|
||||||
|
webSettings.setAllowContentAccess(true);
|
||||||
|
webSettings.setAppCacheEnabled(true);
|
||||||
|
webSettings.setBuiltInZoomControls(true);
|
||||||
|
webSettings.setUseWideViewPort(true);
|
||||||
|
webSettings.setLoadWithOverviewMode(true);
|
||||||
|
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
|
||||||
|
// custom user agent
|
||||||
|
webSettings.setUserAgentString(webSettings.getUserAgentString() + " android_game_web");
|
||||||
|
CookieManager.getInstance().setAcceptThirdPartyCookies(mWebView, true);
|
||||||
|
// get url from intent
|
||||||
|
Intent intent = getIntent();
|
||||||
|
String url = intent.getStringExtra("url");
|
||||||
|
// show web view
|
||||||
|
mWebView.loadUrl(url);
|
||||||
|
mWebView.addJavascriptInterface(new WalletInterface(this), "cfwallet_JuEd8Ql5over8kneww");
|
||||||
|
mWebView.setWebChromeClient(new WebChromeClient() {
|
||||||
|
@Override
|
||||||
|
public void onReceivedTitle(WebView view, String title) {
|
||||||
|
super.onReceivedTitle(view, title);
|
||||||
|
Log.i(TAG, "onReceivedTitle: " + title);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
|
||||||
|
Log.e(TAG, consoleMessage.message());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
mWebView.setWebViewClient(new WebViewClient() {
|
||||||
|
@Override
|
||||||
|
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
||||||
|
return super.shouldOverrideUrlLoading(view, request);
|
||||||
|
// if ("www.example.com".equals(request.getUrl().getHost())) {
|
||||||
|
// // This is my website, so do not override; let my WebView load the page
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
||||||
|
super.onPageStarted(view, url, favicon);
|
||||||
|
Log.i(TAG, "onPageStarted: " + url);
|
||||||
|
String gameData = MainApplication.application.getGameData();
|
||||||
|
String jsCode = String.format("window.platform='android_game_web'; window.gameData='%s';", gameData);
|
||||||
|
callPageJS(jsCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageFinished(WebView view, String url) {
|
||||||
|
super.onPageFinished(view, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadResource(WebView view, String url) {
|
||||||
|
Log.i(TAG, "onLoadResource: " + url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
|
||||||
|
super.onReceivedError(view, request, error);
|
||||||
|
Log.e(TAG, "onReceivedError: " + error);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
|
||||||
|
super.onReceivedHttpError(view, request, errorResponse);
|
||||||
|
Log.e(TAG, "onReceivedHttpError: " + errorResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceivedSslError(WebView view, android.webkit.SslErrorHandler handler,
|
||||||
|
android.net.http.SslError error) {
|
||||||
|
Log.e(TAG, "onReceivedSslError: " + error.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
EventBus.getDefault().register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
UIManager.getSingleton().onStartActivity(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
EventBus.getDefault().unregister(this);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void asyncThread(Runnable runnable) {
|
||||||
|
new Thread(runnable).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resistActions() {
|
||||||
|
actionMap.put("closepage", _data -> {
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
actionMap.put("proxyMethod", _data -> {
|
||||||
|
try {
|
||||||
|
String funId = FUNID_PREFIX + _data.getString("funid");
|
||||||
|
String methodName = _data.getString("methodname");
|
||||||
|
JSONArray params = _data.getJSONArray("params");
|
||||||
|
String[] paramArr = new String[params.length()];
|
||||||
|
for (int i = 0; i < params.length(); i++) {
|
||||||
|
paramArr[i] = params.getString(i);
|
||||||
|
}
|
||||||
|
JcSDK.callNativeJS(funId, methodName, paramArr);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
actionMap.put("scanQRCode", _data -> {
|
||||||
|
try {
|
||||||
|
String funId = FUNID_PREFIX + _data.getString("funid");
|
||||||
|
String title = _data.getString("title");
|
||||||
|
UIManager.getSingleton().showQRScan(funId, title);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
actionMap.put("showQRCode", _data -> {
|
||||||
|
try {
|
||||||
|
String funId = FUNID_PREFIX + _data.getString("funid");
|
||||||
|
String title = _data.getString("title");
|
||||||
|
UIUtils.showQRCode(this, title, "");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
UIManager.getSingleton().onActivityResult(this, requestCode, resultCode, data);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
// Forward results to EasyPermissions
|
||||||
|
UIManager.getSingleton().onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
}
|
||||||
|
public void callPageJS(String javascript) {
|
||||||
|
mWebView.evaluateJavascript(javascript, s -> {
|
||||||
|
Log.i("PAGE", s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
public void onPageEvent(WebPageEvent event) {
|
||||||
|
Log.i(TAG, "on page event: " + event.getDataStr());
|
||||||
|
try {
|
||||||
|
JSONObject data = new JSONObject(event.getDataStr());
|
||||||
|
String action = data.getString("action");
|
||||||
|
// JSONArray params = data.getJSONArray("params");
|
||||||
|
if (actionMap.containsKey(action)) {
|
||||||
|
actionMap.get(action).accept(data);
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, String.format("unknown action: %s, data: %s", action, event.getDataStr()));
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
public void onCallJSEvent(CallJSEvent event) {
|
||||||
|
String funId = event.getFunId();
|
||||||
|
if (funId.indexOf(FUNID_PREFIX) == 0) {
|
||||||
|
funId = funId.replace(FUNID_PREFIX, "");
|
||||||
|
}
|
||||||
|
callPageJS("nativeCall('" + funId + "', '" + event.getData() + "');");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
public void onProxyCBEvent(ProxyCBEvent event) {
|
||||||
|
String funId = event.getFunId();
|
||||||
|
if (funId.indexOf(FUNID_PREFIX) == 0) {
|
||||||
|
funId = funId.replace(FUNID_PREFIX, "");
|
||||||
|
}
|
||||||
|
callPageJS("proxyCallback('" + funId + "', '" + event.getData() + "');");
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.cege.games.release.oauth;
|
package com.cege.games.release.appauth;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -391,4 +391,3 @@ public class AppAuthSvr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.cege.games.release.tiktokapi;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.bytedance.sdk.open.tiktok.CommonConstants;
|
||||||
|
import com.bytedance.sdk.open.tiktok.TikTokOpenApiFactory;
|
||||||
|
import com.bytedance.sdk.open.tiktok.api.TikTokOpenApi;
|
||||||
|
import com.bytedance.sdk.open.tiktok.authorize.model.Authorization;
|
||||||
|
import com.bytedance.sdk.open.tiktok.common.handler.IApiEventHandler;
|
||||||
|
import com.bytedance.sdk.open.tiktok.common.model.BaseReq;
|
||||||
|
import com.bytedance.sdk.open.tiktok.common.model.BaseResp;
|
||||||
|
import com.bytedance.sdk.open.tiktok.share.Share;
|
||||||
|
import com.jc.jcfw.JcSDK;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
public class TikTokEntryActivity extends Activity implements IApiEventHandler {
|
||||||
|
private static final String TAG = TikTokEntryActivity.class.getSimpleName();
|
||||||
|
TikTokOpenApi ttOpenApi;
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
ttOpenApi= TikTokOpenApiFactory.create(this);
|
||||||
|
ttOpenApi.handleIntent(getIntent(),this); // receive and parse callback
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onReq(BaseReq req) {
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onResp(BaseResp resp) {
|
||||||
|
if (resp instanceof Authorization.Response) {
|
||||||
|
Authorization.Response response = (Authorization.Response) resp;
|
||||||
|
// Log.i(TAG, "errorCode: " + response.errorCode);
|
||||||
|
// Log.i(TAG, "errorMsg: " + response.errorMsg);
|
||||||
|
// Log.i(TAG, "authCode: " + response.authCode);
|
||||||
|
// Log.i(TAG, "state: " + response.state);
|
||||||
|
// Log.i(TAG, "grantedPermissions: " + response.grantedPermissions);
|
||||||
|
if (response.errorCode == 0) {
|
||||||
|
JcSDK.nativeCb(response.state, null, response.authCode);
|
||||||
|
} else {
|
||||||
|
JcSDK.nativeCb(response.state, response.errorMsg, null);
|
||||||
|
}
|
||||||
|
finish();
|
||||||
|
} else if (resp.getType() == CommonConstants.ModeType.SHARE_CONTENT_TO_TT_RESP) {
|
||||||
|
Share.Response response = (Share.Response) resp;
|
||||||
|
Log.i(TAG, "share result code:" + response.errorCode + " errorMessage:" + response.errorMsg);
|
||||||
|
if (response.errorCode == 0) {
|
||||||
|
JcSDK.nativeCb(response.state, null, "1");
|
||||||
|
} else {
|
||||||
|
JcSDK.nativeCb(response.state, response.errorMsg, null);
|
||||||
|
}
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onErrorIntent(@Nullable Intent intent) {
|
||||||
|
JcSDK.nativeCb(null, "error intent", null);
|
||||||
|
}
|
||||||
|
}
|
222
app/src/com/cege/games/release/wallet/WalletUtil.java
Normal file
222
app/src/com/cege/games/release/wallet/WalletUtil.java
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
package com.cege.games.release.wallet;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
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.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.util.DriveUtils;
|
||||||
|
import com.jc.jcfw.util.DriverApiUtils;
|
||||||
|
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 final Context mContext;
|
||||||
|
|
||||||
|
private String funID;
|
||||||
|
private String account;
|
||||||
|
public WalletUtil(Context context) {
|
||||||
|
this.mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String TAG = getClass().getSimpleName();
|
||||||
|
|
||||||
|
public void updateParams(String funID, String account) {
|
||||||
|
this.funID = funID;
|
||||||
|
this.account = account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearParams() {
|
||||||
|
this.funID = null;
|
||||||
|
this.account = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccount() {
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void errorCB(String msg) {
|
||||||
|
JcSDK.nativeCb(funID, msg, null);
|
||||||
|
clearParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void successCB(String dataStr) {
|
||||||
|
JcSDK.nativeCb(funID, null, dataStr);
|
||||||
|
clearParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String generateFileName(String account) {
|
||||||
|
return String.format("wallet_%s.json", account);
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getWalletCfgFile(String account) {
|
||||||
|
String filename = generateFileName(account);
|
||||||
|
File dic = new File(mContext.getFilesDir() + "/wallets");
|
||||||
|
if (!dic.exists()) {
|
||||||
|
dic.mkdir();
|
||||||
|
}
|
||||||
|
return new File(mContext.getFilesDir() + "/wallets", filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void savePassToLocal(String pass, Consumer<File> func) {
|
||||||
|
File filePath = getWalletCfgFile(account);
|
||||||
|
JSONObject content = new JSONObject();
|
||||||
|
try {
|
||||||
|
content.put("pass", pass);
|
||||||
|
FileUtils.writeFile(filePath, content.toString());
|
||||||
|
func.accept(filePath);
|
||||||
|
} catch (JSONException | IOException e) {
|
||||||
|
errorCB(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getPassLocal() {
|
||||||
|
try {
|
||||||
|
JSONObject json = loadLocalCfg(account);
|
||||||
|
String passEncrypted = json.getString("pass");
|
||||||
|
String passDecrypted = JcSDK.decryptPass(account, passEncrypted);
|
||||||
|
successCB(passDecrypted);
|
||||||
|
} catch (JSONException | IOException e) {
|
||||||
|
errorCB(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean localCfgExists(String account) {
|
||||||
|
File filePath = getWalletCfgFile(account);
|
||||||
|
return filePath.exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject loadLocalCfg(String account) throws JSONException, IOException {
|
||||||
|
File filePath = getWalletCfgFile(account);
|
||||||
|
if (!filePath.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return FileUtils.readJsonFromFile(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void uploadCfgWithGPS(Consumer<NativeResult> func) {
|
||||||
|
GoogleSignInAccount ga = GoogleSignIn.getLastSignedInAccount(mContext);
|
||||||
|
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(mContext,
|
||||||
|
Collections.singletonList(DriveScopes.DRIVE_APPDATA));
|
||||||
|
credential.setSelectedAccount(ga.getAccount());
|
||||||
|
Drive service = DriveUtils.generateService(credential, mContext.getString(R.string.app_name));
|
||||||
|
try {
|
||||||
|
File file = getWalletCfgFile(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));
|
||||||
|
successCB(fileId);
|
||||||
|
} catch (GoogleJsonResponseException e) {
|
||||||
|
Log.i(TAG, "Unable to create file: " + e.getDetails());
|
||||||
|
func.accept(new NativeResult(funID, e.getMessage(), null));
|
||||||
|
errorCB("Unable to create file: " +e.getMessage());
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.i(TAG, e.getMessage());
|
||||||
|
func.accept(new NativeResult(funID, e.getMessage(), null));
|
||||||
|
errorCB("Unable to create file: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void downloadCfgWithGPS(Consumer<File> func) {
|
||||||
|
GoogleSignInAccount ga = GoogleSignIn.getLastSignedInAccount(mContext);
|
||||||
|
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(mContext,
|
||||||
|
Collections.singletonList(DriveScopes.DRIVE_APPDATA));
|
||||||
|
credential.setSelectedAccount(ga.getAccount());
|
||||||
|
Drive service = DriveUtils.generateService(credential, mContext.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");
|
||||||
|
errorCB("file not found in drive");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean downloadSuccess = false;
|
||||||
|
int count = 0;
|
||||||
|
File fileLocal = getWalletCfgFile(account);
|
||||||
|
while (!downloadSuccess && count++ < 10) {
|
||||||
|
Log.i(TAG, String.format("download file: %s with GPS, try: %d", fileName, count));
|
||||||
|
try {
|
||||||
|
String jsonStr = DriveUtils.downloadFile(service, fileId);
|
||||||
|
FileUtils.writeFile(fileLocal, jsonStr);
|
||||||
|
downloadSuccess = true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.i(TAG, "error download file with GPS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (downloadSuccess) {
|
||||||
|
func.accept(fileLocal);
|
||||||
|
} else {
|
||||||
|
errorCB("error download file with GPS");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void downloadCfgWithApi(String accessToken, Consumer<File> func) {
|
||||||
|
DriverApiUtils api = new DriverApiUtils(accessToken);
|
||||||
|
String fileName = generateFileName(account);
|
||||||
|
File fileLocal = getWalletCfgFile(account);
|
||||||
|
boolean downloadSuccess = false;
|
||||||
|
int count = 0;
|
||||||
|
while (!downloadSuccess && count++ < 10) {
|
||||||
|
Log.i(TAG, String.format("download file: %s with api, try: %d", fileName, count));
|
||||||
|
try {
|
||||||
|
String fileId = api.queryOneAppFile(fileName);
|
||||||
|
if (Strings.isNullOrEmpty(fileId)) {
|
||||||
|
Log.i(TAG, "file not found in drive");
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
String jsonStr = api.fileInfo(fileId);
|
||||||
|
FileUtils.writeFile(fileLocal, jsonStr);
|
||||||
|
downloadSuccess = true;
|
||||||
|
} catch (IOException | JSONException e) {
|
||||||
|
Log.i(TAG, "error download file with api");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (downloadSuccess) {
|
||||||
|
func.accept(fileLocal);
|
||||||
|
} else {
|
||||||
|
errorCB("error download file with api");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void uploadCfgWithApi(String accessToken, Consumer<NativeResult> func) {
|
||||||
|
DriverApiUtils api = new DriverApiUtils(accessToken);
|
||||||
|
File fileLocal = getWalletCfgFile(account);
|
||||||
|
try {
|
||||||
|
String fileName = generateFileName(account);
|
||||||
|
String fileId = api.queryOneAppFile(fileName);
|
||||||
|
if (Strings.isNullOrEmpty(fileId)) {
|
||||||
|
String rep = api.uploadFile(fileLocal, "application/json");
|
||||||
|
JSONObject repData = new JSONObject(rep);
|
||||||
|
fileId = repData.getString("id");
|
||||||
|
}
|
||||||
|
Log.i(TAG, "success upload file with api, ID: " + fileId);
|
||||||
|
func.accept(new NativeResult(funID, null, fileId));
|
||||||
|
successCB(fileId);
|
||||||
|
} catch (IOException | JSONException e) {
|
||||||
|
func.accept(new NativeResult(funID, e.getMessage(), null));
|
||||||
|
errorCB("error upload file with api: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package com.jc.jcfw;
|
package com.jc.jcfw;
|
||||||
|
|
||||||
|
import static com.cege.games.release.Constants.FUNID_PREFIX;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -7,13 +9,17 @@ import android.net.Uri;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.cege.games.release.MainActivity;
|
import com.cege.games.release.MainActivity;
|
||||||
|
import com.cege.games.release.MainApplication;
|
||||||
import com.cege.games.release.ui.UIManager;
|
import com.cege.games.release.ui.UIManager;
|
||||||
|
import com.cege.games.release.webpage.events.CallJSEvent;
|
||||||
import com.cege.games.release.webpage.events.ProxyCBEvent;
|
import com.cege.games.release.webpage.events.ProxyCBEvent;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.jc.jcfw.google.PayClient;
|
import com.jc.jcfw.google.PayClient;
|
||||||
|
import com.jc.jcfw.util.ThreadUtils;
|
||||||
import com.jc.jcfw.util.UIUtils;
|
import com.jc.jcfw.util.UIUtils;
|
||||||
import com.unity3d.player.UnityPlayer;
|
import com.unity3d.player.UnityPlayer;
|
||||||
|
|
||||||
|
import org.cocos2dx.lib.CocosJSHelper;
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@ -30,11 +36,27 @@ public class JcSDK {
|
|||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
private static PayClient payClient;
|
private static PayClient payClient;
|
||||||
|
|
||||||
|
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 native void tick(float dt);
|
||||||
|
|
||||||
public static void initCommonCB(UnityCallback callBack) {
|
public static void initCommonCB(UnityCallback callBack) {
|
||||||
Log.i(TAG, "call init common callback from unity");
|
Log.i(TAG, "call init common callback from unity");
|
||||||
commonCB = callBack;
|
commonCB = callBack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Deprecated
|
||||||
|
* 不使用该方法, 直接由unity调用cpp方法
|
||||||
|
* @param password
|
||||||
|
*/
|
||||||
|
public static void initWallet(String password) {
|
||||||
|
Log.i(TAG, "call init wallet from unity with password: " + password);
|
||||||
|
CocosJSHelper.initWallet(password);
|
||||||
|
commonCB.nativeCallback("", "wallet init success", 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回调至c#
|
* 回调至c#
|
||||||
@ -78,12 +100,47 @@ public class JcSDK {
|
|||||||
UIUtils.showQRCode(MainActivity.app, content, "");
|
UIUtils.showQRCode(MainActivity.app, content, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void showWebPage(String funid, String url) {
|
||||||
|
MainActivity.app.showPage(funid, url);
|
||||||
|
}
|
||||||
|
|
||||||
public static void scanQRCode(String funid, String title) {
|
public static void scanQRCode(String funid, String title) {
|
||||||
// MainActivity.app.showQRScan(funid, title);
|
// MainActivity.app.showQRScan(funid, title);
|
||||||
UIManager.getSingleton().showQRScan(funid, title);
|
UIManager.getSingleton().showQRScan(funid, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void signWithTiktok(String funid) {
|
||||||
|
MainActivity.app.signWithTiktok(funid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void signWithFacebook(String funid) {
|
||||||
|
MainActivity.app.signWithFacebook(funid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void shareWithFacebook(String content) {
|
||||||
|
MainActivity.app.shareWithFacebook(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void signWithTwitter(String funid) {
|
||||||
|
MainActivity.app.signWithTwitter(funid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void signWithGoogle(String funid) {
|
||||||
|
MainActivity.app.signWithGoogle(funid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void signWithApple(String funid) {
|
||||||
|
// MainActivity.app.signWithApple(funid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void signWithOAuth(String funid, String jsonData) {
|
||||||
|
MainActivity.app.oauthLogin(funid, jsonData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void signOutGoogle(String funid) {
|
||||||
|
MainActivity.app.signOutGoogle(funid);
|
||||||
|
}
|
||||||
|
|
||||||
public static void logEvent(String content) {
|
public static void logEvent(String content) {
|
||||||
MainActivity.app.logEvent(content);
|
MainActivity.app.logEvent(content);
|
||||||
}
|
}
|
||||||
@ -119,25 +176,63 @@ public class JcSDK {
|
|||||||
payClient.queryPurchase(funid);
|
payClient.queryPurchase(funid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void signWithOAuth(String funid, String jsonData) {
|
public static void passStorageState(String funid, String account) {
|
||||||
MainActivity.app.oauthLogin(funid, jsonData);
|
Log.i(TAG, "passStorageState with: " + account);
|
||||||
|
MainActivity.app.passStorageState(funid, account);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void signWithGoogle(String funid) {
|
public static void storagePass(String funid, String account, String password) {
|
||||||
MainActivity.app.signWithGoogle(funid);
|
MainActivity.app.storagePass(funid, account, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void signOutGoogle(String funid) {
|
public static void authGetStoragePass(String funid, String account) {
|
||||||
MainActivity.app.signOutGoogle(funid);
|
MainActivity.app.authGetStoragePass(funid, account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void storageGameData(String data) {
|
||||||
|
MainApplication.application.setGameData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void getClientId(String funid) {
|
||||||
|
Log.i(TAG, "getClientId ");
|
||||||
|
MainActivity.app.getClientId(funid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onProxyCB(String funId, String data) {
|
||||||
|
EventBus.getDefault().post(new ProxyCBEvent(funId, data));
|
||||||
|
}
|
||||||
|
|
||||||
public static void nativeCb(String funId, String error, String dataStr) {
|
public static void nativeCb(String funId, String error, String dataStr) {
|
||||||
toUnity(funId, error, dataStr);
|
JSONObject result = new JSONObject();
|
||||||
|
try {
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
if (funId == null || funId.isEmpty()) {
|
||||||
|
funId = MainActivity.app.getFunId();
|
||||||
|
}
|
||||||
|
Log.i(TAG, String.format("%s native cb, error: %s, data: %s", funId, error, dataStr));
|
||||||
|
if (funId.startsWith(FUNID_PREFIX)) {
|
||||||
|
EventBus.getDefault().post(new CallJSEvent(funId, result.toString()));
|
||||||
|
} else {
|
||||||
|
String finalFunId = funId;
|
||||||
|
ThreadUtils.runInMain(() -> JcSDK.runJS(finalFunId, "jniCallback", new String[]{result.toString()}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void callNativeJS(String funId, String methodName, String[] params) {
|
||||||
|
ThreadUtils.runInMain(() -> JcSDK.runJS(funId, methodName, params));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void nativeCb(NativeResult result) {
|
public static void nativeCb(NativeResult result) {
|
||||||
toUnity(result.getFunid(), result.getError(), result.getDataStr());
|
nativeCb(result.getFunid(), result.getError(), result.getDataStr());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void toUnity(String funId, String error, String dataStr) {
|
public static void toUnity(String funId, String error, String dataStr) {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"client_id": "53206975661-asnf3qe4bg29p8h981pgf099osvrjbme.apps.googleusercontent.com",
|
"client_id": "53206975661-asnf3qe4bg29p8h981pgf099osvrjbme.apps.googleusercontent.com",
|
||||||
"redirect_uri": "com.googleusercontent.apps.53206975661-asnf3qe4bg29p8h981pgf099osvrjbme:/oauth2redirect",
|
"redirect_uri": "com.googleusercontent.apps.53206975661-asnf3qe4bg29p8h981pgf099osvrjbme:/oauth2redirect",
|
||||||
"end_session_redirect_uri": "com.googleusercontent.apps.53206975661-asnf3qe4bg29p8h981pgf099osvrjbme:/oauth2redirect",
|
"end_session_redirect_uri": "com.googleusercontent.apps.53206975661-asnf3qe4bg29p8h981pgf099osvrjbme:/oauth2redirect",
|
||||||
"authorization_scope": "openid email profile",
|
"authorization_scope": "openid email profile https://www.googleapis.com/auth/drive.appdata",
|
||||||
"discovery_uri": "https://accounts.google.com/.well-known/openid-configuration",
|
"discovery_uri": "https://accounts.google.com/.well-known/openid-configuration",
|
||||||
"authorization_endpoint_uri": "",
|
"authorization_endpoint_uri": "",
|
||||||
"token_endpoint_uri": "",
|
"token_endpoint_uri": "",
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
<string name="default_web_client_id1" translatable="false">53206975661-ih3r0ubph3rqejdq97b029difbrk2bqj.apps.googleusercontent.com</string>
|
<string name="default_web_client_id1" translatable="false">53206975661-ih3r0ubph3rqejdq97b029difbrk2bqj.apps.googleusercontent.com</string>
|
||||||
<string name="tips_scan_code" translatable="false"></string>
|
<string name="tips_scan_code" translatable="false"></string>
|
||||||
|
|
||||||
<string name="facebook_app_id" translatable="false">927390338872834</string>
|
<string name="facebook_app_id" translatable="false">1204701000119770</string>
|
||||||
<string name="fb_login_protocol_scheme" translatable="false">fb927390338872834</string>
|
<string name="fb_login_protocol_scheme" translatable="false">fb1204701000119770</string>
|
||||||
<string name="facebook_client_token" translatable="false">45a8f9658499222aedd76418f7c33b27</string>
|
<string name="facebook_client_token" translatable="false">3e29f2606ae15a99bb3824d2ef1a9d0b</string>
|
||||||
|
|
||||||
<string name="prompt_info_title" translatable="false">Biometric login for Wallet</string>
|
<string name="prompt_info_title" translatable="false">Biometric login for Wallet</string>
|
||||||
<string name="prompt_info_subtitle" translatable="false">Login using your biometric credential</string>
|
<string name="prompt_info_subtitle" translatable="false">Login using your biometric credential</string>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
apply from: "config.gradle"
|
apply from: "config.gradle"
|
||||||
include ':app'
|
include ':app'
|
||||||
rootProject.name = "HeadlessCocos"
|
rootProject.name = "HeadlessCocos"
|
||||||
|
include ':libcocos2dx'
|
||||||
|
project(':libcocos2dx').projectDir = new File(ext.cfgs.cocos2dxBasePath + '/cocos/platform/android/libcocos2dx')
|
||||||
|
|
||||||
include ':UnityDataAssetPack'
|
include ':UnityDataAssetPack'
|
||||||
project(':UnityDataAssetPack').projectDir = new File(ext.cfgs.unityAndroidProject + '/UnityDataAssetPack')
|
project(':UnityDataAssetPack').projectDir = new File(ext.cfgs.unityAndroidProject + '/UnityDataAssetPack')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user