[Huawei Developers] HMS Community:
Overview

In this article, I will create a Directory android application using Kotlin in which I will integrate HMS Core kits such as HMS Account, AuthService, Identity Kit, Firebase Auth and Webrtc .

App will make use of android MVVM clean architecture using Jetpack components such as DataBinding, AndroidViewModel, Observer, LiveData and much more.

In this article we are going to implement DataBinding using Observable pattern.

FirebaseAuth Service Introduction

Firebase security applies Google’s internal expertise to easily build app sign-ins. Develop simple, multi-platform sign-in with Firebase Authentication. Build Fast For Any Device.

Firebase Authentication provides backend services, easy-to-use SDKs, and ready-made UI libraries to authenticate users to your app.

WebRTC Service Introduction

WebRTC is a free and open-source project providing web browsers and mobile applications with real-time communication via application programming interfaces.

Prerequisite

Huawei Phone EMUI 3.0 or later.

Non-Huawei phones Android 4.4 or later (API level 19 or higher).

HMS Core APK 4.0.0.300 or later

Android Studio

AppGallery Account

App Gallery Integration process

1. Sign In and Create or Choose a project on AppGallery Connect portal.

2. Navigate to Project settings and download the configuration file.

3. Navigate to General Information, and then provide Data Storage location.

App Development

Add Required Dependencies:

Launch Android studio and create a new project. Once the project is ready.

Add following dependency for HMS Kits

//HMS Kits

implementation 'com.huawei.agconnect:agconnect-core:1.5.0.300'

implementation 'com.huawei.hms:hwid:5.3.0.302'

implementation 'com.huawei.hms:identity:5.3.0.300'//Google Firebase

implementation platform('com.google.firebase:firebase-bom:28.4.1')

implementation 'com.google.firebase:firebase-analytics'

implementation 'com.google.firebase:firebase-auth'

implementation 'com.google.firebase:firebase-database'

implementation 'com.google.android.gms:play-services-auth:19.2.0'

implementation 'com.airbnb.android:lottie:4.1.0'

implementation 'com.mikhaellopez:circularimageview:4.3.0'

implementation 'com.kaopiz:kprogresshud:1.2.0'

implementation 'com.google.android.gms:play-services-ads:20.4.0' implementation 'com.github.bumptech.glide:glide:4.12.0'

annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

Navigate to the Gradle scripts folder and open build.gradle (project: app)

repositories {

google()

jcenter()

maven {url 'https://developer.huawei.com/repo/'}

}

dependencies {

classpath "com.android.tools.build:gradle:4.0.1"

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

Code Implementation

Created following package model, event, viewmodel.

ViewModel: The ViewModel makes it easy to update data changes on the UI.Create a package named viewmodel in your main folder.Then create a new file and name it LoginViewModel.kt along with their FactoryViewModelProviders.

MainActivity.kt:

package com.hms.directoryclass MainActivity : AppCompatActivity(), ActivityNavigation { private lateinit var viewModel: LoginViewModel

private lateinit var dataBinding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main) val viewModel: LoginViewModel by lazy {

val activity = requireNotNull(this) {}

ViewModelProviders.of(this, LoginViewModelFactory(activity.application))

.get(LoginViewModel::class.java)

} dataBinding.loginViewModel = viewModel

dataBinding.lifecycleOwner = this

viewModel.startActivityForResultEvent.setEventReceiver(this, this)

}

public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

viewModel.onResultFromActivity(requestCode, data)

super.onActivityResult(requestCode, resultCode, data)

}}

LoginViewModel.kt:

package com.hms.directory.viewmodel

@SuppressLint("StaticFieldLeak")

class LoginViewModel(application: Application) : AndroidViewModel(application), Observable { private val context = getApplication<Application>().applicationContext

private var mAuthManager: AccountAuthService? = null

private var mAuthParam: AccountAuthParams? = null val startActivityForResultEvent = LiveMessageEvent<ActivityNavigation>() fun login() {

val intent = Intent(context, OrderActivity::class.java)

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK

context.startActivity(intent) /* mAuthParam = AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)

.setIdToken()

.setAccessToken()

.createParams()

mAuthManager = AccountAuthManager.getService(Activity(), mAuthParam)

startActivityForResultEvent.sendEvent {

startActivityForResult(

mAuthManager?.signInIntent,

HMS_SIGN_IN

)

}*/

} fun onResultFromActivity(requestCode: Int, data: Intent?) {

when (requestCode) {

HMS_SIGN_IN -> {

val authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data)

onCompleteLogin(authAccountTask)

}

}

} private fun onCompleteLogin(doneTask: Task<AuthAccount>) {

if (doneTask.isSuccessful) {

val authAccount = doneTask.result

Log.d("LoginViewModel", "SigIn Success")

context.startActivity(Intent(context, ContactListActivity::class.java)) } else {

Log.d("LoginViewModel", "SigIn Error")

}

} override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {

} override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {

}}

ContactActivity.kt:

public class ContactListActivity extends AppCompatActivity { @override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_contact_list); // Load contacts from file

Contacts.loadData(this); // Set up recycler view and fill it with all the contacts

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.contact_list);

recyclerView.setAdapter(new ContactListAdapter(this, Contacts.LIST)); }

LoginFireBaseActivity.java

package com.hms.directory.app.call;import androidx.annotation.NonNull;

import androidx.annotation.Nullable;

import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.widget.Toast;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.tasks.OnCompleteListener;

import com.google.android.gms.tasks.Task;

import com.google.firebase.FirebaseApp;

import com.google.firebase.auth.AuthCredential;

import com.google.firebase.auth.AuthResult;

import com.google.firebase.auth.FirebaseAuth;

import com.google.firebase.auth.FirebaseUser;

import com.google.firebase.auth.GoogleAuthProvider;

import com.google.firebase.database.FirebaseDatabase;

import com.hms.corrierapp.R;

import com.hms.directory.app.call.models.User;import org.jetbrains.annotations.NotNull;public class LoginActivity extends AppCompatActivity { GoogleSignInClient mGoogleSignInClient;

int RC_SIGN_IN = 11;

FirebaseAuth mAuth;

FirebaseDatabase database; @override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_login_goole); mAuth = FirebaseAuth.getInstance();

if (mAuth.getCurrentUser() != null) {

goToNextActivity();

} database = FirebaseDatabase.getInstance(); GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)

.requestIdToken("1016048264402-439a9aamtpiajbgqeqg24qkum2bb7fmh.apps.googleusercontent.com")

.requestEmail()

.build(); mGoogleSignInClient = GoogleSignIn.getClient(this, gso); findViewById(R.id.loginBtn).setOnClickListener(new View.OnClickListener() {

@override

public void onClick(View view) {

Intent intent = mGoogleSignInClient.getSignInIntent();

startActivityForResult(intent, RC_SIGN_IN);

//startActivity(new Intent(LoginActivity.this, MainActivity.class));

}

});

} void goToNextActivity() {

startActivity(new Intent(LoginActivity.this, MainActivity.class));

finish();

} @override

protected void onActivityResult(int requestCode, int resultCode, @nullable @org.jetbrains.annotations.Nullable Intent data) {

super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_SIGN_IN) {

Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);

GoogleSignInAccount account = task.getResult();

authWithGoogle(account.getIdToken());

}

} void authWithGoogle(String idToken) {

AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null);

mAuth.signInWithCredential(credential)

.addOnCompleteListener(new OnCompleteListener<AuthResult>() {

@override

public void onComplete(@NonNull @notnull Task<AuthResult> task) {

if (task.isSuccessful()) {

FirebaseUser user = mAuth.getCurrentUser();

User firebaseUser = new User(user.getUid(), user.getDisplayName(), user.getPhotoUrl().toString(), "Unknown", 500);

database.getReference()

.child("profiles")

.child(user.getUid())

.setValue(firebaseUser).addOnCompleteListener(new OnCompleteListener<Void>() {

@override

public void onComplete(@NonNull @notnull Task<Void> task) {

if (task.isSuccessful()) {

startActivity(new Intent(LoginActivity.this, MainActivity.class));

finishAffinity();

} else {

Toast.makeText(LoginActivity.this, task.getException().getLocalizedMessage(), Toast.LENGTH_SHORT).show();

}

}

});

//Log.e("profile", user.getPhotoUrl().toString());

} else {

Log.e("err", task.getException().getLocalizedMessage());

}

}

});

}

}

Xml layout DataBinding

To include data binding in the UI, enclose all content with <layout></layout>.

The ViewModel is introduced to the layout in the <data></data> section, as shown. Ensure that the type value points to the specific folder that has the required ViewModel.

App Build Result

Tips and Tricks

Identity Kit displays the HUAWEI ID registration or sign-in page first. The user can use the functions provided by Identity Kit only after signing in using a registered HUAWEI ID.

Conclusion

In this article, we have learned how to integrate Huawei Identity Kit in Android application. After completely read this article user can easily implement Huawei ID in the Directory App android application using Kotlin.

Thanks for reading this article. Be sure to like and comment to this article, if you found it helpful. It means a lot to me.

References

HMS Docs:

https://developer.huawei.com/consum.../HMSCore-Guides/introduction-0000001050048870