Integrating Login

Follow the steps on this page to integrate Login into your Android app, configure it and add the Sign-in button to your app’s layout that starts the login flow.

Before you start

Make sure you have completed the prerequisites checklist and set up your developer environment.

Add Permissions and Assets

1. Add the permissions to AndroidManifest.xml
 <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
  <uses-permission android:name="android.permission.INTERNET"/> 
2. Add dependencies in your application build.gradle file
 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'
3. Add the Sign-in Button
  1. Download the Sign-in button resource assets.
  2. Add the Sign-in button in your application’s layout:
    Button signInButton = findViewById(;

Important Information

  • In case the user is already logged in with a account in your app, you should save that information in your app’s database and use it to skip the login process when the user launches your app again.
  • If you wish to implement automatic login in your app and skip the login button flow, you may do so by directly implementing the signIn() function as illustrated in the third step below (code for Sign-in with Account).

Start the Login Flow

1. Execute the Sign-in Button Tap

In the Android activity’s onCreate method, add OnClickListener for the sign-in button.

 findViewById( View.OnClickListener() {
     public void onClick(View view) {
2. Check for GET_ACCOUNTS permission and Results
  • To check for GET_ACCOUNTS permission, add the following code to your onCreate method:
     protected void onCreate(Bundle savedInstanceState) {
         if (checkSelfPermission(Manifest.permission.GET_ACCOUNTS) != PackageManager.PERMISSION_GRANTED) {
             requestPermissions(new String[] {
         } else {
             // has GET_ACCOUNTS permission, can proceed with signin
             Log.d(TAG, "onCreate: Already has permission, proceed with signin");
  • To check for results, add the following code to your onRequestPermissionsResult:
     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.

Get User and Session Information

  • We also offer an advanced and more secure Auth Code Flow for Login integration.
  • This flow enables you to get detailed user and session information.
  • After you have completed the steps above, navigate to this section to implement Login using Auth Code flow.
  • If you only wish to fetch basic profile information after the user sign-in, you can continue with the steps below.

Continue with Basic Login Flow

3. Code for Sign-in with Account:
 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 = ""; // 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;
          getAuthToken(account, authTokenType, bundle, MainActivity.this, new OnTokenAcquired(), null);
      } else {

  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 account can be added in a system
          return accounts[0];
      return null;

  private void addNowggAccount() {
      try {
          Intent intent = new Intent();
          intent.setComponent(new ComponentName("", ""));
          intent.putExtra("resultReceiver", parcelResultReceiver(resultReceiver));
      } catch (ActivityNotFoundException e) {

  ResultReceiver parcelResultReceiver(ResultReceiver actualReceiver) {
      Parcel parcel = Parcel.obtain();
      actualReceiver.writeToParcel(parcel, 0);
      ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel);
      return receiverForSending;

  ResultReceiver resultReceiver = new ResultReceiver(new Handler(Looper.getMainLooper())) {
      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
          } else {
              // sign in failed
             Log.d(TAG, "onReceiveResult: sign in failed");
4. After the user signs in, you 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 {

  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 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) {
5. Validate the ID token for the user & get user details

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.

  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>() {
            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
            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()

  public interface BackendApiCallService {
    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;
    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;

    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.


  • If you get responses such as EXPIRED_TOKEN or INVALID_TOKEN, you can request a new token by calling the signIn function again.
  • To pass the currently signed-in user to a backend server, you should send the ID token to your backend server and validate it. See – Authenticate with a backend server.
Text copied to clipboard
Link copied to clipbord
Questions? Please reach out to us at