Related
The HMS Site Kit SDK is a handy set of APIs to help you implement location and address-based searching in your app with ease. If you want to target Huawei devices with your app, and you're looking for a simple way to find and show results to your user, you've come to the right place.
This guide will get you started with the Site Kit SDK, and give you some basic implementation examples. Let's get started.
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 Site Kit 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:site:5.0.0.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 "Site Kit" 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 Site Kit SDK should now be available in your project.
Basic Usage
Huawei's Site Kit SDK gives you quite a few useful features.
There's Keyword Search, which lets the user type in a search query, along with other options, and see relevant results.
There's Nearby Place Search, which returns points of interest close to the user. There's a Place Details API, to let the user find out more about a specific place.
There's the Place Search Suggestion feature, which adds autofill-like search suggestions in real-time.
And finally, there's the Widget component, which implements Place Search Suggestion in a search bar for you.
We'll go over each feature one by one.
Keyword Search
Below is an example of how you might implement a keyword search.
Code:
//Create the search service. It's recommended you use an Activity
//Context, although it's not required.
//You can find your API key on the Project Setting page for your
//project in AppGallery Connect, under App Information.
val searchService = SearchServiceFactory.create(context, "API_KEY")
//Create a request. For this example, we're going to be
//using dummy inputs, but in a real app, these would
//be provided by the user.
val request = TextSearchRequest()
//This can be any keyword, like "McDonald's" or
//"Washington".
request.setQuery("London")
//Define a location (optional). This could be the user's
//current location, or some other area.
val location = Coordinate(48.893478, 2.334595)
request.setLocation(location)
//Set a radius in meters (optional). The default is 50,000.
location.setRadius(1000)
//Set the type of location (optional, but recommended).
//Values can be found in the HwLocationType class.
request.setHwPoiType(HwLocationType.ENTERTAINMENT_PLACE)
//Set the country code to where these results should be
//confined (optional). Uses the ISO-3166-1 alpha-2 standard.
request.setCountryCode("FR")
//Set the language for results to appear in (optional).
request.setLanguage("fr")
//Set the current page (from 1-60). Default is 1.
request.setPageIndex(1)
//Set how many results should appear per-page (from 1-20).
//Default is 20.
request.setPageSize(5)
//Create a result listener for handling search results.
val resultListener = object : SearchResultListener<TextSearchResponse>() {
override fun onSearchResult(result: TextSearchResponse?) {
//We've got results.
if (result == null || result.totalCount <= 0) {
//We actually don't have results. Return.
return
}
val sites: List<Site>? = result.sites
if (sites.isNullOrEmpty()) {
//Couldn't find any sites. Return.
return
}
//Handle results.
sites.forEach { site ->
val id = site.siteId
val name = site.name
}
}
override fun onSearchError(state: SearchStatus) {
//There was an error retrieving results.
val code = status.errorCode
val message = status.errorMessage
}
}
//Finally, initiate the search.
searchService.textSearch(request, resultListener)
Nearby Place Search
A Nearby Place Search is practically identical to a Keyword Search in terms of implementation. Simply replace the textSearch() call with a nearbySearch() call. Almost everything else is identical.
Code:
//Use this instead of `textSearch()`.
//One notable difference is that the default radius
//for a nearby search is 1,000 meters instead of 50,000.
searchService.nearbySearch(request, resultListener)
Place Details
Creating a Place Details request is similar to the previous two, although there are some differences in implementation. For one, you should know the site ID of the place whose details you're querying, which you can get using one of the above methods.
Code:
/Create the search service. It's recommended you use an Activity
//Context, although it's not required.
//You can find your API key on the Project Setting page for your
//project in AppGallery Connect, under App Information.
val searchService = SearchServiceFactory.create(context, "API_KEY")
//Create the details request.
val request = DetailSearchRequest()
//Set the site ID. You can retrieve this from a keyword or
//nearby place search result.
request.setSiteId("THE_SIDE_ID")
//Set the language (optional).
request.setLanguage("fr")
//Create a results listener.
val resultListener = object : SearchResultListener<DetailSearchResponse>() {
override fun onSearchResult(result: DetailSearchResponse?) {
//Detail search succeeded.
if (result == null) {
//Something weird happened. Return.
return
}
//Retrieve the site. Return if null.
val site = result.site ?: return
//Retrieve various details about the site and display
//for the user.
}
override fun onSearchError(status: SearchStatus) {
//There was an error retrieving results.
val code = status.errorCode
val message = status.errorMessage
}
}
//Initiate the request.
searchService.detailSearch(request, resultListener)
Place Search Suggestion
This feature is similar to the Keyword and Nearby Search features, except that it returns a limited set of results. It's more suitable for rapid-fire requests, such as real-time search suggestions.
Here's an example for how to implement it.
Code:
/Create the search service. It's recommended you use an Activity
//Context, although it's not required.
//You can find your API key on the Project Setting page for your
//project in AppGallery Connect, under App Information.
val searchService = SearchServiceFactory.create(context, "API_KEY")
//Create the request.
val request = QuerySuggestionRequest()
//Set the user's current query.
request.setQuery("Pari")
//Set a location (optional).
val location = Coordinate(48.893478, 2.334595)
request.setLocation(location)
//Set a radius in meters (optional) (from 1-50,000).
//Default is 50,000.
request.setRadius(50)
//Set the search country (optional).
request.setCountryCode("FR")
//Set the language results should appear in
//(optional).
request.setLanguage("fr")
//Set a specific POI type (optional). Should
//be a subset of the values found in LocationType.
request.setPoiTypes(LocationType.ADDRESS)
//Create a results listener.
val resultListener = object : SearchResultListener<QuerySuggestionResponse>() {
override fun onSearchResult(result: QuerySuggestionResponse?) {
if (result == null) {
//No results. Return.
return
}
val sites: List<Site>? = result.sites
if (sites.isNullOrEmpty()) {
//No sites. Return.
return
}
//Handle results.
sites.forEach { site ->
val id = site.sideId
val name = site.name
}
}
override fun onSearchError(status: SearchStatus) {
//There was an error retrieving results.
val code = status.errorCode
val message = status.errorMessage
}
}
//Initiate the search request.
searchServie.querySuggestion(request, resultListener)
Widget
The Site Kit can take care of search logic for you, including suggestions. Here's how.
The first thing you need to do is implement the Fragment in your layout.
XML:
<fragment
android:id="@+id/search_fragment"
android_name="com.huawei.hms.site.widget.SearchFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
You can also create a reference in code and use a FragmentManager to add and remove it as needed.
Next, you need to implement the search functionality.
Code:
//Get a reference to the Fragment. This example assumes it's
//in your layout XML.
val searchFragment = supportFragmentManager.findFragmentById(R.id.search_fragment) as SearchFragment
//Set the API key.
//You can find your API key on the Project Setting page for your
//project in AppGallery Connect, under App Information.
searchFragment.setApiKey("API_KEY")
//Set a selection listener.
searchFragment.setOnSiteSelectedListener(object : SiteSelectionListener() {
override fun onSiteSelected(site: Site) {
//The user has selected a site returned by HMS.
//Handle as applicable.
}
override fun onError(status: SearchStatus) {
//There was an error retrieving results.
val code = status.errorCode
val message = status.errorMessage
}
})
Conclusion
That's it! As you can probably see, HMS Site Kit makes it pretty easy to implement location searching in your app.
This is only for devices that come with HMS pre-installed, but it's certainly a useful set of tools. Be sure to check out Huawei's full documentation for more details.
If we briefly talk about what HMS Site Kit is, you can provide users to explore the world faster with Site Kit. You can search for locations by keywords, find places which are close to the specified coordinate point, get detailed information about a place and get suggestions for places by keyword.
We can get detailed information about a place with Place Detail Search, another feature of Site Kit. The only condition for this, we need to know Site model’s id value that belongs to the place we want to search.
Before I explain the use of Place Detail Search, I would like to share with you a function that we can use this feature.
Code:
fun placeDetail(siteId: String){
val searchService = SearchServiceFactory.create(context,
URLEncoder.encode(
"Your-API-KEY",
"utf-8"))
var request = DetailSearchRequest()
request.siteId = siteId
request.language = Locale.getDefault().language // Getting system language
searchService.detailSearch(request, object: SearchResultListener<DetailSearchResponse>{
override fun onSearchError(searchStatus: SearchStatus?) {
Log.e("SITE_KIT","${searchStatus?.errorCode} - ${searchStatus?.errorMessage}")
}
override fun onSearchResult(detailSearchResponse: DetailSearchResponse?) {
var site = detailSearchResponse?.site
site?.let {
Log.i("SITE_KIT", "Name => ${it.name}," +
"Format address => ${it.formatAddress}, " +
"Coordinate => ${it.location.lat} - ${it.location.lng}, " +
"Phone => ${it.poi.phone}, " +
"Photo URLS => ${it.poi.photoUrls}, " +
"Rating => ${it.poi.rating}, " +
"Address Detail => ${it.address.thoroughfare}, ${it.address.subLocality}, " +
"${it.address.locality}, ${it.address.adminArea}, ${it.address.country}")
} ?: kotlin.run {
Log.e("SITE_KIT","Site Place couldn't find with the given site ID")
}
}
})
}
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.
After creating our SearchService object as I described above, we can create a DetailSearchRequest object. We will specify the necessary parameters on this object related to the place which we want want to get information.
After creating our DetailSearchRequest object, we can determine parameters for a place that we want to get information. Two parameters are specified here:
SiteId: There is a unique id value for each Site in Site Kit. This parameter is used to specify the id value of the place whose information is to be obtained.
Language: It is used to specify the language that search results have to be returned. If this parameter is not specified, language of the query field we have specified in the query field is accepted by default. In example code snippet in above, language of device has been added automatically in order to get a healthy result.
After entering the id value and language parameter of the place that we want to learn in detail, we can start learning the details. For this, we will use detailSearch() method of the SearchService object. This method takes two parameters.
For the first parameter, we must specify DetailSearchRequest object we have defined above.
For the second parameter, we have to implement SearchResultListener interface. Since this interface has a generic structure, we need to specify class belonging to the values to be returned. We can get the incoming values by specifying DetailSearchResponse object. Two methods should be override with this interface. onSearchError() method is executed if operation fails, and onSearchResult() method is executed if operations is successful. There is one value in DetailSearchResponse. This value is Site object that belongs to the id value. With the Site variable of DetailSearchResponse object, we can access information belong to place we have searched.
sujith.e said:
Hi,Why API key is required?
Click to expand...
Click to collapse
API key is a simple credential for accessing Huawei services. Your API key is creating automatically on the AppGallery Connect when you create an application, and then your app can use the key to call public APIs provided by Huawei.
When an app calls a public API provided by Huawei, we should give this information to API to help Huawei to identify our application.
Hello everyone, in this article, provides example of HUAWEI Analytics Kit using the Cordova mobile application. But first, let me inform you about HUAWEI Analytics Kit a little.
About HUAWEI Analytics Kit
Offers a rich array of preset analytics models that help you gain a deeper insight into your users, products, and content.
Helps you gain insight into how your users behave on different platforms based on the user behavior events and user attributes reported by your app.
Diverse analytics models: analyzes events, behavior, audiences, funnels, retention, attribution, real-time data.
App Debugging: During app development, the product manager and technical team can cooperate with each other through app debugging to verify data reporting, preventing missing events and event attribute errors.
There are 3 types of events: automatically collected, predefined and custom.
With these insights, you can then take a data-driven approach to make informed decisions for product and marketing optimizations.
Privacy Statement: HUAWEI Analytics Kit does not collect users’ personal data. If your app needs to collect user data, it must do so in accordance with all applicable laws and regulations. You’ll also need to display a privacy statement, so users understand how you’re planning to use their data.
Integrating the AppGallery Connect SDK
Integrating AppGallery Connect is a prerequisite for using HUAWEI Analytics Kit is offering in your application. If you want to use the AppGallery Connect Analytics service, you must first have a AppGallery Connect developer account and integrate HMS Core in your application. You need to create an project from your developer account and then integrate the Cordova HMS Analytics Plugin into your project.
Creating an AppGallery Connect Project
Sign in to AppGallery Connect and select My projects.
Click Add 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"
}
Enter a project name and click OK.
After the project is created, the Project settings page is displayed. You need to add an app to the project.
Adding an App to the Project
Before you use development capabilities provided by AppGallery Connect, you need to add an app to your project first.
Sign in to AppGallery Connect and select My projects.
Click your project from the project list.
Go to Project settings > General information, and click Add app.
On the Add app page, enter app information.
On the Project settings page, enter SHA-256 certificate fingerpring and then download the configuration file agconnect-services.json for Android platform.
Generating a Signing SHA-256 Certificate Fingerprint
On the Project settings page, download the configuration file agconnect-services.plist for iOS platform.
App Information - iOS Platform
Please refer to Configuring App Information in AppGallery Connect and Enabling Huawei Analytics
Integrating the HMS Analytics Plugin
You can either install the plugin through npm or by downloading it from the download page, Cordova Analytics plugin.
Download Cordova Analytics Sample Project Code
Run the following command in the project root directory of your Cordova project to install it through npm.
Code:
cordova plugin add @hmscore/cordova-plugin-hms-analytics
# install the plugin manually after downloading plugin
cordova plugin add <CORDOVA_ANALYTICS_PLUGIN_PATH>
Add the Android platform to the Cordova project
Please refer to Android App Development
Add the iOS platform to the Cordova project
Please refer to iOS App Development
Using Debug Mode
During the development, you can enable the debug mode to view the event records in real time, observe the results, and adjust the event reporting policies.
Enabled Debug Mode and after then the data is successfully reported, you can go to HUAWEI Analytics > App debugging to view the reported data, as shown in the following figure.
Android Platform
Run the following command to enable the debug mode:
Code:
adb shell setprop debug.huawei.hms.analytics.app package_name
Run the following command to disable the debug mode:
iOS Platform
During the development, you can use DebugView to view the event records in real time, observe the results, and adjust the event reporting policies.
To enable the debug mode: Choose Product > Scheme > Edit Scheme from the Xcode menu. On the Arguments page, click + to add the -HADebugEnabled parameter. After the parameter is added, click Close to save the setting.
To disable the debug mode
Viewing Debugging Event Details (Real-time Update)
Sign in to AppGallery Connect and click My projects.
Find your project, and click the app for which you want to view analytics data.
Go to HUAWEI Analytics > App debugging.
The App debugging page displays events reported by the app in the last 60 seconds or last 30 minutes.
If you select Last 60 seconds, the displayed page is as follows.
If you select Last 30 minutes, the displayed page is as follows.
What is AAID(Anonymous Application ID)?
Anonymous device ID opened to third-party apps. Each app is allocated with a unique AAID on the same device so that statistics can be collected and analyzed for different apps (for example, statistics on the number of active users). In addition, personal data from different apps is isolated to protect user data privacy and security.
Code:
/**
* Obtains the app instance ID from AppGallery Connect.
*/
async function onGetAAID() {
try {
const aaid = await HMSAnalytics.getAAID();
alert('getAAID -> Success -> aaid : ' + aaid);
} catch (err) {
alert('getAAID -> Error : ' + err);
}
}
How to records event?
Records custom event
Such events can be used to meet personalized analysis requirements that cannot be met by automatically collected events and predefined events.
Note: The ID of a custom event cannot be the same as that of a predefined event. Otherwise, the custom event will be identified as a predefined event.
Code:
/**
* Report custom events.
*/
async function onEvent() {
const name = 'event_name';
const value = {
"my_event_key": "my_event_value",
"my_event_key_two": "my_event_value_two"
};
try {
const event = await HMSAnalytics.onEvent(name, value);
alert('onEvent -> Success');
} catch (err) {
alert('onEvent -> Error : ' + err);
}
}
Records predefined event
Such events have been predefined by the HMS Core Analytics SDK based on common application scenarios. It is recommended you use predefined event IDs for event collection and analysis.
Code:
/**
* Report predefined events.
*/
async function onSendPredefinedEvent() {
const event_name = HMSAnalytics.HAEventType.SUBMITSCORE;
const event_value = {}
event_value[HMSAnalytics.HAParamType.SCORE] = 12;
event_value[HMSAnalytics.HAParamType.CATEGORY] = "SPORT";
try {
const event = await HMSAnalytics.onEvent(event_name, event_value);
alert('sendPredefinedEvent -> Success');
} catch (err) {
alert('sendPredefinedEvent -> Error : ' + err);
}
}
Please refer to Event Management
Setting User Profiles
Sets user attributes. The values of user attributes remain unchanged throughout the app lifecycle and during each session.
Note: A maximum of 25 user attributes are supported. If the name of an attribute set later is the same as that of an existing attribute, the value of the existing attribute is updated.
Code:
async function onSetUserProfile() {
const userProfileName = "user_profile_name";
const userProfileValue = "user_profile_value";
try {
const setUserProfile = await HMSAnalytics.setUserProfile(userProfileName, userProfileValue);
alert('setUserProfile -> Success');
} catch (err) {
alert('setUserProfile -> Error : ' + err);
}
}
When is the clearCacheData() method used?
It is used when deletes all collected data cached locally, including cached data that failed to be sent.
Note: AAID will be reset. Custom user attributes will be delete.
Code:
async function onClearCachedData() {
try {
const clearCachedData = await HMSAnalytics.clearCachedData();
alert('clearCachedData -> Success');
} catch (err) {
alert('clearCachedData -> Error : ' + err);
}
}
How to define a custom page?
Customizes a page entry event. The API applies only to non-activity pages because automatic collection is supported for activity pages.
Note: If this API is called for an activity page, statistics on page entry and exit events will be inaccurate.
Defines a custom page
After this pageStart() method is called, the pageEnd() API must be called.
Code:
/**
* Defines a custom page entry event.
* @note This method is only to support on Android Platform.
*/
async function onPageStart() {
const start_page_name = "start_page_name";
const start_page_class_override = "start_page_class_override";
try {
const pageStart = await HMSAnalytics.pageStart(start_page_name, start_page_class_override);
alert('pageStart -> Success');
} catch (err) {
alert('pageStart -> Error : ' + err);
}
}
Before this pageEnd() method is called, the pageStart() API must be called.
Code:
/**
* Defines a custom page exit event.
* @note This method is only to support on Android Platform.
*/
async function onPageEnd() {
const end_page_name = "start_page_name";
try {
const pageEnd = await HMSAnalytics.pageEnd(end_page_name)
alert('pageEnd -> Success' + pageEnd);
} catch (err) {
alert('pageEnd -> Error : ' + err);
}
}
Conclusion
In this article you have learned how to integrate HMS Analytics to your Cordova projects, record custom events and monitor them in AppGallery Connect. You can use custom events with user attributes in your apps to see user behaviors, so that you can improve your app depend on them.
Thank you!
Other Huawei Developers Cordova Medium Publications
References
Stack Overflow is the best place for any programming questions. Be sure to tag your question with huawei-mobile-services.
GitHub is the official repository for these plugins, You can open an issue or submit your ideas.
Huawei Developer Forum HMS Core Module is great for general questions, or seeking recommendations and opinions.
Huawei Developer Docs is place to official documentation for all HMS Core Kits, you can find detailed documentations in there.
If you run into a bug in our samples, please submit an issue to the GitHub repository.
Do we need to add huawei analytics dependencies in app-level build.gradle or HMS_analytics plugin will have the dependencies?
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?
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?