Use Keyring for Sign-in Across Different Apps and Platforms - Huawei Developers

It's common for an app developer to develop multiple apps across different platforms. However, an issue that arises is that when signing in to different apps or the same app across different platforms on the same device, users usually needs to repeatedly enter their account name and password even if the same account is used, which has a negative impact on user experience.
Keyring provides developers with the ability to share user authentication credentials across different apps and app platforms, thus creating a seamless sign-in experience for users. In this article I will explain how to integrate Keyring and implement cross-platform & cross-app sign-in.
Preparations​
Before integrating the Keyring SDK, you'll need to perform the following preparations:
1. Configure app information in AppGallery Connect.
2. Create an Android Studio project and configure the Maven repository address. If you are using Android Studio, you can integrate the HMS Core SDK via the Maven repository. Before you start developing an app, integrate the HMS Core SDK into your Android Studio project.
3. Before building the APK, configure the obfuscation configuration file to prevent the HMS Core SDK from being obfuscated.
Integrating the Keyring SDK​
After completing the preparations, let's look at how to integrate the Keyring SDK.
1. Open the app-level build.gradle file in the project.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
2. Add a build dependency on the Keyring SDK in the dependencies block.
Find the dependencies block in the build.gradle file, add a dependency on the Keyring SDK in the block, and click Sync Now to make Android Studio synchronize the project.
Code:
dependencies{
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation "com.huawei.hms:keyring-credential:6.1.1.302"
}
Scenario Simulated by the Sample Code​
​The sample code provides two sample apps, which are App1 and App2.
App1 simulates the sign-in operation, and calls APIs of Keyring to save the user sign-in credentials. App1 then shares these credentials with App2.
App2 calls APIs of Keyring to query available credentials, and calls the getContent API to obtain the user's sign-in password.
To make the sample code work, we need to create two apps in AppGallery Connect, download the agconnect-services.json files of the two apps, and place the files in the corresponding Android Studio projects of App1 and App2. Refer to "Preparations" for details.
Preparing Information​
We need to collect the information listed below for use later on.
We need to set the sharing relationship in the code for App1 and App2. Therefore, we need to query and record the package names and signing certificate fingerprints of App1 and App2. For details about how to obtain the signing certificate fingerprint, please refer to "Preparations."
Development Practice​
1. Configure App1 to save user credentials using the Keyring SDK.
App1 simulates the app sign-in operation, the sample project has only one activity, that is, MainActivity, in which most code lines are used to implement the sign-in screen and basic sign-in logic. This activity has a member object of the CredentialClient type, which is the operation object for accessing Keyring and is initialized in the onCreate method of the activity.
Code:
mCredentialClient = CredentialManager.getCredentialClient(this);
Then, implement the login method for the onClick method of the Login button.
Code:
private void login(View view) {
if (!checkInput()) {
return;
}
String username = mUsername.getText().toString().trim();
String password = mPassword.getText().toString().trim();
// connect server to login.
saveCredential(username, password,
"app2", "com.huawei.hms.keyring.sample.app2",
"XX:XX:XX:XX:XX:XX",
true);
}
At the beginning of the login method, the checkInput method is called to check the validity of the user name and password in the input text boxes. In most cases, the service logic will connect to the background and use the user name and password for sign-in. The sample code does not include the code for implementing this. Here, we assume that the user name and password are correct, and that sign-in is performed successfully in the background.
The next step is to call the saveCredential method to save the credentials. The saveCredential method is a simple method encapsulated to highlight the input parameters. Such input parameters include the user name, password, information related to the sharing target app. It also includes the configuration specifying whether user authentication is required during credential reading.
App2's package name and certificate fingerprint recorded earlier will be used here. When calling the saveCredential method, we need to pass the package name and certificate fingerprint of App2 to the method as parameters.
Code:
private void saveCredential(String username, String password,
String sharedToAppName, String sharedToAppPackage,
String sharedToAppCertHash, boolean userAuth) {
AndroidAppIdentity app2 = new AndroidAppIdentity(sharedToAppName,
sharedToAppPackage, sharedToAppCertHash);
List<AppIdentity> sharedAppList = new ArrayList<>();
sharedAppList.add(app2);
Credential credential = new Credential(username,
CredentialType.PASSWORD, userAuth,
password.getBytes());
credential.setDisplayName("nickname_" + username);
credential.setSharedWith(sharedAppList);
credential.setSyncable(true);
mCredentialClient.saveCredential(credential, new CredentialCallback<Void>() {
@Override
public void onSuccess(Void unused) {showMessage("save credential to Keyring success");}
@Override
public void onFailure(long errorCode, CharSequence description) {
showMessage("save to Keyring failed" + " ====" + errorCode + ":" + description);
}
});
}
In the saveCredential method, we use the package name and certificate fingerprint of App2 to create an app object app2. Then, we place this object in sharedAppList of AppIdentity and use the list as a parameter of the credential object. After that, we create a password-type credential object, and call a series of set methods for this object to set the sharing app list and other configurations of the credentials. Finally, we call the saveCredential method of the Keyring operation object mCredentialClient to save the credentials. We also need to set the callback methods called when credentials are successfully saved or failed to be saved.
We have now saved the credentials in Keyring.
2. Configure App2 to use the Keyring SDK to query and read credentials.
App2 simulates the sign-in operation of another app made by the same developer. App2 can use the Keyring SDK to query credentials saved by itself earlier and credentials shared with it by the specified app, and read the credential content for seamless sign-in. App2 also has only one activity, that is, MainActivity, which simulates the sign-in screen. App2, like App1, also defines a member object mCredentialClient of the CredentialClient type and uses the object as the operation object for accessing Keyring. The operation object is also initialized in the onCreate method of the activity. The queryCredential method is called at the end of the onCreate method to query available credentials.
Now, let's look at how to implement the queryCredential method.
Code:
private void queryCredential() {
final AndroidAppIdentity app1 = new AndroidAppIdentity("app1",
"com.huawei.hms.keyring.sample.app1",
"XX:XX:XX:XX:XX:XX"
);
List<AppIdentity> trustedOwnerList = new ArrayList<>();
trustedOwnerList.add(app1);
mCredentialClient.findCredential(trustedOwnerList, new CredentialCallback<List<Credential>>() {
@Override
public void onSuccess(List<Credential> credentials) {
if (credentials.isEmpty()) {
noAvailableCredential();
} else {
MainActivity.this.setCredentialList(credentials);
}
}
@Override
public void onFailure(long errorCode, CharSequence description) {
noAvailableCredential();
}
private void noAvailableCredential(){showMessage("no shared credential");}
});
}
When preparing for SDK integration earlier, we recorded the package name and certificate fingerprint of App1. Now we use the information in the queryCredential method to create an AndroidAppIdentity object representing App1. Then, place the object in trustedOwnerList of AppIdentity.
Next, we call the findCredential method of the Keyring operation object mCredentialClient and pass trustedOwnerList and the result callback to the method. The findCredential method will query and list credentials that are available to this app. Such credentials include those stored by this app and those shared with this app by other apps specified in trustedOwnerList. In the sample code of App2, the findCredential method will query credentials saved by App2 and credentials shared with App2 by App1.
Available credentials exist if the onSuccess method is called and the credentials parameter is not empty. Then, the setCredentialList method will be called to display the credential list in the RecyclerView component on the app screen.
The choose method in the CredentialHolder class will be called if one of the credentials displayed on the screen is chosen. In the choose method, the selected credential object will be assigned to the member object mChooseCredential. After the user taps the Login button on the app screen, the login method will be called.
Code:
private void login(View v) {
if (mChooseCredential == null) {
showMessage("please_choose_account");
return;
}
mChooseCredential.getContent(new CredentialCallback<byte[]>() {
@Override
public void onSuccess(byte[] bytes) {
// String password = new String(bytes);
showMessage("Login success");
}
@Override
public void onFailure(long l, CharSequence charSequence) {
showMessage("Get password failed");
}
});
}
In the login method, if mChooseCredential is not empty, the getContent method of the chosen credential object will be called to obtain the credential content. When calling the getContent method, we also need to pass the result callback to it.
The bytes parameter in the onSuccess method indicates the credential content, that is, the user sign-in password saved by App1. In a real app, we can directly use the password for sign-in, creating a seamless sign-in experience.
That's all for this tutorial. You can visit the Keyring official website for more information.

Does it support for quickApp?

Basavaraj.navi said:
Does it support for quickApp?
Click to expand...
Click to collapse
Yes, it supports quick apps.

Related

Getting Started with Huawei's Safety Detect SDK

Today we're going to go through getting started with Huawei's Safety Detect SDK. We'll talk about how to get set up, as well as some basic examples of how to use it.
What is Huawei Safety Detect?
Safety Detect builds robust security capabilities, including system integrity check (SysIntegrity), app security check (AppsCheck), malicious URL check (URLCheck), fake user detection (UserDetect), and malicious Wi-Fi detection (WifiDetect), into your app, effectively protecting it against security threats.
Preparation
First up, make sure you have a Huawei Developer Account. This process can take a couple days, and you'll need one to use this SDK, so be sure to start that as soon as possible. You can sign up at https://developer.huawei.com.
Next, you'll want to obtain the SHA-256 representation of your app's signing key. If you don't have a signing key yet, be sure to create one before continuing. To obtain your signing key's SHA-256, you'll need to use Keytool which is part of the JDK installation. Keytool is a command-line program. If you're on Windows, open CMD. If you're on Linux, open Terminal.
On Windows, you'll need to "cd" into the directory containing the Keytool executable. For example, if you have JDK 1.8 v231 installed, Keytool will be located at the following path:
Code:
C:\Program Files\Java\jdk1.8.0_231\bin\
Once you find the directory, "cd" into it:
Code:
C: #Make sure you're in the right drive
cd C:\Program Files\Java\jdk1.8.0_231\bin\
Next, you need to find the location of your keystore. Using Android's debug keystore as an example, where the Android SDK is hosted on the "E:" drive in Windows, the path will be as follows:
Code:
E:\AndroidSDK\.android\debug.keystore
(Keytool also supports JKS-format keystores.)
Now you're ready to run the command. On Windows, it'll look something like this:
Code:
keytool -list -v -keystore E:\AndroidSDK\.android\debug.keystore
On Linux, the command should be similar, just using UNIX-style paths instead.
Enter the keystore password, and the key name (if applicable), and you'll be presented with something similar to the following:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Make note of the SHA256 field.
SDK Setup
Now we're ready to add the Safety Detect SDK to your Android Studio project. Go to your Huawei Developer Console and click the HUAWEI AppGallery tile. Agree to the terms of use if prompted.
Click the "My projects" tile here. If you haven't already added your project to the AppGallery, add it now. You'll be asked for a project name. Make it something descriptive so you know what it's for.
Now, you should be on a screen that looks something like the following:
Click the "Add app" button. Here, you'll need to provide some details about your app, like its name and package name.
Once you click OK, some SDK setup instructions will be displayed. Follow them to get everything added to your project. You'll also need to add the following to the "dependencies" section of your app-level build.gradle file:
Code:
implementation 'com.huawei.hms:safetydetect:4.0.3.300'
If you ever need to come back to these instructions, you can always click the "Add SDK" button after "App information" on the "Project setting" page.
Now you should be back on the "Project setting" page. Find the "SHA-256 certificate fingerprint" field under "App information," click the "+" button, and paste your SHA-256.
Now, go to the Manage APIs tab on the "Project setting" page. Scroll down until you find "Safety Detect" and make sure it's enabled.
Now, if you're using obfuscation in your app, you'll need to whitelist a few things for HMS to work properly.
For ProGuard:
Code:
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
For AndResGuard:
Code:
"R.string.hms*",
"R.string.agc*",
"R.string.connect_server_fail_prompt_toast",
"R.string.getting_message_fail_prompt_toast",
"R.string.no_available_network_prompt_toast",
"R.string.third_app_*",
"R.string.upsdk_*",
"R.layout.hms*",
"R.layout.upsdk_*",
"R.drawable.upsdk*",
"R.color.upsdk*",
"R.dimen.upsdk*",
"R.style.upsdk*
That's it! The Safety Detect SDK should now be available in your project.
Basic Usage
Now that the SDK is set up, it's time to actually use it. Safety Detect currently has 5 APIs you can use: SysIntegrity, AppsCheck, URLCheck, UserDetect, and WifiDetect.
The first thing you'll want to do when using any of these APIs is to check whether HMS is actually available:
Code:
if (HuaweiApiAvailability.getInstance().isHuaweiMobileServicesAvailable(context) == ConnectionResult.SUCCESS) {
//HMS is available
} else {
//HMS isn't available. Act accordingly
}
Without HMS, these APIs won't work. Prompt the user to update/install HMS, or simply silently fail, depending on your needs.
SysIntegrity
The SysIntegrity API is similar to Google's SafetyNet. You can use it to check if the current device is insecure (e.g. is rooted). If your app relies heavily on running in a secure environment, you can use this check and refuse to run if it fails.
To use SysIntegrity, you need a few things: a nonce value, your app ID, and an active internet connection. The nonce value should be a secret, needs to be at least 16 bytes long, and can only be used once. It'll be contained in the SysIntegrity check result, so you can verify that the result is genuine.
You can find your app ID under the "App information" section on the "Project Setting" page.
Here's a quick example in Kotlin of how to set up the integrity check request:
Code:
fun checkSysIntegrity() {
val client = SafetyDetect.getClient(context)
//Ideally, you'd use a better nonce generation method, either from your own server
//or some other secure environment.
val nonce = "NONCE_${System.currentTimeMillis()}".toByteArray()
//You can find your APP_ID under "App information" in your project's settings on the AppGallery Developer Console.
val task = client.sysIntegrity(nonce, "APP_ID")
task.addOnSuccessListener {
val result = it.result
//Process the result. It will be in the JWS (JSON Web Signature) format, containing a header, payload, and signature.
//The header contains a certificate chain that should be verified against the HUAWEI CGB Root CA.
//Make sure the domain name of the leaf certificate in the certificate chain is `sysintegrity.platform.hicloud.com`.
//Verify the signature.
//Next, check the payload for the nonce and result. The payload format is something like the following:
/*
{
"advice":"RESTORE_TO_FACTORY_ROM",
"apkCertificateDigestSha256":[
"yT5JtXRgeIgXssx1gQTsMA9GzM9ER4xAgCsCC69Fz3I="
],
"apkDigestSha256":"6Ihk8Wcv1MLm0O5KUCEVYCI/0KWzAHn9DyN38R3WYu8=",
"apkPackageName":"com.huawei.hms.safetydetectsample",
"basicIntegrity":false,
"nonce":"R2Rra24fVm5xa2Mg",
"timestampMs":1571708929141
}
*/
//If basicIntegrity is false, then the check failed and you should handle it appropriately.
//You can use the following library to parse the JWS string: https://mvnrepository.com/artifact/com.nimbusds/nimbus-jose-jwt
}
task.addOnFailureListener {
//The request failed. If `it is ApiException`, you might be able to get more details about why the failure occurred.
//Note that this doesn't imply that the device has failed an integrity check. It merely means the check itself has failed.
//You can choose to retry, or simply ignore the error.
}
}
Put that code in a helper Class, and call it as needed. It is an asynchronous API, so make sure you account for that.
AppsCheck
The functionality of AppsCheck is pretty simple. It'll return a list of apps installed on the current device that are potentially malicious. You can use the result to decide on whether or not you want to restrict features, or prevent your app from running.
To get you up and running, a basic example is provided below. You can use it as the base for your implementation.
Code:
fun checkApps() {
val client = SafetyDetect.getClient(context)
val task = client.maliciousAppsList
task.addOnSuccessListener {
if (it.rtnCode == CommonCode.OK) {
//The request truly succeeded
//An ArrayList<MaliciousAppsData>
val apps = it.maliciousAppsList
if (apps.isEmpty()) {
//No malicious apps were found
} else {
//HMS found at least one potentially malicious app
apps.forEach {
//The package name of the potentially malicious app
val packageName = it.apkPackageName
//The SHA-256 of the potentially malicious app
val sha256 = it.apkSha256
//The category of the potentially malicious app
//Constants are defined in the AppsCheckConstants class
//Currently, this can return either VIRUS_LEVEL_RISK (1)
//or VIRUS_LEVEL_VIRUS (2)
val category = it.apkCategory
}
}
} else {
//Something went wrong with the request
//Use `it.getErrorReason()` to see why
}
}
task.addOnFailureListener {
//A communication error occurred.
//If `it is ApiException`, you may be able to get more details about why
//the failure occurred.
}
}
URLCheck
If your app allows users to visit URLs you aren't able to verify (forum app, social media app, etc), URLCheck can help you screen links that users click. If the URL is detected as malicious, you can prompt the user.
If you want to implement this for yourself, start with the example code below:
Code:
fun checkUrl(url: String) {
val client = SafetyDetect.getClient(context)
//Ensure the URLCheck API is initialized
val initTask = client.initUrlCheck()
initTask.addOnSuccessListener {
//Initialization was successful.
//Make sure to remove any query parameters from the URL before checking it.
//For example, if the full URL is https://google.com/home?someKey=true, you need to pass
//https://google.com/home.
//...
//UrlCheckThreat can either be MALWARE or PHISHING.
//Each category is fairly self-explanatory.
//The threat argument is a vararg, so you can pass one or both.
//...
//You can find your APP_ID under "App information" in your project's settings on the AppGallery Developer Console.
val task = client.urlCheck(url, "APP_ID", UrlCheckThreat.MALWARE, UrlCheckThreat.PHISHING)
task.addOnSuccessListener {
//API call succeeded.
if (it.urlCheckResponse.isEmpty()) {
//URL is safe, continue
} else {
//URL matches either MALWARE or PHISHING category or both. Notify user or refuse to visit
//as is appropriate.
//Get the first threat type. Will match one of the UrlCheckThreat values you pass to
//the urlCheck() method.
val type = it.urlCheckResponse[0].urlCheckResult
}
}
task.addOnFailureListener {
//A communication error occurred.
//If `it is ApiException`, you may be able to get more details about why
//the failure occurred.
}
}
initTask.addOnFailureListener {
//Initialization failed.
}
}
UserDetect
UserDetect is essentially a realtime Captcha service. If there are parts of your app that you don't want to be used by bots (i.e. a clicker game), you can trigger a detection request to determine if the user is a bot or a person.
This one is a bit more complicated to implement, as it requires that you use HMS' cloud API to make the final request (i.e. a web server).
An example implementation in Kotlin is shown below:
Code:
fun checkUser() {
val client = SafetyDetect.getClient(context)
val initTask = client.initUserDetect()
initTask.addOnSuccessListener {
//Initialization was successful
//You can find your APP_ID under "App information" in your project's settings on the AppGallery Developer Console.
val task = client.userDetection("APP_ID")
task.addOnSuccessListener {
val responseToken = it.responseToken
if (responseToken.isNotEmpty()) {
//Pass this token to your server, and have it call HMS' cloud API to do the actual verification.
}
}
task.addOnFailureListener {
//A communication error occurred.
//If `it is ApiException`, you may be able to get more details about why
//the failure occurred.
}
}
initTask.addOnFailureListener {
//Initialization failed.
}
}
WifiDetect
If your app relies on a secure WiFi connection, this API may be helpful to you. You can use it to check whether the user's WiFI connection is actually secure.
Here's a quick example stub in Kotlin:
Code:
fun checkWifi() {
val client = SafetyDetect.getClient(context)
val task = client.wifiDetectStatus
task.addOnSuccessListener {
//The status will either be 0, 1, or 2, depending on the WiFi network state.
//0 means WiFi is disconnected.
//1 means WiFi is secure.
//2 means WiFi is insecure.
val status = it.wifiDetectStatus
}
task.addOnFailureListener {
//A communication error occurred.
//If `it is ApiException`, you may be able to get more details about why
//the failure occurred.
}
}
Conclusion
That's all for the SafetyDetect SDK! If you're using HMS, or you're planning to use HMS, and you want to make sure your app is properly secured, the various included APIs are sure to be helpful.
You can find more details, including the full API reference for the Safety Detect SDK, on Huawei's developer website.

Search places by keywords with HMS Site Kit

Hello everyone, in this article series, I will tell you about what is HMS Site Kit and how to use it’s features. With HMS Site Kit, you can basically provide users with easy and reliable access to services to related to locations and places.
With the HMS Site Kit, we can provide them make use of this features while helping users to to discover world quickly;
We can take place suggestions according to the keywords that we have determined,
According to the location of the user’s device, we can search for nearby places,
We can get detailed information about a location,
We can learn the human readable address information of a coordinate point,
We can learn the time period where a coordinate point is found.
In the first article of Site Kit series, I will give you an information about how to setup Site Kit to Android project and how to use Keyword Search.
How to integrate HMS Site Kit to project?
First of all, we need to create a signed Bundle/APK of our project. For this, you can follow the steps which have shown in the picture below.
We can start to creating signature by clicking on the Build->Generate Signed Bundle/APK menu on Android Studio. Then, we can start the process of generating a signed APK by selecting the APK option on screen that comes up.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
By pressing the Create New button on the screen that comes up, we can determine the path, password, key alias and key password values of the .jks file to be created for our application. Informations in the Certificate field is not mandatory.
After clicking OK button, we can continue the APK signing process by entering our password informations.
Then, we can complete the signing process by choosing which version of our application we want to sign such as release and debug, together with the signature versions.
After completing this process, we need to make configurations of this signature file in the build.gradle file at the app level of our application.
Code:
signingConfigs {
release {
storeFile file('SiteKitDemo.jks')
keyAlias 'SiteKitDemo'
keyPassword '****'
storePassword '****'
v1SigningEnabled true
v2SigningEnabled true
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
signingConfig signingConfigs.release
debuggable true
}
}
After performing this process, we can perform the operations related to Gradle synchronization by clicking on the sync now button.
After performing this process, we need to add ‘SHA-256 certificate fingerprint’ value of our application to AppGallery Connect.
We can learn value of ‘SHA-256 certificate fingerprint’ via termianl/CMD. For this, we need to go by terminal to the bin folder under the jre(Java Runtime Environment) installed on our system and run the command below.
Code:
C:\Program Files (x86)\Java\jre1.8.0_251\bin>keytool -list -v -keystore <keystore-path>
We will see a screen output as follows. Here, we need to get the value of SHA256.
We need to add this SHA256 value which we have received to the General Information field in the Project Settings menu on AppGalleryConnect. After performing this process, we can download the agconnect-services.json file.
After performing this process, we need to enable Site Kit service in Manage APIs tab on Project Settings tab.
We need to add agconnect-services.json file which we have downloaded, to under app folder on Android Studio of our project as follows.
After performing this process, we need to add Maven libraries and dependency values on build.gradle files.
First of all, we need to open build.gradle file at the project level and add the lines shown below:
Code:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.61'
repositories {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' } // HUAWEI Maven repository
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
def agcpVersion = "1.3.1.300"
classpath "com.huawei.agconnect:agcp:${agcpVersion}" // HUAWEI agcp plugin
}
}
allprojects {
repositories {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' } // HUAWEI Maven repository
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
After performing this process, we need to add plugin and dependency values in the build.gradle file at the app level as follows.
Code:
apply plugin: 'com.huawei.agconnect'
...
...
dependencies {
...
def siteKitVersion = "4.0.3.300"
implementation "com.huawei.hms:site:${siteKitVersion}"
}
To prevent HMS SDK from hiding, we need to add following lines of code to proguard-rules.pro file which is located under the app folder.
Code:
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
HMS Site Kit — Keyword Search
Thanks to this feature provided by Site Kit, we can search for many places such as tourist attractions, restaurants, schools and hotels by entering information such as keywords, coordinates.
Thanks to the data from this search result, we can easily access many different information about places such as name, address, coordinates, phone numbers, pictures, address details. Within the AddressDetail model, we can easily access information about the address piece by piece through different variables and change the way the address’ notation as we wish.
First of all, after sharing sharing the method what we can search by keyword, we will examine these pieces of code and parameters one by one.
Code:
fun keywordSearch(coordinate: Coordinate, keyword: String, radius: Int,
pageIndex: Int, pageSize: Int, countryCode: String){
val searchService = SearchServiceFactory.create(context,
URLEncoder.encode(
"Your-API-KEY",
"utf-8"))
var request = TextSearchRequest()
request.query = keyword
request.location = coordinate
request.radius = radius
request.pageIndex = pageIndex
request.pageSize = pageSize
request.language = Locale.getDefault().language // Getting system language
request.countryCode = countryCode
searchService.textSearch(request, object: SearchResultListener<TextSearchResponse>{
override fun onSearchError(searchStatus: SearchStatus?) {
Log.e("SITE_KIT","${searchStatus?.errorCode} - ${searchStatus?.errorMessage}")
}
override fun onSearchResult(textSearchResponse: TextSearchResponse?) {
var siteList = textSearchResponse?.sites
siteList?.let {
for(site in siteList){
Log.i("SITE_KIT", "Name => ${site.name}," +
"Format address => ${site.formatAddress}, " +
"Coordinate => ${site.location.lat} - ${site.location.lng}, " +
"Phone => ${site.poi.phone}, " +
"Photo URLS => ${site.poi.photoUrls}, " +
"Rating => ${site.poi.rating}, " +
"Address Detail => ${site.address.thoroughfare}, ${site.address.subLocality}, " +
"${site.address.locality}, ${site.address.adminArea}, ${site.address.country}")
}
} ?: kotlin.run {
Log.e("SITE_KIT","There is not any site")
}
}
})
}
First, we need to create a SearchService object from the SearchServiceFactory class. For this, we can use the create() method of the SearchServiceFactory class. We need to declare two parameters in create() method.
The first of these parameters is context value. It is recommended that Context value should be in Activity type. Otherwise, when HMS Core(APK) needs to be updated, we can not receive any notification about it.
The second parameter is API Key value that we can access via AppGallery Connect. This value is generated automatically by AppGallery Connect when a new app is created. We need to encode API parameter as encodeURI.
We need to create a TextSearchRequest object to perform searching by keyword. We will perform the related search criteria on this TextSearchRequest object.
While performing the searching operation, we can set many different criteria as we see in the code snippet. Let us examine the duties of these criteria one by one if you want to:
Query: Used to specify the keyword that we will use during the search process.
Location: It is used to specify latitude and longitude values with a Coordinate object to ensure that search results are searched as closely to the location that we want.
Radius: It is used to make the search results within in a radius determined in meters. It can take values between 1 and 50000, and its default value is 50000.
CountryCode: It is using to limit search results according to certain country borders.
Language: It is used to specify the language that search results have to be returned. If this parameter is not specified, the language of the query field we have specified in the query field is accepted by default. In example code snippet in above, the language of device has been added automatically in order to get a healthy result.
PageSize: Results return with the Pagination structure. This parameter is used to determine the number of Sites to be found in each page.
PageIndex: It is used to specify the number of the page to be returned with the Pagination structure.
Once we have determined our criteria, we can start the search using textSearch() method of SearchService object. textSearch() method takes two parameters.
First parameter is TextSearchRequest object which we have defined above. Here, our search criterias are defined.
For the second parameter, we need to implement SearchResultListener interface. Since the SearchResultListener interface is generic, we need the data type that results will return here. Here we can specify TextSearchResponse class that is model provided by Huawei Site Kit. This interface contains two methods, onSearchError() and onSearchResult() methods. We can configure these methods according to logic of our program and take necessary actions.

How To Integrate Huawei Account Kit to a Cordova Project?

This article includes information about how to integrate Huawei Cordova Account plugin to a Cordova project and how to use some APIs that Huawei Account Kit provides.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
The Cordova Account plugin provides adaption code used for the HUAWEI Account Kit to use in Cordova platform. HUAWEI Account Kit enables developers to use simple, secure, and quick sign-in and authorization functions to save time from long authorization periods and it’s two factor authentication(password authentication and mobile number authentication) process keeps users informations safe.
Service Features
· Quick and standard
Huawei Account Kit allows you to connect to the Huawei ecosystem using your HUAWEI ID from a range of devices. This range of devices is not limitted with mobile phones, you can also easily access applications on tablets, wearables, and smart displays by using Huawei ID.
· Massive user base and global services
Huawei Account Kit serves 190+ countries and regions worldwide. Users can also use HUAWEI ID to quickly sign in to apps. For details about supported regions/countries please refer here from official documentation.
· Secure, reliable, and compliant with international standards
Complies with international standards and protocols (such as OAuth2.0 and OpenID Connect), and supports two-factor authentication to ensure high security.
Integrating Huawei Account Kit to a Cordova Project
Preperations
1. You should prepare your development environment by following “Preparing the Development Environment” guide from official documentation.
2. To be able to use Huawei Cordova Account Plugin you shoud register as a Huawei developer and follow “Configuring App Information in AppGallery Connect” guide from official documentation.
Integrating Cordova Account Plugin
1- You can install the plugin through npm.
· Run the following command in the root directory of your Cordova project to install it through npm.
Code:
cordova plugin add @hmscore/cordova-plugin-hms-account
2- You should check if the Cordova Account Plugin successfully added to “plugin” folder of the root directory of your cordova project.
3- You should add agconnect-services.json(downloaded from AppGallery Connect), jks and build.json files to your projects root directory.
· Please refer following code snippet for build.json file.
Code:
{
"android": {
"release": {
"keystore": "./xxx.jks",
"storePassword": "xxxxx",
"alias": "xxx",
"password": "xxxxx"
},
"debug": {
"keystore": "./xxx.jks",
"storePassword": "xxxxx",
"alias": "xxx",
"password": "xxxxx"
}
}
}
Now the integration part is done and you are ready to use the Cordova Account Plugin in your Cordova project.
Use Cordova Account Plugin APIs
Signing-In with Huawei ID
To allow users securely signing-in with Huawei ID, you should use signIn method of HMSAccount module. When this method called for the first time for a user, a Huawei ID authorization interface will be shows up and user should click “Authorize and Login” button with necessary permission checks. After signing in for the first time, when users try to sign in again, the authorization screen will not show up again, unless they revoke the authorization.
Code:
const jsonArr = [CommonTypes.ScopeConstants.SCOPE_AUTHORIZATION_CODE];
const param = CommonTypes.HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM;
try {
const res = await HMSAccount.signIn(jsonArr, param);
alert(JSON.stringify(res));
} catch (ex) {
alert(JSON.stringify(ex));
}
When sign-in operation is successfull, user information will be returned as AuthHuaweiID object, otherwise an exception will be returned.
Signing-Out from Huawei ID
signOut method is used to allow user signing-out from Huawei ID. But it does not clear user information permenantly. The authorization information is not cleared, so when signIn method called again the application will not interact with the authorization interface.
Code:
try {
const res = await HMSAccount.signOut();
alert("signOut -> success");
} catch (ex) {
alert('signOut -> Error : ' + JSON.stringify(ex));
}
If the user signed out successfully, the promise is resolved . Otherwise it is rejected.
Silently Signing-In with Huawei ID
Authorization is required only at the first sign-in to your app using a HUAWEI ID. The silentSignIn method allows to using the same HUAWEI ID without authorization for subsequent sign-ins.
Code:
try {
const res = await HMSAccount.silentSignIn();
alert("silentSignIn -> success :" + JSON.stringify(res));
} catch (ex) {
alert('silentSignIn -> Error : ' + JSON.stringify(ex));
}
In case of silentSignIn is successfull, user information will be returned via a AuthHuaweiId object. Otherwise exception object is returned.
Canceling Huawei ID Authorization
To improve privacy and security, users are allowed to revoke authorization on your app. As mentioned before, when user firstly signing-ins, a Huawei ID authorization interface will be shows up. But for other calls of signIn method, the authorization interface will not be shows up because authorization information is not deleted with signOut method call or others. To clear authorization information cancelAuthorization method should be called and revoke authorization.
Code:
try {
const res = await HMSAccount.cancelAuthorization();
alert("cancelAuthorization -> success");
} catch (ex) {
alert('cancelAuthorization -> Error : ' + JSON.stringify(ex));
}
If the user cancels an authorization successfully, the promise will be resolved and authorization information will be deleted; otherwise exception object will be returned.
Automatically Retrieving SMS Verification Code
To allow your app to use SMS verification and verify the user identity using an SMS verification code you should integrate the HMSReadSmsManager module of Huawei Cordova Account Plugin. Without any need to apply for the SMS read permission, your app can automatically read the SMS verification code when this module is used.
Code:
try {
const res = await HMSReadSMSManager.smsVerificationCode();
alert("smsVerificationCode -> success :" + JSON.stringify(res));
} catch (ex) {
alert('smsVerificationCode -> Error : ' + JSON.stringify(ex));
}
After smsVerificationCode method of HMSReadSmsManager module called, app starts to listen right formatted messages, and catch them. There is five minutes timing out period, if the right formatted message is catched in this period of time, message will be returned otherwise a time out message will be fundisplayed.
You should generate an SMS verification code based on the mobile number and send an SMS message to the user in a specific format.The specific format should be as follows;
· “prefix_flag”: Indicates the prefix flag of the SMS message, including <#>, [#], and \u200b\u200b (which is a string of invisible Unicode characters)
· “short message verification code is”: indicates the SMS message content that is changeable
· “XXXXXX”: indicates a verification code
· “hash_value”: indicates the hash value generated by the HMS Core SDK to uniquely identify the app.
The hash_value is unique for all apps, it is generated based on the app package name. To obtain this hash value you can use obtainHashCode method of HMSReadSmsManager module.
Code:
try { const res = await HMSReadSMSManager.obtainHashCode(); alert("hashCode -> success :" + JSON.stringify(res)); } catch (ex) { alert('hashCode -> Error : ' + JSON.stringify(ex)); }
Sample Sign-In/Sign-Out Application
With the help of the above information lets create a sample app which performs a basic sign-in operation to see how to use HMS Account Kit APIs.
Step 1: Lets follow instructions on “Integrating Huawei Account Kit to a Cordova Project” of this article to prepare development environment and integrate plugin to the sample project.
Step 2: Make sure that app creation and integration of the plugin successfull.
Step 3: Create a button for sign-in operation on index.html file.
Step 4: Call HMS Account Kit signIn API to allow user signing-in on index.js file.
Code:
var app = {
initialize: function() {
document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
},
onDeviceReady: function() {
document.getElementById('btn_sign_in_with_id_token').addEventListener('click', signInWithIdToken);
}
};
async function signInWithIdToken() {
const jsonArr = [CommonTypes.ScopeConstants.SCOPE_ID_TOKEN];
const param = CommonTypes.HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM;
HMSAccount.signIn(jsonArr, param).then( function(userInfo){
localStorage.setItem('userInfo', JSON.stringify(userInfo));
window.location = "login.html";
}).catch(function(){
alert('signIn -> Error : ' + JSON.stringify(ex));
});
}
app.initialize();
Step 5: After successfull sign-in operation, lets use user information and displat it on a user information page. For that lets create a new page as follows.
login.html file includes one button for sign-out and user information fields. These fields filling up with user information which came from sign-in response as seen below.
Code:
var app = {
initialize: function() {
document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
},
onDeviceReady: function() {
var data = {
getUserInfo: function() {
var userInfo = localStorage.getItem('userInfo');
console.log(userInfo);
return JSON.parse(userInfo);
}
}
var userDataObject=data.getUserInfo();
document.getElementById('btn_sign_out').addEventListener('click', signOut);
document.getElementById('userName').innerHTML = "User Name: " + userDataObject.givenName + " " + userDataObject.familyName;
document.getElementById('nickName').innerHTML = "Nick Name: " + userDataObject.displayName;
}
};
async function signOut() {
HMSAccount.signOut().then( function(){
if(confirm('HuaweiId Authorization will be also deleted!')){
HMSAccount.cancelAuthorization();
}
alert("signOut -> success");
window.location = "index.html";
}).catch(function(){
alert('signOut -> Error : ' + JSON.stringify(ex));
});
}
app.initialize();
Step 6: Run cordova project
If you need, you can find whole sample sign-in/sign-out project on github.
As it can be seen using Huawei Cordova Account Plugin is an easy way to provide users secure sign in operations. It also helps to save from time with one click sign in functionality.
What are the maximum lengths of access_token and refresh_token?

Beginner: Integration of Huawei Site Kit and Cloud DB in Android (Kotlin)

Introduction
In this article, we will be learning how to integrate the Huawei Site kit and Cloud DB integrations in Android using Kotlin. Using AGC Cloud DB service, Service Providers from multiple cities can manage their data through CRUD (Create, Read, Update and Delete) operations. Using Site Kit user can search nearby stores and check stores details.
Development Overview
You need to install Android Studio and I assume that you have prior knowledge about the Android and Kotlin
Hardware Requirements
A computer (desktop or laptop) running Windows 10.
A Huawei phone (with the USB cable), which is used for debugging.
Software Requirements
Java JDK 1.7 or later
Android studio installed.
HMS Core (APK) 4.x or later
Integration of Site Kit
Site Kit provides place search services including keyword search, nearby place search, place detail search, and place search suggestion, helping your app provide convenient place-related services to attract more users and improve user loyalty.
Step 1: To integrate Site kit, need to add the below library:
Code:
implementation 'com.huawei.hms:site:5.0.2.300’
Step 2: How to get API Key?
Create an app in AppGallery Connect enter all necessary information.
Generate and configure the signing certificate fingerprint.
Add the AppGallery Connect plug-in and the Maven repository in the project-level build.gradle file. Configure the signature file in Android Studio.
For details, refer to Preparations for Integrating HUAWEI HMS Core.
After configure project, you can find API key in below image.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Step 3: To initialize HMS Site kit:
searchService = SearchServiceFactory.create(this, Utils.getApiKey())
To fetch nearby stores based on user’s current location:
SearchServiceActivity.kt
Code:
intent.let {
val request = NearbySearchRequest().apply {
queryString=it.getStringExtra(AppConstants.REQUEST_QUERY).toString()
setQuery(queryString)
setLocation(
Coordinate(
it.getDoubleExtra(AppConstants.SERVICE_LAT_KEY, 0.0),
it.getDoubleExtra(AppConstants.SERVICE_LNG_KEY, 0.0)
)
)
}
imageString = it.getStringExtra(AppConstants.PROVIDER_IMAGE_KEY).toString()
searchService?.nearbySearch(request, searchResultListener)
}
Results
Note: For more details, refer Site kit integration procedure. Site kit- SDK integration
Integration of Cloud DB
In this scenario, we can learn about a database service that runs on a cloud and is accessible from anywhere. Find the following points for better understand:
How to use Cloud DB to develop applications?
How to read, write and query application data to Cloud DB?
This service provides the synergy database product that provides data synergy management capabilities between the device and the cloud, unified data models, and various data management APIs.
Cloud DB supplies us simply cloud database and our project work together successfully and we can take advantages of CRUD (Create, Read, Update and Delete) operations.
Prerequisites
To use the Cloud DB for build application service, you need to complete the following preparations:
You have registered an account on the AppGallery Connect console and passed real-name authentication.
You have created a project and application on the AppGallery Connect console.
You have enabled the Anonymous account authentication service for the application to use permissions of the authentication user.
You have installed Android Studio on the local host.
Enable Cloud DB Service
Before using the Cloud DB service, you need to enable it.
Log in to AppGallery Connect and click My Projects.
Select a project from the project list and click an app for which you need to enable the Cloud DB service.
In the navigation bar, choose Build > Cloud DB.
Click Enable now to enable the Cloud DB service.
Select the Data storage location.
After the service is initialized, the Cloud DB service is enabled successfully.
After the service is initialized, the Cloud DB service is enabled successfully.
Adding and Exporting Object Types
The following example shows how to create object types on the AppGallery Connect console and export the object type file in the Java format for Android application development.
1. Log in to AppGallery Connect and click My projects.
2. Select a project from the project list and click an app for which you need to add an object type.
3. In the navigation bar, choose Build > Cloud DB.
4. Click Add to navigate to the object type creation page.
5. Set Object Type Name to LoginInfo, and click Next.
6. Click “+Add Field”, add the fields as per your requirements and click Next.
7. (Optional) Click “+Add Index”.
8. Add permissions as follows and click Next. (For Everyone, upsert and delete access is not allowed).
9. Click OK. Object types are created and displayed in the object type list.
The created object types are displayed in the object type list.
Repeat the above steps to create to create multiple table.
10. Click “Export” button
11. Set the format of the file to be exported to JAVA.
12. Set the Java file type to Android.
13. Enter the package name in the JAVA file.
The package name can contain only the following three types:
Letters: A–Z or a–z, which are mandatory
Digits: 0–9
Special characters: underscore (_) and period (.)
15. Click Export. The file that contains all object types will be downloaded. Add the exported JAVA file in your project. The file that contains all object types in the version is exported to the local PC. The exported Java file will be added to the local development environment in subsequent steps.
Cloud DB Zone
You can create a Cloud DB zone on the AppGallery Connect console. Perform the following steps to set Cloud DB Zone Name.
1. Log in to AppGallery Connect and click My projects.
2. Select a project from the project list and click an app for which you need to add a Cloud DB zone.
3. In the navigation tree, choose Build > Cloud DB.
4. Click the Cloud DB Zones tab.
5. Click Add to go to the Cloud DB zone creation page.
6. Enter Your App Name in the Cloud DB Zone Name text box.
7. Click OK the created Cloud DB zones are displayed in the Cloud DB zone list.
Configuring the Development Environment
Add a Cloud DB SDK to the dependencies node in the build.gradle file in the Project/app directory.
Code:
implementation <strong>'com.huawei.agconnect:agconnect=database:1.2.3.301’</strong>
In the build.gradle file, set the compatibility mode of Java source code to JDK1.8.
Code:
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
Adding Object Type Files
During application development, you can directly add the JAVA files exported from the AppGallery Connect console to the local development environment, and use the createObjectType() method in the AGConnectCloudDB class to define and create object types. Then you do not need to create object types for local application development.
Add all exported files to the local development environment.
Initialize Cloud DB. Use the createObjectType() method in the AGConnectCloudDB class to define and create object types.
Initializing
After adding an object type file, you can use the Cloud DB to develop an application. When developing an application, you need to initialize AGConnectCloudDB, and create Cloud DB zone and object types.
Initialize AGConnectCloudDB in an application’s CloudDBZoneWrapper
Code:
public static void initAGConnectCloudDB(Context context) {
AGConnectCloudDB.initialize(context);
}
Obtain the AGConnectCloudDB instance and create object types.
Code:
mCloudDB = AGConnectCloudDB.getInstance();
mCloudDB.createObjectType(ObjectTypeInfoHelper.getObjectTypeInfo());
Create the Cloud DB zone configuration object and open the Cloud DB zone. Add the below code in CloudDBZoneWrapper class.
Code:
public void openCloudDBZoneV2() {
mConfig = new CloudDBZoneConfig(AppConstants.URBAN_HOME_SERVICES,
CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE, CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC);
mConfig.setPersistenceEnabled(true);
Task<CloudDBZone> openDBZoneTask = mCloudDB.openCloudDBZone2(mConfig, true);
openDBZoneTask.addOnSuccessListener(cloudDBZone -> {
Log.w(TAG, "open clouddbzone success");
mCloudDBZone = cloudDBZone;
// Add subscription after opening cloudDBZone success
mUiCallBack.onInitCloud();
addSubscription();
}).addOnFailureListener(e ->
Log.w(TAG, "open clouddbzone failed for”));
}
Writing Data
You can use the executeUpsert() API to write one object or a group of objects to the current Cloud DB zone.
Add the below code in CloudDBZoneWrapper class.
Code:
public void insertDbZoneInfo(T objectInfo) {
if (mCloudDBZone == null) {
Log.w(TAG, "CloudDBZone is null, try re-open it");
return;
}
Task<Integer> upsertTask = mCloudDBZone.executeUpsert(objectInfo);
upsertTask.addOnSuccessListener(cloudDBZoneResult -> {
mUiCallBack.onInsertSuccess(cloudDBZoneResult);
}).addOnFailureListener(e -> {
mUiCallBack.updateUiOnError("Insert table info failed");
});
}
Viewing Data
Data added on the application page will be stored on the cloud. After a listener for data changes is registered on the device, the device will be notified when there is any changes on the cloud, and the local data will be updated in time.
You can use the query condition together with the subscribeSnapshot() method to specify an object to be listened on. When the data of the object is changed, the device will be notified and the original data stored on the cloud will be synchronized to the device based on the data changes information obtained by snapshots.
Add the below code in CloudDBZoneWrapper class.
Code:
private OnSnapshotListener<T> mSnapshotListener = (cloudDBZoneSnapshot, e) -> {
if (e != null) {
Log.w(TAG, "onSnapshot" );
return;
}
CloudDBZoneObjectList<T> snapshotObjects = cloudDBZoneSnapshot.getSnapshotObjects();
List<T> dbZoneList = new ArrayList<>();
try {
if (snapshotObjects != null) {
while (snapshotObjects.hasNext()) {
T objectInfo = snapshotObjects.next();
dbZoneList.add(objectInfo);
}
}
mUiCallBack.onSubscribe(dbZoneList);
} catch (AGConnectCloudDBException snapshotException) {
Log.w(TAG, "onSnapshot:(getObject)");
} finally {
cloudDBZoneSnapshot.release();
}
};
Querying Data
The executeQuery(), addOnSuccessListener(), and addOnFailureListener() methods are used together to query data in asynchronous mode.
Add the below code in CloudDBZoneWrapper class.
Code:
public void queryAllData(CloudDBZoneQuery<T> query) {
if (mCloudDBZone == null) {
Log.w(TAG, "CloudDBZone is null, try re-open it");
return;
}
Task<CloudDBZoneSnapshot<T>> queryTask = mCloudDBZone.executeQuery(query,
CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY);
queryTask.addOnSuccessListener(new OnSuccessListener<CloudDBZoneSnapshot<T>>() {
@Override
public void onSuccess(CloudDBZoneSnapshot<T> snapshot) {
processQueryResult(snapshot);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
mUiCallBack.updateUiOnError("Query failed");
}
});
}
Deleting Data
You can use the executeDelete() method to delete a single object or a group of objects. When deleting data, Cloud DB will delete the corresponding data based on the input object primary key and does not check whether other attributes of the object are consistent with the stored data. When a group of objects are deleted, the deletion operation is atomic. That is, objects in the list are either all deleted successfully or all fail to be deleted.
Add the below code in CloudDBZoneWrapper class.
Code:
public void deleteTableData(List<T> tableObject) {
if (mCloudDBZone == null) {
Log.w(TAG, "CloudDBZone is null, try re-open it");
return;
}
Task<Integer> deleteTask = mCloudDBZone.executeDelete(tableObject);
if (deleteTask.getException() != null) {
mUiCallBack.updateUiOnError("Delete service type table failed");
return;
}
mUiCallBack.onDelete(tableObject);
}
}
Editing Data
You can use the editService() method to edit professional’s details.
Add the below code in ManageServiceActivity.kt class.
Code:
override fun editService(listObject: ServiceType) {
val intent = Intent(this, AddServiceActivity::class.java)
intent.apply {
putExtra(AppConstants.CATEGORY_NAME, listObject.cat_name)
putExtra(AppConstants.PROVIDER_PH_NUM, listObject.phone_number.toString())
putExtra(AppConstants.PROVIDER_MAIL_ID, listObject.email_id)
putExtra(AppConstants.PROVIDER_COUNTRY, listObject.country)
putExtra(AppConstants.PROVIDER_ID, listObject.id)
putExtra(AppConstants.PROVIDER_NAME, listObject.service_provider_name)
putExtra(AppConstants.PROVIDER_CITY, listObject.city)
putExtra(AppConstants.PROVIDER_STATE, listObject.state)
}
startActivity(intent)
}
Results
Tips and Tricks
Always use the latest version of the library.
Always provide proper Roles to user in Object Types.
Note: For more details, please refer Cloud Db service integration documentation, Cloud DB- Introduction
Conclusion
By using Cloud DB you can connect with Database without the need of APIs. You can perform the CRUD operations and also can restrict user access for the tables. Easy to connect with the application. Also you can search nearby service (plumber, electrician, painter etc) using site kit like as etc.
Site Kit to fetch nearby stores.
Cloud DB service to add, delete and edit professional’s details.
References
Site Kit
Cloud DB- Applying for Cloud BD
Cloud DB- Introduction
Checkout in forum

Beginner: Integration of Huawei Site Kit and Cloud DB in Android (Kotlin)

Introduction
In this article, we will be learning how to integrate the Huawei Site kit and Cloud DB integrations in Android using Kotlin. Using AGC Cloud DB service, Service Providers from multiple cities can manage their data through CRUD (Create, Read, Update and Delete) operations. Using Site Kit user can search nearby stores and check stores details.
Development Overview
You need to install Android Studio and I assume that you have prior knowledge about the Android and Kotlin
Hardware Requirements
A computer (desktop or laptop) running Windows 10.
A Huawei phone (with the USB cable), which is used for debugging.
Software Requirements
Java JDK 1.7 or later
Android studio installed.
HMS Core (APK) 4.x or later
Integration of Site Kit
Site Kit provides place search services including keyword search, nearby place search, place detail search, and place search suggestion, helping your app provide convenient place-related services to attract more users and improve user loyalty.
Step 1: To integrate Site kit, need to add the below library:
Java:
implementation 'com.huawei.hms:site:5.0.2.300’
Step 2: How to get API Key?
Create an app in AppGallery Connect enter all necessary information.
Generate and configure the signing certificate fingerprint.
Add the AppGallery Connect plug-in and the Maven repository in the project-level build.gradle file. Configure the signature file in Android Studio.
For details, refer to Preparations for Integrating HUAWEI HMS Core.
After configure project, you can find API key in below image.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Step 3: To initialize HMS Site kit:
Java:
searchService = SearchServiceFactory.create(this, Utils.getApiKey())
To fetch nearby stores based on user’s current location:
SearchServiceActivity.kt
Java:
intent.let {
val request = NearbySearchRequest().apply {
queryString=it.getStringExtra(AppConstants.REQUEST_QUERY).toString()
setQuery(queryString)
setLocation(
Coordinate(
it.getDoubleExtra(AppConstants.SERVICE_LAT_KEY, 0.0),
it.getDoubleExtra(AppConstants.SERVICE_LNG_KEY, 0.0)
)
)
}
imageString = it.getStringExtra(AppConstants.PROVIDER_IMAGE_KEY).toString()
searchService?.nearbySearch(request, searchResultListener)
}
Results
Note: For more details, refer Site kit integration procedure. Site kit- SDK integration
Integration of Cloud DB
In this scenario, we can learn about a database service that runs on a cloud and is accessible from anywhere. Find the following points for better understand:
How to use Cloud DB to develop applications?
How to read, write and query application data to Cloud DB?
This service provides the synergy database product that provides data synergy management capabilities between the device and the cloud, unified data models, and various data management APIs.
Cloud DB supplies us simply cloud database and our project work together successfully and we can take advantages of CRUD (Create, Read, Update and Delete) operations.
Prerequisites
To use the Cloud DB for build application service, you need to complete the following preparations:
You have registered an account on the AppGallery Connect console and passed real-name authentication.
You have created a project and application on the AppGallery Connect console.
You have enabled the Anonymous account authentication service for the application to use permissions of the authentication user.
You have installed Android Studio on the local host.
Enable Cloud DB Service
Before using the Cloud DB service, you need to enable it.
Log in to AppGallery Connect and click My Projects.
Select a project from the project list and click an app for which you need to enable the Cloud DB service.
In the navigation bar, choose Build > Cloud DB.
Click Enable now to enable the Cloud DB service.
Select the Data storage location.
After the service is initialized, the Cloud DB service is enabled successfully.
Adding and Exporting Object Types
The following example shows how to create object types on the AppGallery Connect console and export the object type file in the Java format for Android application development.
1. Log in to AppGallery Connect and click My projects.
2. Select a project from the project list and click an app for which you need to add an object type.
3. In the navigation bar, choose Build > Cloud DB.
4. Click Add to navigate to the object type creation page.
5. Set Object Type Name to LoginInfo, and click Next.
6. Click “+Add Field”, add the fields as per your requirements and click Next.
7. (Optional) Click “+Add Index”.
8. Add permissions as follows and click Next. (For Everyone, upsert and delete access is not allowed).
9. Click OK. Object types are created and displayed in the object type list.
The created object types are displayed in the object type list.
Repeat the above steps to create to create multiple table.
10. Click “Export” button
11. Set the format of the file to be exported to JAVA.
12. Set the Java file type to Android.
13. Enter the package name in the JAVA file.
The package name can contain only the following three types:\
Letters: A–Z or a–z, which are mandatory
Digits: 0–9
Special characters: underscore (_) and period (.)
15. Click Export. The file that contains all object types will be downloaded. Add the exported JAVA file in your project. The file that contains all object types in the version is exported to the local PC. The exported Java file will be added to the local development environment in subsequent steps.
Cloud DB Zone
You can create a Cloud DB zone on the AppGallery Connect console. Perform the following steps to set Cloud DB Zone Name.
1. Log in to AppGallery Connect and click My projects.
2. Select a project from the project list and click an app for which you need to add a Cloud DB zone.
3. In the navigation tree, choose Build > Cloud DB.
4. Click the Cloud DB Zones tab.
5. Click Add to go to the Cloud DB zone creation page.
6. Enter Your App Name in the Cloud DB Zone Name text box.
7. Click OK the created Cloud DB zones are displayed in the Cloud DB zone list.
Configuring the Development Environment
Add a Cloud DB SDK to the dependencies node in the build.gradle file in the Project/app directory.
Java:
implementation <strong>'com.huawei.agconnect:agconnect=database:1.2.3.301’</strong>
In the build.gradle file, set the compatibility mode of Java source code to JDK1.8.
Java:
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
Adding Object Type Files
During application development, you can directly add the JAVA files exported from the AppGallery Connect console to the local development environment, and use the createObjectType() method in the AGConnectCloudDB class to define and create object types. Then you do not need to create object types for local application development.
Add all exported files to the local development environment.
Initialize Cloud DB. Use the createObjectType() method in the AGConnectCloudDB class to define and create object types.
Initializing
After adding an object type file, you can use the Cloud DB to develop an application. When developing an application, you need to initialize AGConnectCloudDB, and create Cloud DB zone and object types.
Initialize AGConnectCloudDB in an application’s CloudDBZoneWrapper
Java:
public static void initAGConnectCloudDB(Context context) {
AGConnectCloudDB.initialize(context);
}
Obtain the AGConnectCloudDB instance and create object types.
Java:
mCloudDB = AGConnectCloudDB.getInstance();
mCloudDB.createObjectType(ObjectTypeInfoHelper.getObjectTypeInfo());
Create the Cloud DB zone configuration object and open the Cloud DB zone. Add the below code in CloudDBZoneWrapper class.
Java:
public void openCloudDBZoneV2() {
mConfig = new CloudDBZoneConfig(AppConstants.URBAN_HOME_SERVICES,
CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE, CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC);
mConfig.setPersistenceEnabled(true);
Task<CloudDBZone> openDBZoneTask = mCloudDB.openCloudDBZone2(mConfig, true);
openDBZoneTask.addOnSuccessListener(cloudDBZone -> {
Log.w(TAG, "open clouddbzone success");
mCloudDBZone = cloudDBZone;
// Add subscription after opening cloudDBZone success
mUiCallBack.onInitCloud();
addSubscription();
}).addOnFailureListener(e ->
Log.w(TAG, "open clouddbzone failed for”));
}
Writing Data
You can use the executeUpsert() API to write one object or a group of objects to the current Cloud DB zone.
Add the below code in CloudDBZoneWrapper class.
Java:
public void insertDbZoneInfo(T objectInfo) {
if (mCloudDBZone == null) {
Log.w(TAG, "CloudDBZone is null, try re-open it");
return;
}
Task<Integer> upsertTask = mCloudDBZone.executeUpsert(objectInfo);
upsertTask.addOnSuccessListener(cloudDBZoneResult -> {
mUiCallBack.onInsertSuccess(cloudDBZoneResult);
}).addOnFailureListener(e -> {
mUiCallBack.updateUiOnError("Insert table info failed");
});
}
Viewing Data
Data added on the application page will be stored on the cloud. After a listener for data changes is registered on the device, the device will be notified when there is any changes on the cloud, and the local data will be updated in time.
You can use the query condition together with the subscribeSnapshot() method to specify an object to be listened on. When the data of the object is changed, the device will be notified and the original data stored on the cloud will be synchronized to the device based on the data changes information obtained by snapshots.
Add the below code in CloudDBZoneWrapper class.
Java:
private OnSnapshotListener<T> mSnapshotListener = (cloudDBZoneSnapshot, e) -> {
if (e != null) {
Log.w(TAG, "onSnapshot" );
return;
}
CloudDBZoneObjectList<T> snapshotObjects = cloudDBZoneSnapshot.getSnapshotObjects();
List<T> dbZoneList = new ArrayList<>();
try {
if (snapshotObjects != null) {
while (snapshotObjects.hasNext()) {
T objectInfo = snapshotObjects.next();
dbZoneList.add(objectInfo);
}
}
mUiCallBack.onSubscribe(dbZoneList);
} catch (AGConnectCloudDBException snapshotException) {
Log.w(TAG, "onSnapshot:(getObject)");
} finally {
cloudDBZoneSnapshot.release();
}
};
Querying Data
The executeQuery(), addOnSuccessListener(), and addOnFailureListener() methods are used together to query data in asynchronous mode.
Add the below code in CloudDBZoneWrapper class.
Java:
public void queryAllData(CloudDBZoneQuery<T> query) {
if (mCloudDBZone == null) {
Log.w(TAG, "CloudDBZone is null, try re-open it");
return;
}
Task<CloudDBZoneSnapshot<T>> queryTask = mCloudDBZone.executeQuery(query,
CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY);
queryTask.addOnSuccessListener(new OnSuccessListener<CloudDBZoneSnapshot<T>>() {
@Override
public void onSuccess(CloudDBZoneSnapshot<T> snapshot) {
processQueryResult(snapshot);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
mUiCallBack.updateUiOnError("Query failed");
}
});
}
Deleting Data
You can use the executeDelete() method to delete a single object or a group of objects. When deleting data, Cloud DB will delete the corresponding data based on the input object primary key and does not check whether other attributes of the object are consistent with the stored data. When a group of objects are deleted, the deletion operation is atomic. That is, objects in the list are either all deleted successfully or all fail to be deleted.
Add the below code in CloudDBZoneWrapper class.
Java:
public void deleteTableData(List<T> tableObject) {
if (mCloudDBZone == null) {
Log.w(TAG, "CloudDBZone is null, try re-open it");
return;
}
Task<Integer> deleteTask = mCloudDBZone.executeDelete(tableObject);
if (deleteTask.getException() != null) {
mUiCallBack.updateUiOnError("Delete service type table failed");
return;
}
mUiCallBack.onDelete(tableObject);
}
}
Editing Data
You can use the editService() method to edit professional’s details.
Add the below code in ManageServiceActivity.kt class.
Java:
override fun editService(listObject: ServiceType) {
val intent = Intent(this, AddServiceActivity::class.java)
intent.apply {
putExtra(AppConstants.CATEGORY_NAME, listObject.cat_name)
putExtra(AppConstants.PROVIDER_PH_NUM, listObject.phone_number.toString())
putExtra(AppConstants.PROVIDER_MAIL_ID, listObject.email_id)
putExtra(AppConstants.PROVIDER_COUNTRY, listObject.country)
putExtra(AppConstants.PROVIDER_ID, listObject.id)
putExtra(AppConstants.PROVIDER_NAME, listObject.service_provider_name)
putExtra(AppConstants.PROVIDER_CITY, listObject.city)
putExtra(AppConstants.PROVIDER_STATE, listObject.state)
}
startActivity(intent)
}
Results
Tips and Tricks
Always use the latest version of the library.
Always provide proper Roles to user in Object Types.
Note: For more details, please refer Cloud Db service integration documentation, Cloud DB- Introduction
Conclusion
By using Cloud DB you can connect with Database without the need of APIs. You can perform the CRUD operations and also can restrict user access for the tables. Easy to connect with the application. Also you can search nearby service (plumber, electrician, painter etc) using site kit like as etc.
Site Kit to fetch nearby stores.
Cloud DB service to add, delete and edit professional’s details.
References
Site Kit
Cloud DB- Applying for Cloud BD
Cloud DB- Introduction
Read In Forum
Does CloudDB supports offline operations ?
What is the max size of data to be stored on Cloud DB?

Categories

Resources