DEV Community

Basavaraj Navi
Basavaraj Navi

Posted on

Pygmy collection application Part 1 (Account kit)

Introduction

Great things always take time. So this blog will be a little lengthy to convey you in a better way. I'll cover the following things

  1. Application basic introduction.

  2. Huawei Account kit integration.

While building this application I'll write series of article.

1. Application basic Introduction

What is the Pygmy Collection?
Let us understand the meaning.

Daily Deposit Scheme is a monetary deposit scheme introduced to help daily wage earners, small traders to inculcate saving habits and also as a way of funding their bigger capital requirements. In this scheme money can be deposited into an account on a daily basis. The amount may be as small as Rupees 20/-. The unique characteristic of this scheme is that an agent from the bank collects money to be deposited, on a daily basis, from the doorsteps of the account holder. It has provided many employment opportunities as agents.

Features of the scheme?
Choice to opt for Scheme Period from 12, 24, 36 months.
Amount as low as Rs.10 per day can be saved daily/weekly/monthly.
Benefit of this scheme is for small shopkeepers, salesmen, hawkers, etc.
No penalty even if the depositor is unable to pay a contribution regularly.
Deposit accounts can be closed prematurely subject to certain conditions.
Loans can be availed upto a maximum of 85% of the balance in the Pigmy account.
Nomination facility available.
No tax will be deducted for the interest on the deposit. (for Members Only)
The rates of interest are fixed by the Bank from time to time.
If the amount is withdrawn before 6 months then a premature deduction @ 5% will be made from the deposit amount.
Account Holder can withdraw the amount after 6 months without penalty. After completion of 1 year, interest at 2% p.a., Upto 2 year interest 3% p.a., for 3 years interest 5% p.a. will be paid to the account holder.
What does this application do?
This product aims to automate the Pygmy deposit scheme in credit societies for small savers. As we see a lot of fraudulent activities in payment collectives from collection agents, the idea is to design a full proof system which involves less human effort. Credit Societies can automate their collection process by introducing generic hand-held devices for our concern, android mobile, to their field Collection Agents i.e., Cash Collectors for better control, visibility and end-Customer experience. In this application the cash collector can view the customer list where he wants to go for collection with their detailed address and also the collection plan of the customer. Collection information is sent immediately to the Credit Society server and also the customer gets a confirmation message as soon as he makes payment to the cash collector with details of the total collection amount till date. Cash collector can view the complete collection sheet of each customer at the end of month so that he will cross check it with the system and the customer. This entire system will have a web-based background for maintaining depositional transactional history.

It is basically a finance application where agents will go and collect X amount of money from the shops. So that X amount will be saved in the shopkeeper's savings account. Even shopkeepers can also get the loan from the finance.

Nowadays India is moving towards digital but most of the Finances are still using manual processes, where they are going with pen and paper to collect the money. But in fact the shopkeepers are not getting any messages when they pay money to the finance agent, they are not able to see the balances. And in the pen and paperwork there is not much transparency. In the project we are trying to avoid all the manual work.

One tree can produce approximately 10k to 20k papers. Imagine if we make the process digital we can save trees and the environment will be safe.

Advantages

  1. Building an application to avoid pen and paperwork.
  2. Maintain transparency in the account information.
  3. Reduces the time and avoids fraud in the account.
  4. Handling security in the application.
  5. Scan and receive the amount.
  6. Send an amount received as a confirmation message to shopkeepers.
  7. Direction to all the shops when new agents join, there will not be much issue to travel to all the shops.
  8. Report day/week/month wise.
  9. Sending an everyday report to the manager.
  10. Save paper and save the environment.

Software and Hardware Requirement

OS: Windows/Ubuntu/Mac
RAM: 8 GB
Storage 40 GB
IDE: Android Studio
Language: Java
Home items detailed description

New Account opening

This is where a pygmy collection agent or manager of Finance can open a customer account using some customer basic information like First name, Last name, mobile number, Shop name, Account number(Currently its manual just to support existing finance business), Opening balance, Gender, Account type, Scheme type, address and document.

Collection

Agents can collect money from customers using account search or by scanning QR code. When an agent searches for an account number or scans the QR code all customer information has been shown and the agent can enter the amount and collect money.

Report

Here the agent can get the report by daily or monthly and custom report. He can get the report between dates and the report can be exported to pdf and it can be shared with the manager to make it transparent.

Add Member: New agents can be added in this section.

KYC update

If any customer KYC is pending, the agent can take a photo or select it from the gallery and get the type of document and document number and the agent can verify the customer KYC.

Employee profile

Agent detail will be shown in this screen.

Generate QR Code

Agents can generate QR codes for each customer and take a printout and paste in the shop. Whenever an agent goes for collection he doesn't need to ask for an account number and details; he can directly scan to get the customer details. The QR code will be saved under the eCollection folder inside the external storage.

Mini Statement

In this section the agent can get the mini statement for any customer. It shows the full report of that customer and he can export it as a pdf and share it with detailed transaction details with the customer to make it transparent.

2. Huawei Account Kit integration.

HMS (Huawei mobile services)

HMS core (Huawei Mobile Services) opens a wide range of services to application developers. It offers basic services such as logging in with Huawei ID, payment services and push notifications. In addition, HMS core provides various advanced features, such as, positioning, map, machine learning, and games that provide a better experience to Huawei users.

HMS Account Kit provides you with simple, secure, and quick sign-in and authorization functions. Instead of entering accounts and passwords and waiting for authentication, users can just tap the Sign in with HUAWEI ID button to quickly and securely sign in to your app with their HUAWEI IDs.

Using Huawei Account Kit, users can quickly and securely sign in to the application, and the first-time user needs to authorize the application and then, the user has the ability to sign in to the app with one tap using Huawei ID. Huawei facilitates app developers to use the Account Kit on multiple device types such as phones, tablets, and smart screens.

Prerequisite

AppGallery Account
Android Studio 3.X
SDK Platform 19 or later
Gradle 4.6 or later
HMS Core (APK) 4.0.0.300 or later
Huawei Phone EMUI 3.0 or later
Non-Huawei Phone Android 4.4 or later
Service integration on AppGallery.

  1. We need to register as a developer account in AppGallery Connect
  2. Create an app by referring to Creating a Project and Creating an App in the Project
  3. Set the data storage location based on the current location.
  4. Enabling Account kit Service on AppGallery.
  5. Generating a Signing Certificate Fingerprint.
  6. Configuring the Signing Certificate Fingerprint.
  7. Get your agconnect-services.json file to the app root directory. ** Client development **
  8. Create android project in android studio IDE.
  9. Add the maven URL inside the repositories of buildscript and
allprojects respectively (project level build.gradle file).
maven { url 'https://developer.huawei.com/repo/' }
Enter fullscreen mode Exit fullscreen mode
  1. Add the classpath inside the dependency section of the project level build.gradle file.

classpath 'com.huawei.agconnect:agcp:1.5.2.300'

Enter fullscreen mode Exit fullscreen mode
  1. Add the plugin in the app-level build.gradle file.
apply plugin: 'com.huawei.agconnect
Enter fullscreen mode Exit fullscreen mode
  1. Add the below library in the app-level build.gradle file dependencies section.
implementation 'com.huawei.hms:hwid:6.1.0.300'
Enter fullscreen mode Exit fullscreen mode
  1. Add all the below permission in the AndroidManifest.xml.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Enter fullscreen mode Exit fullscreen mode
  1. Sync the project.

Let us write code.


 private void huaweiLogin() {
        AccountAuthParams authParams = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM).setIdToken().createParams();
        AccountAuthService service = AccountAuthManager.getService(LoginActivity.this, authParams);
        startActivityForResult(service.getSignInIntent(), 8888);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        // Process the authorization result and obtain an ID token from AuthAccount.
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 8888) {
            Task<AuthAccount> authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data);
            if (authAccountTask.isSuccessful()) {
                // The sign-in is successful, and the user's ID information and ID token are obtained.
                AuthAccount authAccount = authAccountTask.getResult();
                Log.i(TAG, "idToken:" + authAccount.getIdToken());
                Toast.makeText(this, "Welcome " + authAccount.getDisplayName() + " We need more data for registration please help us with it.", Toast.LENGTH_LONG).show();
                PygmyAgentEntity agent = PygmyDatabase.getDatabase(LoginActivity.this).agentDao().findAgent(authAccount.getEmail());
                if (agent == null) {
                    PygmyNavigator.navigateToRegisterScreenWithData(this, authAccount.getDisplayName(), authAccount.getEmail());
                } else {
                    UserDataUtils.saveUserPhoneNumber(this, agent.getMobileNumber());
                    UserDataUtils.saveUserPassword(this, agent.getPassword());
                    UserDataUtils.saveUserLoggedIn(this, true);
                    UserDataUtils.saveUserData(this, new Gson().toJson(agent));
                    PygmyNavigator.navigateToWelcomeScreen(this);
                    finish();
                }
            } else {
                // The sign-in failed. No processing is required. Logs are recorded for fault locating.
                Log.e(TAG, "sign in failed : " + ((ApiException) authAccountTask.getException()).getStatusCode());
            }
        }
    }
Enter fullscreen mode Exit fullscreen mode

Full code

LoginActivity.java

package com.shea.pygmycollection.ui.activities;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.gson.Gson;
import com.huawei.agconnect.crash.AGConnectCrash;
import com.huawei.hmf.tasks.Task;
import com.huawei.hms.ads.AdListener;
import com.huawei.hms.ads.AdParam;
import com.huawei.hms.ads.BannerAdSize;
import com.huawei.hms.ads.HwAds;
import com.huawei.hms.ads.banner.BannerView;
import com.huawei.hms.common.ApiException;
import com.huawei.hms.support.account.AccountAuthManager;
import com.huawei.hms.support.account.request.AccountAuthParams;
import com.huawei.hms.support.account.request.AccountAuthParamsHelper;
import com.huawei.hms.support.account.result.AuthAccount;
import com.huawei.hms.support.account.service.AccountAuthService;
import com.huawei.hms.support.hwid.ui.HuaweiIdAuthButton;
import com.shea.pygmycollection.R;
import com.shea.pygmycollection.data.database.PygmyDatabase;
import com.shea.pygmycollection.data.database.entities.PygmyAgentEntity;
import com.shea.pygmycollection.huaweianalytics.AnalyticUtils;
import com.shea.pygmycollection.huaweianalytics.HuaweiAnalyticsClient;
import com.shea.pygmycollection.huaweianalytics.HuaweiEventParams;
import com.shea.pygmycollection.huaweianalytics.HuaweiLog;
import com.shea.pygmycollection.utils.PygmyNavigator;
import com.shea.pygmycollection.utils.UserDataUtils;

import java.util.ArrayList;
import java.util.List;

import static maes.tech.intentanim.CustomIntent.customType;


public class LoginActivity extends AppCompatActivity implements View.OnClickListener {
    private static final int MULTIPLE_PERMISSIONS = 2000;
    private static final int PERMISSION_REQUESTS = 100;
    Button loginBtn;
    EditText mobileNumberET;
    EditText passwordET;
    TextView registerHereBtn;
    HuaweiIdAuthButton huaweiLogin;
    public static final String TAG = LoginActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        mobileNumberET = findViewById(R.id.mobileNumberET);
        passwordET = findViewById(R.id.passwordET);
        loginBtn = findViewById(R.id.loginBtn);
        registerHereBtn = findViewById(R.id.registerHereBtn);
        huaweiLogin = findViewById(R.id.huaweiLogin);
        loginBtn.setOnClickListener(this);
        registerHereBtn.setOnClickListener(this);
        huaweiLogin.setOnClickListener(this);

        // Initialize the HUAWEI Ads SDK.
        HwAds.init(this);
        // Obtain BannerView.
        BannerView bannerView = findViewById(R.id.hw_banner_view);
        // Set the ad unit ID and ad dimensions. "testw6vs28auh3" is a dedicated test ad unit ID.
        bannerView.setAdId("testw6vs28auh3");
        bannerView.setBannerAdSize(BannerAdSize.BANNER_SIZE_360_57);
        // Set the refresh interval to 30 seconds.
        bannerView.setBannerRefresh(30);
        // Create an ad request to load an ad.
        AdParam adParam = new AdParam.Builder().build();
        bannerView.loadAd(adParam);
        bannerView.setAdListener(adListener);


        if (!UserDataUtils.getUserPhoneNumber(this).isEmpty()) {
            mobileNumberET.setText(UserDataUtils.getUserPhoneNumber(this));
        }
        if (!UserDataUtils.getUserPassword(this).isEmpty()) {
            mobileNumberET.setText(UserDataUtils.getUserPassword(this));
        }

        AnalyticUtils.logHuaweiAnalyticEvent(new HuaweiLog()
                .setScreenName(HuaweiEventParams.ScreenName.LOGIN_SCREEN)
                .setDescription(HuaweiEventParams.Description.OPEN_LOGIN_SCREEN)
                .setEventName(HuaweiEventParams.EventName.OPEN)
                .setUiElementName(HuaweiEventParams.UiElementName.GALLARY_BUTTON)
        );

        //checkPermissions();

        if (!this.allPermissionsGranted()) {
            this.getRuntimePermissions();
        }
    }

    public boolean isPermissionGranted() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(android.Manifest.permission.CALL_PHONE)
                    == PackageManager.PERMISSION_GRANTED) {
                Log.v("TAG", "Permission is granted");
                return true;
            } else {

                Log.v("TAG", "Permission is revoked");
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 1);
                return false;
            }
        } else { //permission is automatically granted on sdk<23 upon installation
            Log.v("TAG", "Permission is granted");
            return true;
        }
    }

    private String[] getRequiredPermissions() {
        try {
            PackageInfo info =
                    this.getPackageManager()
                            .getPackageInfo(this.getPackageName(), PackageManager.GET_PERMISSIONS);
            String[] ps = info.requestedPermissions;
            if (ps != null && ps.length > 0) {
                return ps;
            } else {
                return new String[0];
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            return new String[0];
        }
    }

    private boolean allPermissionsGranted() {
        for (String permission : this.getRequiredPermissions()) {
            if (!LoginActivity.isPermissionGranted(this, permission)) {
                return false;
            }
        }
        return true;
    }

    private void getRuntimePermissions() {
        List<String> allNeededPermissions = new ArrayList<>();
        for (String permission : this.getRequiredPermissions()) {
            if (!LoginActivity.isPermissionGranted(this, permission)) {
                allNeededPermissions.add(permission);
            }
        }

        if (!allNeededPermissions.isEmpty()) {
            ActivityCompat.requestPermissions(
                    this, allNeededPermissions.toArray(new String[0]), LoginActivity.PERMISSION_REQUESTS);
        }
    }

    private static boolean isPermissionGranted(Context context, String permission) {
        if (ContextCompat.checkSelfPermission(context, permission)
                == PackageManager.PERMISSION_GRANTED) {
            Log.i(TAG, "Permission granted: " + permission);
            return true;
        }
        Log.i(TAG, "Permission NOT granted: " + permission);
        return false;
    }

    private AdListener adListener = new AdListener() {
        @Override
        public void onAdLoaded() {
            // Called when an ad is loaded successfully.
        }

        @Override
        public void onAdFailed(int errorCode) {
            // Called when an ad fails to be loaded.
        }

        @Override
        public void onAdOpened() {
            // Called when an ad is opened.
        }

        @Override
        public void onAdClicked() {
            // Called when an ad is clicked.
        }

        @Override
        public void onAdLeave() {
            // Called when an ad leaves an app.
        }

        @Override
        public void onAdClosed() {
            // Called when an ad is closed.
        }
    };

    public void slideUp(View view) {
        startActivity(new Intent(LoginActivity.this, WelcomeActivity.class));
        customType(LoginActivity.this, "bottom-to-up");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.loginBtn:
                login();
                break;
            case R.id.registerHereBtn:
                PygmyNavigator.navigateToRegisterScreen(this);
                break;
            case R.id.huaweiLogin:
                huaweiLogin();
                break;
        }
    }

    public void login() {
        if (mobileNumberET.getText().toString().length() == 0) {
            Toast.makeText(this, "Please enter mobile number", Toast.LENGTH_SHORT).show();
            // Add a key-value pair of the string type.
            AGConnectCrash.getInstance().setCustomKey("mobileNumber", "Phone number is empty");
            return;
        }

        if (mobileNumberET.getText().toString().length() != 10) {
            Toast.makeText(this, "Please enter valid mobile number", Toast.LENGTH_SHORT).show();
            AGConnectCrash.getInstance().setCustomKey("InvalidNumber", 10);
            return;
        }

        if (passwordET.getText().toString().length() == 0) {
            Toast.makeText(this, "Please enter password", Toast.LENGTH_SHORT).show();
            return;
        }

        if (passwordET.getText().toString().length() != 6) {
            Toast.makeText(this, "Please enter valid password", Toast.LENGTH_SHORT).show();
            return;
        }

        PygmyAgentEntity agent = PygmyDatabase.getDatabase(LoginActivity.this).agentDao().findAgent(mobileNumberET.getText().toString());
        if (agent == null) {
            Toast.makeText(this, "Agent not available", Toast.LENGTH_SHORT).show();
            return;
        } else if (!agent.getPassword().equals(passwordET.getText().toString())) {
            Toast.makeText(this, "Wrong password", Toast.LENGTH_SHORT).show();
            return;
        } else {
            UserDataUtils.saveUserPhoneNumber(this, mobileNumberET.getText().toString());
            UserDataUtils.saveUserPassword(this, passwordET.getText().toString());
            UserDataUtils.saveUserLoggedIn(this, true);
            UserDataUtils.saveUserData(this, new Gson().toJson(agent));
            PygmyNavigator.navigateToWelcomeScreen(this);
            finish();
        }

       /* if (mobileNumberET.getText().toString().equalsIgnoreCase("9731276143") && passwordET.getText().toString().equalsIgnoreCase("123456")) {
            //Toast.makeText(this, "Valid user", Toast.LENGTH_SHORT).show();
            UserDataUtils.saveUserPassword(this, mobileNumberET.getText().toString());
            UserDataUtils.saveUserPassword(this, passwordET.getText().toString());
            UserDataUtils.saveUserLoggedIn(this, true);
            PygmyNavigator.navigateToWelcomeScreen(this);
        } else {
            Toast.makeText(this, "Invalid user", Toast.LENGTH_SHORT).show();
        }*/
    }

    private void huaweiLogin() {
        AccountAuthParams authParams = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM).setIdToken().createParams();
        AccountAuthService service = AccountAuthManager.getService(LoginActivity.this, authParams);
        startActivityForResult(service.getSignInIntent(), 8888);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        // Process the authorization result and obtain an ID token from AuthAccount.
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 8888) {
            Task<AuthAccount> authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data);
            if (authAccountTask.isSuccessful()) {
                // The sign-in is successful, and the user's ID information and ID token are obtained.
                AuthAccount authAccount = authAccountTask.getResult();
                Log.i(TAG, "idToken:" + authAccount.getIdToken());
                Toast.makeText(this, "Welcome " + authAccount.getDisplayName() + " We need more data for registration please help us with it.", Toast.LENGTH_LONG).show();
                PygmyAgentEntity agent = PygmyDatabase.getDatabase(LoginActivity.this).agentDao().findAgent(authAccount.getEmail());
                if (agent == null) {
                    PygmyNavigator.navigateToRegisterScreenWithData(this, authAccount.getDisplayName(), authAccount.getEmail());
                } else {
                    UserDataUtils.saveUserPhoneNumber(this, agent.getMobileNumber());
                    UserDataUtils.saveUserPassword(this, agent.getPassword());
                    UserDataUtils.saveUserLoggedIn(this, true);
                    UserDataUtils.saveUserData(this, new Gson().toJson(agent));
                    PygmyNavigator.navigateToWelcomeScreen(this);
                    finish();
                }
            } else {
                // The sign-in failed. No processing is required. Logs are recorded for fault locating.
                Log.e(TAG, "sign in failed : " + ((ApiException) authAccountTask.getException()).getStatusCode());
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case MULTIPLE_PERMISSIONS: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {  // permissions granted.
                    //getCallDetails(); // Now you call here what ever you want :)
                } else {
                    String perStr = "";
                    for (String per : permissions) {
                        perStr += "\n" + per;
                    }   // permissions list of don't granted permission
                }
                return;
            }
        }
    }


    String[] permissions = new String[]{
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA,
            Manifest.permission.MANAGE_EXTERNAL_STORAGE,
            Manifest.permission.CALL_PHONE
    };

    private boolean checkPermissions() {
        int result;
        List<String> listPermissionsNeeded = new ArrayList<>();

        for (String p : permissions) {
            result = ContextCompat.checkSelfPermission(getApplicationContext(), p);
            if (result != PackageManager.PERMISSION_GRANTED) {
                listPermissionsNeeded.add(p);
            }
        }

        if (!listPermissionsNeeded.isEmpty()) {
            ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), MULTIPLE_PERMISSIONS);
            return false;
        }
        return true;
    }

}
Enter fullscreen mode Exit fullscreen mode

activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:hwads="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.activities.LoginActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="8dp"
        android:fontFamily="@font/montserrat_bold"
        android:text="eCollection."
        android:textColor="@color/colorText"
        android:textSize="40sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:fontFamily="@font/montserrat_light"
        android:text="Make everything digital, Save paper"
        android:textColor="@color/colorText"
        android:textSize="16sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="8dp"
        android:visibility="visible"
        android:background="@drawable/ic_illustration_login"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2" />

    <EditText
        android:id="@+id/mobileNumberET"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="24dp"
        android:layout_marginEnd="8dp"
        android:background="@drawable/bg_txt_username"
        android:fontFamily="@font/montserrat_semibold"
        android:hint="Mobile Number"
        android:inputType="number"
        android:paddingLeft="60dp"
        android:textColor="@color/colorText"
        android:textSize="40px"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

    <EditText
        android:id="@+id/passwordET"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:background="@drawable/bg_txt_password"
        android:fontFamily="@font/montserrat_semibold"
        android:hint="Password"
        android:inputType="textPassword"
        android:paddingLeft="60dp"
        android:textColor="@color/colorText"
        android:textSize="40px"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/mobileNumberET" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:fontFamily="@font/montserrat_light"
        android:text="Forgot your password?"
        android:textColor="@color/colorText"
        android:textSize="32px"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.883"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/passwordET" />

    <Button
        android:id="@+id/loginBtn"
        android:layout_width="86dp"
        android:layout_height="86dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="8dp"
        android:background="@drawable/bg_btn_login"
        android:onClick="slideUp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.951"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView3" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="48dp"
        android:fontFamily="@font/montserrat_semibold"
        android:onClick="slideUp"
        android:text="Sign in"
        android:textColor="@color/colorText"
        android:textSize="48px"
        app:layout_constraintEnd_toStartOf="@+id/loginBtn"
        app:layout_constraintTop_toBottomOf="@+id/textView3" />

    <TextView
        android:id="@+id/textView5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="48dp"
        android:layout_marginEnd="20dp"
        android:fontFamily="@font/montserrat_semibold"
        android:onClick="slideUp"
        android:text="Sign in with Huawei"
        android:textColor="@color/colorText"
        android:textSize="48px"
        android:visibility="gone"
        app:layout_constraintEnd_toStartOf="@+id/huaweiLogin"
        app:layout_constraintTop_toBottomOf="@+id/textView4" />

    <com.huawei.hms.support.hwid.ui.HuaweiIdAuthButton
        android:id="@+id/huaweiLogin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="50dp"
        android:layout_marginEnd="8dp"
        android:onClick="slideUp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView4" />


    <TextView
        android:id="@+id/registerHereBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="16dp"
        android:fontFamily="@font/montserrat_light"
        android:text="Don't you have an account? Create"
        android:textColor="@color/colorText"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />


    <com.huawei.hms.ads.banner.BannerView
        android:id="@+id/hw_banner_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        hwads:adId="testw6vs28auh3"
        hwads:bannerSize="BANNER_SIZE_360_57"
        android:layout_marginStart="8dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="8dp"
        android:visibility="gone"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2"/>

</androidx.constraintlayout.widget.ConstraintLayout>
Enter fullscreen mode Exit fullscreen mode

Result

Image description

Image description

Tips and Tricks

  1. Make sure you are already registered as a Huawei developer.
  2. Set min SDK version to 21 or later, otherwise you will get AndriodManifest to merge issue.
  3. Make sure you have added the agconnect-services.json file to the app folder.
  4. Make sure you have added the SHA-256 fingerprint without fail.
  5. Make sure all the dependencies are added properly.

Conclusion

In this section, you saw the main flow to integrate the Huawei Account Kit in your mobile application using Android Studio and Java. Other than the Account Kit, HMS core provides a wider range of services to enhance the user experience with the Huawei platform. We have learnt the steps to create projects and steps to integrate the account kit.

References

Account Kit - Official document
Account Kit - Code lab

Top comments (0)