Follow the steps on this page to integrate now.gg Login into your Android app, configure it and add the now.gg Sign-in button to your app’s layout that starts the login flow.
Make sure you have completed the prerequisites checklist and set up your developer environment.
Start by adding the permissions to AndroidManifest.xml.
<uses-permission android:name="android.permission.GET_ACCOUNTS"/> <uses-permission android:name="android.permission.INTERNET"/>
Add the following dependencies in your application build.gradle file:
//retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0' implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
The now.gg Sign-in button assets are included within now.gg SDK package under the Assets/Login directory.
Button signInButton = findViewById(R.id.now_gg_login_button);
In the Android activity’s onCreate method, add OnClickListener for the sign-in button.
findViewById(R.id.now_gg_login_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
signIn();
}
});
You should now check for the GET_ACCOUNTS permission and Results.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (checkSelfPermission(Manifest.permission.GET_ACCOUNTS) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {
Manifest.permission.GET_ACCOUNTS
},
GET_ACCOUNTS_REQUEST_CODE);
} else {
// has GET_ACCOUNTS permission, can proceed with signin
Log.d(TAG, "onCreate: Already has permission, proceed with signin");
}
}
onRequestPermissionsResult:
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == GET_ACCOUNTS_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted, can proceed with sign-in.
signIn();
}
}
}
The following code sample is to perform ‘Sign-in with now.gg Account’, which should be triggered on the click of the Login Button.
public static final String ID_TOKEN = "id_token"; // Do Not Modify
public static final String CLIENT_ID = "<your client id>"; // Replace with your client id
public static final String ACCOUNT_TYPE = "now.gg"; // Do Not Modify
public static final String HOST_URL = "hostUrl"; //Do Not Modify
private void signIn() {
Account account = getNowggAccount();
if (account != null) {
Bundle bundle = new Bundle();
bundle.putString("client_id", CLIENT_ID);
String authTokenType = ID_TOKEN;
AccountManager.get(getApplicationContext()).
getAuthToken(account, authTokenType, bundle, MainActivity.this, new OnTokenAcquired(), null);
} else {
addNowggAccount();
}
}
private Account getNowggAccount() {
Account[] accounts = AccountManager.get(getApplicationContext()).getAccountsByType(ACCOUNT_TYPE);
if (accounts.length > 0) {
Log.d(TAG, "getNowggAccount: account found");
// currently only one now.gg account can be added in a system
return accounts[0];
}
return null;
}
private void addNowggAccount() {
try {
Intent intent = new Intent();
intent.setComponent(new ComponentName("gg.now.accounts", "gg.now.accounts.AuthenticatorActivity"));
intent.setAction("IAP_ADD_ACCOUNT");
intent.putExtra("resultReceiver", parcelResultReceiver(resultReceiver));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
ResultReceiver parcelResultReceiver(ResultReceiver actualReceiver) {
Parcel parcel = Parcel.obtain();
actualReceiver.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel);
parcel.recycle();
return receiverForSending;
}
ResultReceiver resultReceiver = new ResultReceiver(new Handler(Looper.getMainLooper())) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
Log.d(TAG, "onReceiveResult() called with: resultCode = [" + resultCode + "], resultData = [" + resultData.toString() + "]");
// onReceiveResult
if (resultCode == 0) { // means sign in is okay
signIn();
} else {
// sign in failed
Log.d(TAG, "onReceiveResult: sign in failed");
}
}
};
After the user signs in, you will get the requested token (id_token) in OnTokenAcquired callback function. This token can be used to get the user’s details by verifying the token or passing the token to your backend server. You will get the user details from your server as a response.
private class OnTokenAcquired implements AccountManagerCallback {
@Override
public void run(AccountManagerFuture result) {
try {
Bundle bundle = (Bundle) result.getResult();
boolean success = bundle.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
if (success) {
final String token = bundle.getString(ID_TOKEN);
// get the now.gg server URL, from which you can get the user details and verify the tokens
final String hostUrl = bundle.getString(HOST_URL);
verifyToken(token, hostUrl);
}
else {
// get token failed
// error case. The developer can show errors or show other login mechanisms
Log.d(TAG, "run: get token failed " + bundle);
}
} catch (AuthenticatorException | IOException | OperationCanceledException e) {
e.printStackTrace();
}
}
}
Now, you have to verify the integrity of id_token (that you received in OnTokenAcquired) by calling the verifyToken function and get the user’s details, as illustrated below:
private void verifyToken(String idToken, String hostUrl) {
BackendApiCallService backendApiCallService = getBackendRetrofit(hostUrl).create(BackendApiCallService.class);
Call < TokenVerifyResponse > tokenVerifyResponseCall = backendApiCallService.verifyIdToken(new TokenVerifyRequest(ID_TOKEN, idToken, CLIENT_ID));
tokenVerifyResponseCall.enqueue(new Callback < TokenVerifyResponse > () {
@Override
public void onResponse(Call < TokenVerifyResponse > call, Response < TokenVerifyResponse > response) {
if (response.isSuccessful()) {
Log.d(TAG, "onResponse: " + response.body().toString());
} else {
Gson gson = new Gson();
TokenVerifyResponse error = gson.fromJson(response.errorBody().charStream(), TokenVerifyResponse.class);
if (!error.isSuccess() && ("EXPIRED_TOKEN".equals(error.getCode()) || "INVALID_TOKEN".equals(error.getCode()))) {
// retry the verify token call, after getting a new TOKEN
}
}
}
@Override
public void onFailure(Call call, Throwable t) {
Log.d(TAG, "onFailure() called with: call = [" + call + "], t = [" + t + "]");
}
});
}
public Retrofit getBackendRetrofit(String hostUrl) {
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
return new Retrofit.Builder()
.baseUrl(hostUrl)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
}
public interface BackendApiCallService {
@POST("/accounts/oauth2/v1/verify-token")
Call < TokenVerifyResponse > verifyIdToken(@Body TokenVerifyRequest authRequest);
}
public class TokenVerifyRequest {
String token_type;
String token;
String client_id;
public TokenVerifyRequest(String token_type, String token, String client_id) {
this.token_type = token_type;
this.token = token;
this.client_id = client_id;
}
}
public class TokenVerifyResponse {
boolean success;
String code;
String msg;
@SerializedName("decodedData")
UserDataVerified userDataVerified;
public TokenVerifyResponse(boolean success, String code, String msg, UserDataVerified userDataVerified) {
this.success = success;
this.code = code;
this.msg = msg;
this.userDataVerified = userDataVerified;
}
public UserDataVerified getUserDataVerified() {
return userDataVerified;
}
public boolean isSuccess() {
return success;
}
public String getCode() {
return code;
}
@Override
public String toString() {
return "TokenVerifyResponse{" +
"success=" + success +
", code='" + code + '\'' +
", msg='" + msg + '\'' +
", userDataVerified=" + userDataVerified +
'}';
}
}
For more information on the UserDataVerified class, please refer to the Retrieve Profile Information section.
Note:
signIn function again.This section illustrates how to implement logout for your users.
To perform log out for a user:
The following section illustrates the process of using the retrieved profile information of the user.
id_token. To get user details that you received in OnTokenAcquired, you have to call the verifyToken function.If your app does not have a backend server, you can use the following section to retrieve user profile information.
You can get the profile information for a logged-in user, using an on-device API call. To do this, use the userDataVerified field from the TokenVerifyResponse that you received by calling the verifyToken function.
UserDataVerified userData = tokenVerifyResponse.getUserDataVerified();
String userId = userData.getUserId();
String name = userData.getName();
String email = userData.getEmail();
String picture = userData.getPicture();
public class UserDataVerified {
String iss;
String sub;
String aud;
String exp;
String iat;
String auth_time;
String tokenId;
String sessionId;
String scope;
String email;
String name;
String picture;
String mobile;
String userId;
public UserDataVerified(String iss, String sub, String aud, String exp, String iat,
String auth_time, String email, String mobile, String userId,
String tokenId, String sessionId, String scope, String name, String picture) {
this.iss = iss;
this.sub = sub;
this.aud = aud;
this.exp = exp;
this.iat = iat;
this.auth_time = auth_time;
this.email = email;
this.mobile = mobile;
this.userId = userId;
this.tokenId = tokenId;
this.sessionId = sessionId;
this.scope = scope;
this.name = name;
this.picture = picture;
}
@Override
public String toString() {
return "UserDataVerified{" +
"iss='" + iss + '\'' +
", sub='" + sub + '\'' +
", aud='" + aud + '\'' +
", exp='" + exp + '\'' +
", iat='" + iat + '\'' +
", auth_time='" + auth_time + '\'' +
", tokenId='" + tokenId + '\'' +
", sessionId='" + sessionId + '\'' +
", scope='" + scope + '\'' +
", email='" + email + '\'' +
", name='" + name + '\'' +
", picture='" + picture + '\'' +
", mobile='" + mobile + '\'' +
", userId='" + userId + '\'' +
'}';
}
}
userId on the client using userData.getUserId().userId as a response with the user data.User Account Service
User Account Service
Document Rev. 1.0