cocos_android/app/src/com/cege/games/release/MainActivity.java
2023-05-17 11:42:44 +08:00

901 lines
30 KiB
Java

package com.cege.games.release;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.Window;
import android.widget.Toast;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.core.app.ActivityOptionsCompat;
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.CustomCaptureActivity;
import com.cege.games.release.activity.WebPageActivity;
import com.cege.games.release.apple.AppleLoginActivity;
import com.cege.games.release.dialog.QRCodeActivity;
import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
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.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
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.firebase.analytics.FirebaseAnalytics;
import com.jc.jcfw.JcSDK;
import com.jc.jcfw.appauth.AuthStateManager;
import com.jc.jcfw.appauth.JConfiguration;
import com.jc.jcfw.util.FileUtils;
import com.jc.jcfw.util.JsonUtils;
import com.king.zxing.CameraScan;
import com.king.zxing.util.CodeUtils;
import com.king.zxing.util.LogUtils;
import com.unity3d.player.UnityPlayerActivity;
import net.openid.appauth.AppAuthConfiguration;
import net.openid.appauth.AuthState;
import net.openid.appauth.AuthorizationException;
import net.openid.appauth.AuthorizationRequest;
import net.openid.appauth.AuthorizationResponse;
import net.openid.appauth.AuthorizationService;
import net.openid.appauth.AuthorizationServiceConfiguration;
import net.openid.appauth.ClientAuthentication;
import net.openid.appauth.ClientSecretBasic;
import net.openid.appauth.RegistrationRequest;
import net.openid.appauth.RegistrationResponse;
import net.openid.appauth.ResponseTypeValues;
import net.openid.appauth.TokenRequest;
import net.openid.appauth.TokenResponse;
import net.openid.appauth.browser.AnyBrowserMatcher;
import net.openid.appauth.browser.BrowserMatcher;
import org.cocos2dx.lib.Cocos2dxHelper;
import org.cocos2dx.lib.CocosJSHelper;
import org.json.JSONException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;
public class MainActivity extends UnityPlayerActivity
implements Cocos2dxHelper.Cocos2dxHelperListener, EasyPermissions.PermissionCallbacks {
private static final String TAG = MainActivity.class.getSimpleName();
public static MainActivity app;
private Toast toast;
public static final String KEY_TITLE = "key_title";
public static final String KEY_IS_CONTINUOUS = "key_continuous_scan";
// scan QRCode
public static final int REQUEST_CODE_SCAN = 0X01;
public static final int REQUEST_CODE_PHOTO = 0X02;
// AppAuth
private static final int RC_AUTH = 0X04;
// google signin
private static final int RC_SIGN_IN = 0X05;
public static final int RC_CAMERA = 0X011;
public static final int RC_READ_PHOTO = 0X012;
public static final int FILE_SELECTOR_CODE = 0X014;
private String title;
private String funId;
private String oid;
private QRCodeActivity qrCodeActivity;
// AppAuth
private AuthorizationService mAuthService;
private AuthStateManager mAuthStateManager;
private JConfiguration mConfiguration;
private ExecutorService mExecutor;
private final AtomicReference<String> mClientId = new AtomicReference<>();
private final AtomicReference<AuthorizationRequest> mAuthRequest = new AtomicReference<>();
private final AtomicReference<CustomTabsIntent> mAuthIntent = new AtomicReference<>();
private CountDownLatch mAuthIntentLatch = new CountDownLatch(1);
private TikTokOpenApi tiktokOpenApi;
public String getFunId() {
return funId;
}
@NonNull
private final BrowserMatcher mBrowserMatcher = AnyBrowserMatcher.INSTANCE;
private GoogleSignInClient mGoogleSignInClient;
// facebook login
private CallbackManager mCallbackManager;
private FirebaseAnalytics mFirebaseAnalytics;
private AppEventsLogger fbLogger;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate: " + getIntent().getDataString());
// Obtain the FirebaseAnalytics instance.
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
onLoadNativeLibraries();
app = this;
Cocos2dxHelper.init(this);
CocosJSHelper.initJSEnv(getApplicationContext());
// begin of google sign
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id1))
.requestScopes(new Scope(Scopes.EMAIL))
// .requestScopes(new Scope("https://www.googleapis.com/auth/drive.appdata"))
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
// end of google sign
// begin of google oauth sign
mExecutor = Executors.newSingleThreadExecutor();
mAuthStateManager = AuthStateManager.getInstance(this);
mConfiguration = JConfiguration.getInstance(this);
mExecutor.submit(this::initializeAppAuth);
// end of google oauth sign
// begin of facebook login
initFacebookSDK();
// end of facebook login
// ATTENTION: This was auto-generated to handle app links.
// Intent appLinkIntent = getIntent();
// String appLinkAction = appLinkIntent.getAction();
// Uri appLinkData = appLinkIntent.getData();
tiktokOpenApi = TikTokOpenApiFactory.create(this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mCallbackManager.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && data != null) {
switch (requestCode) {
case REQUEST_CODE_SCAN:
String result = CameraScan.parseScanResult(data);
Log.i(TAG, "scan qrcode with funId: " + funId + " result: " + result);
JcSDK.nativeCb(funId, null, result);
funId = "";
break;
case REQUEST_CODE_PHOTO:
parsePhoto(data);
break;
case RC_AUTH:
AuthorizationResponse response = AuthorizationResponse.fromIntent(data);
AuthorizationException ex = AuthorizationException.fromIntent(data);
if (response != null || ex != null) {
mAuthStateManager.updateAfterAuthorization(response, ex);
}
if (response != null && response.authorizationCode != null) {
// authorization code exchange is required
mAuthStateManager.updateAfterAuthorization(response, ex);
exchangeAuthorizationCode(response);
} else if (ex != null) {
Log.i(TAG, "Authorization flow failed: " + ex.getMessage());
} else {
Log.i(TAG, "No authorization state retained - reauthorization required");
}
break;
case RC_SIGN_IN:
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
handleSignInResult(task);
break;
case FILE_SELECTOR_CODE:
Uri uri = data.getData();
shareToTikTok(funId, uri);
break;
}
} else {
boolean next = false;
if (requestCode == REQUEST_CODE_SCAN && data != null) {
if (data.getBooleanExtra("localImg", false)) {
startPhotoCode(this.funId);
next = true;
}
}
if (!next) {
if (requestCode == RC_SIGN_IN) {
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
handleSignInResult(task);
}
if (requestCode == REQUEST_CODE_SCAN) {
JcSDK.nativeCb(funId, "activity result with code: " + resultCode, null);
}
funId = "";
}
}
}
private Context getContext() {
return this;
}
@Override
protected void onStart() {
super.onStart();
if (mExecutor.isShutdown()) {
mExecutor = Executors.newSingleThreadExecutor();
}
}
// begin for unity
@Override
protected void onNewIntent(Intent intent) {
// To support deep linking, we need to make sure that the client can get access
// to
// the last sent intent. The clients access this through a JNI api that allows
// them
// to get the intent set on launch. To update that after launch we have to
// manually
// replace the intent with the one caught here.
setIntent(intent);
}
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 (Exception e) {
e.printStackTrace();
}
}
@Override
public void showDialog(String pTitle, String pMessage) {
}
@Override
public void runOnGLThread(Runnable pRunnable) {
}
/** begin of easypermissions */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// Forward results to EasyPermissions
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
@Override
public void onPermissionsGranted(int requestCode, @NonNull List<String> list) {
// Some permissions have been granted
}
@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> list) {
// Some permissions have been denied
if ((requestCode == RC_CAMERA || requestCode == RC_READ_PHOTO) && null != funId && !"".equals(funId)) {
JcSDK.nativeCb(funId, "User cancel", null);
funId = "";
}
}
// end of easypermissions
// begin of qrcode
/**
* check if had permission for camera
*/
@AfterPermissionGranted(RC_CAMERA)
private void checkCameraPermissions() {
String[] perms = { Manifest.permission.CAMERA };
if (EasyPermissions.hasPermissions(this, perms)) {
startScan(title);
} else {
// Do not have permissions, request them now
EasyPermissions.requestPermissions(this, getString(R.string.permission_camera),
RC_CAMERA, perms);
}
}
/**
* scan qrcode
*/
private void startScan(String title) {
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.in, R.anim.out);
Intent intent = new Intent(this, CustomCaptureActivity.class);
// Intent intent = new Intent(this, CaptureActivity.class);
intent.putExtra(KEY_TITLE, title);
intent.putExtra(KEY_IS_CONTINUOUS, false);
runOnUiThread(() -> {
this.startActivityForResult(intent, REQUEST_CODE_SCAN, optionsCompat.toBundle());
});
}
private void asyncThread(Runnable runnable) {
new Thread(runnable).start();
}
private void parsePhoto(Intent data) {
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), data.getData());
parsePhotoData(bitmap);
} catch (Exception e) {
e.printStackTrace();
JcSDK.nativeCb(funId, e.toString(), null);
funId = "";
}
}
private void parsePhotoData(Bitmap bitmap) {
asyncThread(() -> {
final String result = CodeUtils.parseQRCode(bitmap);
if (null == result || "".equals(result)) {
JcSDK.nativeCb(funId, "no qrdeata", null);
} else {
LogUtils.d("result:" + result);
JcSDK.nativeCb(funId, null, result);
}
funId = "";
});
}
public void showQRScan(String funId, String title) {
this.title = title;
this.funId = funId;
checkCameraPermissions();
}
/**
* start image scan
*/
public void startPhotoCode(String funId) {
Intent pickIntent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(pickIntent, REQUEST_CODE_PHOTO);
}
// end of qrcode
public void signWithGoogle(String funId) {
this.funId = funId;
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
if (account != null) {
Log.w(TAG, "already login: " + account.getIdToken());
mGoogleSignInClient.silentSignIn()
.addOnCompleteListener(this, this::handleSignInResult);
} else {
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);
}
} else {
Log.i(TAG, "no gms, use app auth");
AuthState state = mAuthStateManager.getCurrent();
if (state.isAuthorized() && state.getIdToken() != null) {
Log.w(TAG, "getNeedsTokenRefresh: " + state.getNeedsTokenRefresh());
if (state.getNeedsTokenRefresh()) {
Log.w(TAG, "need refresh accessToken");
TokenRequest tokenRequest = state.createTokenRefreshRequest();
performTokenRequest(
tokenRequest,
this::handleCodeExchangeResponse);
} else {
Log.w(TAG, "already login, accessToken not expired");
Log.w(TAG, "id token : " + state.getIdToken());
runOnUiThread(() -> successSdkCb(state.getIdToken()));
}
} else {
mExecutor.submit(this::doAuth);
}
}
}
public void signOutGoogle(String funId) {
mGoogleSignInClient.signOut()
.addOnCompleteListener(this, task -> {
// ...
});
}
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
try {
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
Log.w(TAG, "signIn success: ");
Log.w(TAG, "gsa idToken: " + account.getIdToken());
runOnUiThread(() -> successSdkCb(account.getIdToken()));
// Signed in successfully, show authenticated UI.
} catch (ApiException e) {
// The ApiException status code indicates the detailed failure reason.
// Please refer to the GoogleSignInStatusCodes class reference for more
// information.
Log.w(TAG, "signInResult:failed code=" + e.getStatusCode());
}
}
// begin of AppAuth
/**
* Initializes the authorization service configuration if necessary, either from
* the local
* static values or by retrieving an OpenID discovery document.
*/
@WorkerThread
private void initializeAppAuth() {
Log.i(TAG, "Initializing AppAuth");
recreateAuthorizationService();
if (mAuthStateManager.getCurrent().getAuthorizationServiceConfiguration() != null) {
// configuration is already created, skip to client initialization
Log.i(TAG, "auth config already established");
initializeClient();
return;
}
// if we are not using discovery, build the authorization service configuration
// directly
// from the static configuration values.
if (mConfiguration.getDiscoveryUri() == null) {
Log.i(TAG, "Creating auth config from res/raw/auth_config.json");
AuthorizationServiceConfiguration config = new AuthorizationServiceConfiguration(
mConfiguration.getAuthEndpointUri(),
mConfiguration.getTokenEndpointUri(),
mConfiguration.getRegistrationEndpointUri(),
mConfiguration.getEndSessionEndpoint());
mAuthStateManager.replace(new AuthState(config));
initializeClient();
return;
}
// WrongThread inference is incorrect for lambdas
// noinspection WrongThread
Log.i(TAG, "Retrieving OpenID discovery doc");
AuthorizationServiceConfiguration.fetchFromUrl(
mConfiguration.getDiscoveryUri(),
this::handleConfigurationRetrievalResult,
mConfiguration.getConnectionBuilder());
}
@MainThread
private void handleConfigurationRetrievalResult(
AuthorizationServiceConfiguration config,
AuthorizationException ex) {
if (config == null) {
Log.i(TAG, "Failed to retrieve discovery document", ex);
return;
}
Log.i(TAG, "Discovery document retrieved");
mAuthStateManager.replace(new AuthState(config));
mExecutor.submit(this::initializeClient);
}
private void recreateAuthorizationService() {
if (mAuthService != null) {
Log.i(TAG, "Discarding existing AuthService instance");
mAuthService.dispose();
}
mAuthService = createAuthorizationService();
mAuthRequest.set(null);
mAuthIntent.set(null);
}
private AuthorizationService createAuthorizationService() {
Log.i(TAG, "Creating authorization service");
AppAuthConfiguration.Builder builder = new AppAuthConfiguration.Builder();
builder.setBrowserMatcher(mBrowserMatcher);
builder.setConnectionBuilder(mConfiguration.getConnectionBuilder());
return new AuthorizationService(this, builder.build());
}
private void createAuthRequest(@Nullable String loginHint) {
Log.i(TAG, "Creating auth request for login hint: " + loginHint);
AuthorizationRequest.Builder authRequestBuilder = new AuthorizationRequest.Builder(
mAuthStateManager.getCurrent().getAuthorizationServiceConfiguration(),
mClientId.get(),
ResponseTypeValues.CODE,
mConfiguration.getRedirectUri())
.setScope(mConfiguration.getScope());
if (!TextUtils.isEmpty(loginHint)) {
authRequestBuilder.setLoginHint(loginHint);
}
mAuthRequest.set(authRequestBuilder.build());
}
private void warmUpBrowser() {
mAuthIntentLatch = new CountDownLatch(1);
mExecutor.execute(() -> {
Log.i(TAG, "Warming up browser instance for auth request");
CustomTabsIntent.Builder intentBuilder = mAuthService.createCustomTabsIntentBuilder(mAuthRequest.get().toUri());
mAuthIntent.set(intentBuilder.build());
mAuthIntentLatch.countDown();
});
}
@MainThread
private void initializeAuthRequest() {
createAuthRequest("");
warmUpBrowser();
displayAuthOptions();
}
/**
* Initiates a dynamic registration request if a client ID is not provided by
* the static
* configuration.
*/
@WorkerThread
private void initializeClient() {
if (mConfiguration.getClientId() != null) {
Log.i(TAG, "Using static client ID: " + mConfiguration.getClientId());
// use a statically configured client ID
mClientId.set(mConfiguration.getClientId());
runOnUiThread(this::initializeAuthRequest);
return;
}
RegistrationResponse lastResponse = mAuthStateManager.getCurrent().getLastRegistrationResponse();
if (lastResponse != null) {
Log.i(TAG, "Using dynamic client ID: " + lastResponse.clientId);
// already dynamically registered a client ID
mClientId.set(lastResponse.clientId);
runOnUiThread(this::initializeAuthRequest);
return;
}
// WrongThread inference is incorrect for lambdas
// noinspection WrongThread
Log.i(TAG, "Dynamically registering client");
RegistrationRequest registrationRequest = new RegistrationRequest.Builder(
mAuthStateManager.getCurrent().getAuthorizationServiceConfiguration(),
Collections.singletonList(mConfiguration.getRedirectUri()))
.setTokenEndpointAuthenticationMethod(ClientSecretBasic.NAME)
.build();
mAuthService.performRegistrationRequest(
registrationRequest,
this::handleRegistrationResponse);
}
private void handleRegistrationResponse(
RegistrationResponse response,
AuthorizationException ex) {
mAuthStateManager.updateAfterRegistration(response, ex);
if (response == null) {
Log.i(TAG, "Failed to dynamically register client", ex);
return;
}
Log.i(TAG, "Dynamically registered client: " + response.clientId);
mClientId.set(response.clientId);
initializeAuthRequest();
}
private void displayAuthOptions() {
AuthState state = mAuthStateManager.getCurrent();
AuthorizationServiceConfiguration config = state.getAuthorizationServiceConfiguration();
String authEndpointStr;
if (config.discoveryDoc != null) {
authEndpointStr = "Discovered auth endpoint: \n";
} else {
authEndpointStr = "Static auth endpoint: \n";
}
authEndpointStr += config.authorizationEndpoint;
Log.i(TAG, authEndpointStr);
String clientIdStr;
if (state.getLastRegistrationResponse() != null) {
clientIdStr = "Dynamic client ID: \n";
} else {
clientIdStr = "Static client ID: \n";
}
clientIdStr += mClientId;
Log.i(TAG, clientIdStr);
}
/**
* Performs the authorization request, using the browser selected in the
* spinner,
* and a user-provided `login_hint` if available.
*/
@WorkerThread
private void doAuth() {
try {
mAuthIntentLatch.await();
} catch (InterruptedException ex) {
Log.w(TAG, "Interrupted while waiting for auth intent");
}
Intent intent = mAuthService.getAuthorizationRequestIntent(
mAuthRequest.get(),
mAuthIntent.get());
startActivityForResult(intent, RC_AUTH);
}
@MainThread
private void exchangeAuthorizationCode(AuthorizationResponse authorizationResponse) {
Log.d(TAG, "Exchanging authorization code");
performTokenRequest(
authorizationResponse.createTokenExchangeRequest(),
this::handleCodeExchangeResponse);
}
@MainThread
private void performTokenRequest(
TokenRequest request,
AuthorizationService.TokenResponseCallback callback) {
ClientAuthentication clientAuthentication;
try {
clientAuthentication = mAuthStateManager.getCurrent().getClientAuthentication();
} catch (ClientAuthentication.UnsupportedAuthenticationMethod ex) {
Log.d(TAG, "Token request cannot be made, client authentication for the token "
+ "endpoint could not be constructed (%s)", ex);
return;
}
mAuthService.performTokenRequest(
request,
clientAuthentication,
callback);
}
@WorkerThread
private void handleCodeExchangeResponse(
@Nullable TokenResponse tokenResponse,
@Nullable AuthorizationException authException) {
mAuthStateManager.updateAfterTokenResponse(tokenResponse, authException);
if (!mAuthStateManager.getCurrent().isAuthorized()) {
final String message = "Authorization Code exchange failed"
+ ((authException != null) ? authException.error : "");
// WrongThread inference is incorrect for lambdas
// noinspection WrongThread
Log.d(TAG, message);
} else {
AuthState state = mAuthStateManager.getCurrent();
Log.d(TAG, "login success, auth state: " + state.isAuthorized());
Log.d(TAG, "app auth idToken: " + state.getIdToken());
mAuthStateManager.replace(state);
runOnUiThread(() -> successSdkCb(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;
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);
}
public void showQRCode(String funid, String str, String title, String oid) {
runOnUiThread(() -> {
if (qrCodeActivity == null) {
qrCodeActivity = new QRCodeActivity(getContext());
}
qrCodeActivity.showQRCode(str, title, oid);
qrCodeActivity.show();
});
}
public void showToast(String text) {
runOnUiThread(() -> {
if (toast == null) {
toast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
} else {
toast.setDuration(Toast.LENGTH_SHORT);
toast.setText(text);
}
toast.show();
});
}
// 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)) {
runOnUiThread(() -> errorSdkCb("access token expired"));
}
}
@Override
public void onCancel() {
Log.d(TAG, "Login cancel");
runOnUiThread(() -> errorSdkCb("user login cancel"));
}
@Override
public void onError(FacebookException exception) {
Log.i(TAG, "Login error: " + exception.getMessage());
runOnUiThread(() -> errorSdkCb(exception.getMessage()));
}
});
}
public void signWithFacebook(String funId) {
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) {
ShareLinkContent linkContent = new ShareLinkContent.Builder()
.setContentUrl(Uri.parse("https://www.baidu.com"))
.setQuote(content)
.build();
ShareDialog.show(this, linkContent);
}
private boolean verifyFbAccessToken(AccessToken accessToken) {
boolean isLoggedIn = accessToken != null && !accessToken.isExpired();
if (isLoggedIn) {
runOnUiThread(() -> successSdkCb(accessToken.getToken()));
return true;
} else {
return false;
}
}
// end of facebook login
public void signWithTwitter(String funId) {
Log.i(TAG, "login with twitter: " + funId);
this.funId = funId;
}
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 signWithApple(String funId) {
this.funId = funId;
Log.i(TAG, "login with apple: " + funId);
runOnUiThread(() -> {
Intent intent = new Intent(this, AppleLoginActivity.class);
intent.putExtra("funId", funId);
startActivity(intent);
});
}
public void showPage(String fid, final String url) {
runOnUiThread(() -> {
Log.i(TAG, "show page: " + url);
Intent intent = new Intent(this, WebPageActivity.class);
intent.putExtra("url", url);
startActivity(intent);
// picker video file and share to tiktok
// openFileSelector();
});
}
public void shareToTikTok(String funId, Uri uriToImage) {
this.funId = 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);
}
}