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 & gt; 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