public class GoogleLogin
{
/ Responses supported by this class /
public static final int GOOGLE_RESPONSE_OK = 0;
public static final int GOOGLE_RESPONSE_CANCELED = 1;
public static final int GOOGLE_RESPONSE_ERROR = 2;
public static final int GOOGLE_RESPONSE_DEVELOPER_ERROR = 3;
/* Debug output tag /
private static final String TAG = "UE4-GOOGLE";
/* Is this a shipping build /
boolean bShippingBuild = false;
/* Has init been called succesfully /
public boolean bInitialized = false;
/* Has onStart() been called /
public boolean bStarted = false;
/*
* Activity needed here to send the signal back when user successfully logged in.
/
private GameActivity activity;
/* Name of game package /
private String packageName;
/* Android key from Google API dashboard /
private String clientId;
/* Backend server key from Google API dashboard /
private String serverClientId;
/* Unique request id when using sign in activity /
private static final int REQUEST_SIGN_IN = 9001;
/* Google API client needed for actual sign in */
private GoogleSignInClient mGoogleSignInClient;
public GoogleLogin(GameActivity activity, final Logger InLog, String inPackageName, String BuildConfiguration)
{
this.activity = activity;
GoogleLog = new Logger(TAG);
ActivityLog = InLog;
packageName = inPackageName;
bShippingBuild = BuildConfiguration.equals("Shipping");
}
public boolean init(String inClientId, String inServerClientId)
{
if (bShippingBuild)
{
GoogleLog.SuppressLogs();
}
boolean bClientIdValid = (inClientId != null && !inClientId.isEmpty());
boolean bServerIdValid = (inServerClientId != null && !inServerClientId.isEmpty());
if (bClientIdValid && bServerIdValid)
{
GoogleLog.debug("init");
boolean bIsAvailable = isGooglePlayServicesAvailable();
GoogleLog.debug("Is Google Play Services Available:" + bIsAvailable);
if (bIsAvailable)
{
GoogleLog.debug("packageName: " + packageName);
clientId = inClientId;
GoogleLog.debug("GoogleSignIn clientId:" + clientId);
serverClientId = inServerClientId;
GoogleLog.debug("GoogleSignIn serverClientId:" + serverClientId);
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(serverClientId)
.requestProfile()
//.requestServerAuthCode(serverClientId)
.requestEmail()
.build();
// Build a GoogleSignInClient with the options specified by gso.
mGoogleSignInClient = GoogleSignIn.getClient(activity, gso);
bInitialized = true;
PrintKeyHash(packageName);
}
}
else
{
GoogleLog.debug("clientId: " + inClientId + " or serverClientId: " + inServerClientId + " is invalid");
}
GoogleLog.debug("init complete: " + bInitialized);
return bInitialized;
}
public void onStart()
{
GoogleLog.debug("onStart");
bStarted = true;
}
public void onStop()
{
GoogleLog.debug("onStop");
}
public void onDestroy()
{
GoogleLog.debug("onDestroy");
}
public int login(String[] ScopeFields)
{
GoogleLog.debug("login:" + ScopeFields.toString());
int resultCode = GOOGLE_RESPONSE_ERROR;
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
if (signInIntent != null)
{
GoogleLog.debug("login start activity:");
activity.startActivityForResult(signInIntent, REQUEST_SIGN_IN);
resultCode = GOOGLE_RESPONSE_OK;
}
else
{
GoogleLog.debug("getSignInIntent failure:");
nativeLoginComplete(GOOGLE_RESPONSE_ERROR, "");
}
return resultCode;
}
public int logout()
{
GoogleLog.debug("logout");
mGoogleSignInClient.signOut()
.addOnCompleteListener(activity, new OnCompleteListener<Void>()
{
@Override
public void onComplete(@NonNull Task<Void> task)
{
boolean bWasSuccessful = task.isSuccessful();
GoogleLog.debug("onSignOut Complete success:" + bWasSuccessful);
nativeLogoutComplete(bWasSuccessful ? GOOGLE_RESPONSE_OK : GOOGLE_RESPONSE_ERROR);
}
});
return GOOGLE_RESPONSE_OK;
}
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
GoogleLog.debug("onActivityResult: " + requestCode + " result: " + resultCode);
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
if (requestCode == REQUEST_SIGN_IN)
{
GoogleLog.debug("onActivityResult REQUEST_SIGN_IN");
GoogleLog.debug("data: " + ((data != null) ? data.toString() : "null"));
if (resultCode == Activity.RESULT_OK)
{
GoogleLog.debug("signing in");
}
Task<GoogleSignInAccount> completedTask = GoogleSignIn.getSignedInAccountFromIntent(data);
try
{
// Try to access the account result
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
// Signed in successfully
GoogleLog.debug("Sign in success");
PrintUserAccountInfo(account);
nativeLoginComplete(GOOGLE_RESPONSE_OK, getLoginJsonStr(account));
}
catch (ApiException e)
{
// The ApiException status code indicates the detailed failure reason.
// Please refer to the GoogleSignInStatusCodes class reference for more information.
GoogleLog.debug("Sign in failure:" + GoogleSignInStatusCodes.getStatusCodeString(e.getStatusCode()));
if (e.getStatusCode() == GoogleSignInStatusCodes.DEVELOPER_ERROR)
{
nativeLoginComplete(GOOGLE_RESPONSE_DEVELOPER_ERROR, "");
}
else
{
nativeLoginComplete(GOOGLE_RESPONSE_ERROR, "");
}
}
GoogleLog.debug("onActivityResult end");
}
}
private String getLoginJsonStr(GoogleSignInAccount acct)
{
if (acct != null)
{
return "{\"user_data\":" + getUserJsonStr(acct) + "," +
"\"auth_data\":" + getAuthTokenJsonStr(acct) + "}";
}
return "";
}
private String getUserJsonStr(GoogleSignInAccount acct)
{
if (acct != null)
{
return "{\"sub\":\""+ acct.getId() + "\"," +
"\"given_name\":\"" + acct.getGivenName() + "\"," +
"\"family_name\":\"" + acct.getFamilyName() + "\"," +
"\"name\":\"" + acct.getDisplayName() + "\"," +
"\"picture\":\"" + acct.getPhotoUrl() + "\"" + "}";
}
return "";
}
private String getAuthTokenJsonStr(GoogleSignInAccount acct)
{
if (acct != null)
{
return "{\"access_token\":\"androidInternal\"," +
"\"refresh_token\":\"androidInternal\"," +
"\"id_token\":\""+ acct.getIdToken() + "\"}";
}
return "";
}
public void PrintUserAccountInfo(GoogleSignInAccount acct)
{
GoogleLog.debug("PrintUserAccountInfo");
if (acct != null)
{
GoogleLog.debug("User Details:");
GoogleLog.debug(" DisplayName:" + acct.getDisplayName());
GoogleLog.debug(" Id:" + acct.getId());
GoogleLog.debug(" Email:" + acct.getEmail());
GoogleLog.debug(" Account:" + acct.getAccount().toString());
GoogleLog.debug(" Scopes:" + acct.getGrantedScopes());
GoogleLog.debug(" IdToken:" + acct.getIdToken());
GoogleLog.debug(" ServerAuthCode:" + acct.getServerAuthCode());
}
else
{
GoogleLog.debug("Account is null");
}
}
private boolean isGooglePlayServicesAvailable()
{
GoogleApiAvailability apiAvail = GoogleApiAvailability.getInstance();
int status = apiAvail.isGooglePlayServicesAvailable(activity);
GoogleLog.debug("isGooglePlayServicesAvailable statusCode: " + status);
if (status == ConnectionResult.SUCCESS)
{
return true;
}
else
{
return false;
}
}
public void PrintKeyHash(String packageName)
{
try
{
PackageInfo info = activity.getPackageManager().getPackageInfo(
packageName,
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures)
{
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
GoogleLog.debug(Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
}
catch (PackageManager.NameNotFoundException e)
{
GoogleLog.debug("NameNotFoundException:" + e);
}
catch (NoSuchAlgorithmException e)
{
GoogleLog.debug("NoSuchAlgorithmException:" + e);
}
}
// Callback that notify the C++ implementation that a task has completed
public native void nativeLoginComplete(int responseCode, String javaData);
public native void nativeLogoutComplete(int responseCode);
}
import android.accounts.Account; import android.app.Activity; import android.content.Intent; import android.content.IntentSender; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import android.content.res.Resources; import android.os.Bundle; import android.support.annotation.NonNull; import android.util.Base64;
import com.google.android.gms.common.api.Result; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability;
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.auth.api.signin.GoogleSignInStatusCodes; import com.google.android.gms.common.api.ApiException; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task;
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;
public class GoogleLogin { / Responses supported by this class / public static final int GOOGLE_RESPONSE_OK = 0; public static final int GOOGLE_RESPONSE_CANCELED = 1; public static final int GOOGLE_RESPONSE_ERROR = 2; public static final int GOOGLE_RESPONSE_DEVELOPER_ERROR = 3;
/* Debug output tag / private static final String TAG = "UE4-GOOGLE";
// Output device for log messages. private Logger GoogleLog; private Logger ActivityLog;
/* Is this a shipping build / boolean bShippingBuild = false; /* Has init been called succesfully / public boolean bInitialized = false; /* Has onStart() been called / public boolean bStarted = false;
/* * Activity needed here to send the signal back when user successfully logged in. / private GameActivity activity;
/* Name of game package / private String packageName; /* Android key from Google API dashboard / private String clientId; /* Backend server key from Google API dashboard / private String serverClientId; /* Unique request id when using sign in activity / private static final int REQUEST_SIGN_IN = 9001; /* Google API client needed for actual sign in */ private GoogleSignInClient mGoogleSignInClient;
public GoogleLogin(GameActivity activity, final Logger InLog, String inPackageName, String BuildConfiguration) { this.activity = activity;