Search On Map With Site Kit - Huawei Developers

{
"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"
}
Hello everyone.
This article about Huawei Map Kit and Site Kit. I will explain how to use site kit with map. Firstly I would like to give some detail about Map Kit and site Kit.
Map Kit provides an SDK for map development. It covers map data of more than 200 countries and regions, and supports dozens of languages. With this SDK, you can easily integrate map-based functions into your apps. Map kit supports only .Huawei devices. Thanks to Map Kit, you can add markers and shapes on your custom map. Also, Map kit provides camera movements and two different map type.
Site Kit provides the following core capabilities you need to quickly build apps with which your users can explore the world around them. Thanks to site kit, both you can search places and provides to you nearby places. Site Kit not only list places but also provide places detail.
Development Preparation
Step 1 : Register as Developer
Firstly, you have to register as developer on AppGallery Connect and create an app. You can find the guide of registering as a developer here :
Step 2 : Generating a Signing Certificate Fingerprint
Firstly, create a new project on Android Studio. Secondly, click gradle tab on the right of the screen. Finally, click Task > android > signingReport. And you will see on console your projects SHA-256 key.
Copy this fingerprint key and go AppGallery Console > My Apps > select your app > Project Settings and paste “SHA-256 certificate fingerprint” area. Don’t forget click the tick on the right.
Step 3 : Enabling Required Services
In HUAWEI Developer AppGallery Connect, go to Develop > Overview > Manage APIs.
Enable Huawei Map Kit and Site Kit on this page.
Step 4 : Download agconnect-services.json
Go to Develop > Overview > App information. Click agconnect-services.json to download the configuration file. Copy the agconnect-services.json file to the app root directory.
Step 5: Adding Dependecies
Open the build.gradle file in the root directory of your Android Studio project. Go to buildscript > repositories and allprojects > repositories, and configure the Maven repository address for the HMS SDK.
Code:
buildscript {
repositories {
maven { url 'http://developer.huawei.com/repo/' }
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.2'
classpath 'com.huawei.agconnect:agcp:1.2.1.301'
}
}
allprojects {
repositories {
google()
jcenter()
maven {url 'http://developer.huawei.com/repo/'}
}
}
Add dependencies in build.gradle file in app directory.
Code:
dependencies {
implementation 'com.huawei.hms:maps: 4.0.1.302 ' //For Map Kit
implementation 'com.huawei.hms:site:4.0.2.301' //For Site Kit
implementation 'com.jakewharton:butterknife:10.1.0' //Butterknife Library is optional.
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
}
Add the AppGallery Connect plug-in dependency to the file header.
Code:
apply plugin: 'com.huawei.agconnect'
Configure the signature in android. Copy the signature file generated in Generating a Signing Certificate Fingerprint to the app directory of your project and configure the signature in the build.gradle file.
Code:
android {
signingConfigs {
release {
storeFile file("**.**") //Signing certificate.
storePassword "******" //Keystore password.
keyAlias "******" //Alias.
keyPassword "******" //Key password.
v2SigningEnabled true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
signingConfig signingConfigs.release}
}
}
}
Open the modified build.gradle file again. You will find a Sync Now link in the upper right corner of the page. Click Sync Now and wait until synchronization is complete.
Step 6: Adding Permissions
To call capabilities of HUAWEI Map Kit, you must apply for the following permissions for your app:
Code:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
To obtain the current device location, you need to add the following permissions in the AndroidManifest file. In Android 6.0 and later, you need to apply for these permissions dynamically.
Code:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Development Process
Step 1 : Create Fragment XML File
I used fragment for this app. But you can use in the activity. Firstly You have to create a XML file for page design. My page looks like this screenshot.
Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="10dp">
<EditText
android:id="@+id/editText_search"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_weight="1"
android:textSize="15dp"
android:hint="Search..."
android:background="@drawable/input_model_selected"
android:fontFamily="@font/muli_regular"
android:inputType="textEmailAddress"
android:layout_marginTop="10dp"
android:layout_marginRight="25dp"
android:layout_marginLeft="25dp"/>
<Button
android:id="@+id/btn_search"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginTop="10dp"
android:background="@drawable/orange_background"
android:layout_weight="1"
android:layout_marginRight="5dp"
android:onClick="search"
android:layout_marginLeft="5dp"
android:text="Search"
android:textAllCaps="false" />
</LinearLayout>
</LinearLayout>
</ScrollView>
<com.huawei.hms.maps.MapView
android:id="@+id/mapview_mapviewdemo"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:cameraTargetLat="48.893478"
map:cameraTargetLng="2.334595"
map:cameraZoom="10" />
</LinearLayout>
Step 2 : Create Java File and Implement CallBacks
Now, create a java file called MapFragment and implement to this class OnMapReadyCallback. After this implementation onMapReady method will override on your class.
Secondy, you have to bind Map View, Edit Text and search button. Also, map object, permissions and search service should be defined.
Code:
View rootView;
@BindView(R.id.mapview_mapviewdemo)
MapView mMapView;
@BindView(R.id.editText_search)
EditText editText_search;
@BindView(R.id.btn_search)
Button btn_search;
private HuaweiMap hMap;
private static final String[] RUNTIME_PERMISSIONS = {
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.INTERNET
};
private static final int REQUEST_CODE = 100;
//Site Kit
private SearchService searchService;
Step 3 : onCreateView and onMapReady Methods
First of all, XML should be bound. onCreateView should start view binding and onCreateView should end return view. All codes should be written between view binding and return lines.
Secondly permissions should be checked. For this you have to add hasPermissions method like this:
Code:
private static boolean hasPermissions(Context context, String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
Thirdliy, onClick event should be defined for search button like this:
Code:
btn_search.setOnClickListener(this);
Next, search service should be created. When creating search service, API Key should be given as a parameter. You can access your API Key from console.
Code:
searchService = SearchServiceFactory.create(getContext(), “API KEY HERE”);
Finally, mapView should be created like this :
Code:
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(“MapViewBundleKey”);
}
mMapView.onCreate(mapViewBundle);
mMapView.getMapAsync(this);
On the onMapReady method should be include a map object. With this object you can add camera zoom and current location. If you want to zoom in on a specific coordinate when the page is opened, moveCamera should be added. And ıf you want to show current location on map, please add hMap.setMyLocationEnabled(true);
All of onCreateView should be like this :
Code:
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_map, container, false);
ButterKnife.bind(this,rootView);
if (!hasPermissions(getContext(), RUNTIME_PERMISSIONS)) {
ActivityCompat.requestPermissions(getActivity(), RUNTIME_PERMISSIONS, REQUEST_CODE);
}
btn_search.setOnClickListener(this);
searchService = SearchServiceFactory.create(getContext(), "API KEY HERE");
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle("MapViewBundleKey");
}
mMapView.onCreate(mapViewBundle);
mMapView.getMapAsync(this);
return rootView;
}
@Override
public void onMapReady(HuaweiMap huaweiMap) {
hMap = huaweiMap;
hMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng2, 13));
hMap.setMyLocationEnabled(true);
}
Finally map is ready. Now we will search with Site Kit and show the results as a marker on the map.
Step 4 : Make Search Request And Show On Map As Marker
Now, a new method should be created for searching. TextSearchRequest object and a specific coordinate must be created within the search method. These coordinates will be centered while searching.
Coordinates and keywords should be set on the TextSearchRequest object.
On the onSearchResult method, you have to clear map. Because in the new search results, old markers shouldn’t appear. And create new StringBuilder AddressDetail objects.
Get all results with a for loop. On this for loop markers will be created. Some parameters should be given while creating the marker. Creating a sample marker can be defined as follows.
Code:
hMap.addMarker(new MarkerOptions()
.position(new LatLng(site.getLocation().getLat(), site.getLocation().getLng())) //For location
.title(site.getName()) // Marker tittle
.snippet(site.getFormatAddress())); //Will show when click to marker.
All of the search method should be like this :
Code:
public void search(){
TextSearchRequest textSearchRequest = new TextSearchRequest();
Coordinate location = new Coordinate(currentLat, currentLng);
textSearchRequest.setQuery(editText_search.getText().toString());
textSearchRequest.setLocation(location);
searchService.textSearch(textSearchRequest, new SearchResultListener<TextSearchResponse>() {
@Override
public void onSearchResult(TextSearchResponse textSearchResponse) {
hMap.clear();
StringBuilder response = new StringBuilder("\n");
response.append("success\n");
int count = 1;
AddressDetail addressDetail;
for (Site site :textSearchResponse.getSites()){
addressDetail = site.getAddress();
response.append(String.format(
"[%s] name: %s, formatAddress: %s, country: %s, countryCode: %s \r\n",
"" + (count++), site.getName(), site.getFormatAddress(),
(addressDetail == null ? "" : addressDetail.getCountry()),
(addressDetail == null ? "" : addressDetail.getCountryCode())));
hMap.addMarker(new MarkerOptions().position(new LatLng(site.getLocation().getLat(), site.getLocation().getLng())).title(site.getName()).snippet(site.getFormatAddress()));
}
Log.d("SEARCH RESULTS", "search result is : " + response);
}
@Override
public void onSearchError(SearchStatus searchStatus) {
Log.e("SEARCH RESULTS", "onSearchError is: " + searchStatus.getErrorCode());
}
});
}
Now your app that searches on the map using the Site Kit is ready. Using the other features of Map Kit, you can create a more advanced, more specific application. You can get directions on the map. Or you can draw lines on the map. There are many features of Map Kit. You can add them to your project collectively by examining all of them at the link below.

Good job

Can we customize search list.

sujith.e said:
Can we customize search list.
Click to expand...
Click to collapse
Sure, we can customize search parameters. You can add
textSearchRequest.setPoiType(***LocationType.***HOSPITAL);
in the search() method. Also, LocationType object include so many different types. For eg. Museums, hospitals, banks, art gallery, airport, atm, bus station, gym etc.

Can I share my live location to other peoples?

Can we show customized view on the marker click?

ProManojKumar said:
Can I share my live location to other peoples?
Click to expand...
Click to collapse
Unfortunately site kit and map kit don't allow share your live location to other people. If you want to share your live location, you have to create a background location service and create a server&client system.

ask011 said:
Can we show customized view on the marker click?
Click to expand...
Click to collapse
Sure, you can create a customized view for marker click action. You can create a view and set it on "OnMarkerClickListener" override method.

Related

Create Your Own Image Classification Model in ML Kit (AI Create)

Image classification uses the transfer learning algorithm to perform minute-level learning training on hundreds of images in specific fields (such as vehicles and animals) based on the base classification model with good generalization capabilities, and can automatically generate a model for image classification. The generated model can automatically identify the category to which the image belongs. This is an auto generated model. What if we want to create our image classification model?
In Huawei ML Kit it is possible. The AI Create function in HiAI Foundation provides the transfer learning capability of image classification. With in-depth machine learning and model training, AI Create can help users accurately identify images. In this article we will create own image classification model and we will develop an Android application with using this model. Let’s start.
First of all we need some requirement for creating our model;
You need a Huawei account for create custom model. For more detail click here.
You will need HMS Toolkit. In Android Studio plugins find HMS Toolkit and add plugin into your Android Studio.
You will need Python in our computer. Install Python 3.7.5 version. Mindspore is not used in other versions.
And the last requirements is the model. You will need to find the dataset. You can use any dataset you want. I will use flower dataset. You can find my dataset in here.
Model Creation
Create a new project in Android Studio. Then click HMS on top of the Android Studio screen. Then open Coding Assistant.
1- In the Coding Assistant screen, go to AI and then click AI Create. Set the following parameters, then click Confirm.
Operation type : Select New Model
Model Deployment Location : Select Deployment Cloud.
After click confirm a browser will be opened to log into your Huawei account. After log into your account a window will opened as below.
{
"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- Drag or add the image classification folders to the Please select train image folder area then set Output model file path and train parameters. If you have extensive experience in deep learning development, you can modify the parameter settings to improve the accuracy of the image recognition model. After preparation click Create Model to start training and generate an image classification model.
3- Then it will start training. You can follow the process on log screen:
4- After training successfully completed you will see the screen like below:
In this screen you can see the train result, train parameter and train dataset information of your model. You can give some test data for testing your model accuracy if you want. Here is the sample test results:
5- After confirming that the training model is available, you can choose to generate a demo project.
Generate Demo: HMS Toolkit automatically generates a demo project, which automatically integrates the trained model. You can directly run and build the demo project to generate an APK file, and run the file on the simulator or real device to check the image classification performance.
Using Model Without Generated Demo Project
If you want to use the model in your project you can follow the steps:
1- In your project create an Assests file:
2- Then navigate to the folder path you chose in step 1 in Model Creation. Find your model the extension will be in the form of “.ms” . Then copy your model into Assets file. After we need one more file. Create a txt file containing your model tags. Then copy that file into Assets folder also.
3- Download and add the CustomModelHelper.kt file into your project. You can find repository in here:
https://github.com/iebayirli/AICreateCustomModel
Don’t forget the change the package name of CustomModelHelper class. After the ML Kit SDK is added, its errors will be fixed.
4- After completing the add steps, we need to add maven to the project level build.gradle file to get the ML Kit SDKs. Your gradle file should be like this:
Code:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.3.72"
repositories {
google()
jcenter()
maven { url "https://developer.huawei.com/repo/" }
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.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
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://developer.huawei.com/repo/" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
5- Next, we are adding ML Kit SDKs into our app level build.gradle. And don’t forget the add aaptOption. Your app level build.gradle file should be like this:
Code:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.iebayirli.aicreatecustommodel"
minSdkVersion 26
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
kotlinOptions{
jvmTarget= "1.8"
}
aaptOptions {
noCompress "ms"
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.huawei.hms:ml-computer-model-executor:2.0.3.301'
implementation 'mindspore:mindspore-lite:0.0.7.000'
def activity_version = "1.2.0-alpha04"
// Kotlin
implementation "androidx.activity:activity-ktx:$activity_version"
}
6- Let’s create the layout first:
Code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline1"
android:orientation="horizontal"
app:layout_constraintGuide_percent=".65"/>
<ImageView
android:id="@+id/ivImage"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintDimensionRatio="3:4"
android:layout_margin="16dp"
android:scaleType="fitXY"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/guideline1"/>
<TextView
android:id="@+id/tvResult"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="16dp"
android:autoSizeTextType="uniform"
android:background="@android:color/white"
android:autoSizeMinTextSize="12sp"
android:autoSizeMaxTextSize="36sp"
android:autoSizeStepGranularity="2sp"
android:gravity="center_horizontal|center_vertical"
app:layout_constraintTop_toTopOf="@+id/guideline1"
app:layout_constraintBottom_toTopOf="@+id/btnRunModel"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<Button
android:id="@+id/btnRunModel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Pick Image and Run"
android:textAllCaps="false"
android:background="#ffd9b3"
android:layout_marginBottom="8dp"
app:layout_constraintWidth_percent=".75"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
7- Then lets create const values in our activity. We are creating four values. First value is for permission. Other values are relevant to our model. Your code should look like this:
Code:
companion object {
const val readExternalPermission = android.Manifest.permission.READ_EXTERNAL_STORAGE
const val modelName = "flowers"
const val modelFullName = "flowers" + ".ms"
const val labelName = "labels.txt"
}
8- Then we create the CustomModelHelper example. We indicate the information of our model and where we want to download the model:
Code:
private val customModelHelper by lazy {
CustomModelHelper(
this,
modelName,
modelFullName,
labelName,
LoadModelFrom.ASSETS_PATH
)
}
9- After, we are creating two ActivityResultLauncher instances for gallery permission and image picking with using Activity Result API:
Code:
private val galleryPermission =
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
if (!it)
finish()
}
private val getContent =
registerForActivityResult(ActivityResultContracts.GetContent()) {
val inputBitmap = MediaStore.Images.Media.getBitmap(
contentResolver,
it
)
ivImage.setImageBitmap(inputBitmap)
customModelHelper.exec(inputBitmap, onSuccess = { str ->
tvResult.text = str
})
}
In getContent instance. We are converting selected uri to bitmap and calling the CustomModelHelper exec() method. If the process successfully finish we update textView.
10- After creating instances the only thing we need to is launching ActivityResultLauncher instances into onCreate():
Code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
galleryPermission.launch(readExternalPermission)
btnRunModel.setOnClickListener {
getContent.launch(
"image/*"
)
}
}
11- Let’s bring them all the pieces together. Here is our MainActivity:
Code:
package com.iebayirli.aicreatecustommodel
import android.os.Bundle
import android.provider.MediaStore
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private val customModelHelper by lazy {
CustomModelHelper(
this,
modelName,
modelFullName,
labelName,
LoadModelFrom.ASSETS_PATH
)
}
private val galleryPermission =
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
if (!it)
finish()
}
private val getContent =
registerForActivityResult(ActivityResultContracts.GetContent()) {
val inputBitmap = MediaStore.Images.Media.getBitmap(
contentResolver,
it
)
ivImage.setImageBitmap(inputBitmap)
customModelHelper.exec(inputBitmap, onSuccess = { str ->
tvResult.text = str
})
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
galleryPermission.launch(readExternalPermission)
btnRunModel.setOnClickListener {
getContent.launch(
"image/*"
)
}
}
companion object {
const val readExternalPermission = android.Manifest.permission.READ_EXTERNAL_STORAGE
const val modelName = "flowers"
const val modelFullName = "flowers" + ".ms"
const val labelName = "labels.txt"
}
}
Summary
In summary, we learned how to create a custom image classification model. We used HMS Toolkit for model training. After model training and creation we learned how to use our model in our application. If you want more information about Huawei ML Kit you find in here.
Here is the output:
https://github.com/iebayirli/AICreateCustomModel
Minimum sdk version for this

Find the introduction Sliders and Huawei Account Kit Integration in Money Management Android app (Kotlin) - Part 1

{
"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"
}
Introduction
In this article, we can learn how to integrate the Huawei Account Kit in Money Management app along with introduction slides. The sliders will provide the quick view of the app functionalities. So, I will provide the series of articles on this Money Management App, in upcoming articles I will integrate other Huawei Kits.
Account Kit
Huawei Account Kit provides for developers with simple, secure, and quick sign-in and authorization functions. User is not required to enter accounts, passwords and waiting for authorization. User can click on Sign In with HUAWEI ID button to quickly and securely sign in to the app.
Requirements
1. Any operating system (MacOS, Linux and Windows).
2. Must have a Huawei phone with HMS 4.0.0.300 or later.
3. Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.
4. Minimum API Level 24 is required.
5. Required EMUI 9.0.0 and later version devices.
How to integrate HMS Dependencies
1. First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a Huawei ID.
2. Create a project in android studio, refer Creating an Android Studio Project.
3. Generate a SHA-256 certificate fingerprint.
4. To generate SHA-256 certificate fingerprint. On right-upper corner of android project click Gradle, choose Project Name > Tasks > android, and then click signingReport, as follows.
Note: Project Name depends on the user created name.
5. Create an App in AppGallery Connect.
6. Download the agconnect-services.json file from App information, copy and paste in android Project under app directory, as follows.
7. Enter SHA-256 certificate fingerprint and click Save button, as follows.
Note: Above steps from Step 1 to 7 is common for all Huawei Kits.
8. Click Manage APIs tab and enable Account Kit.
9. Add the below maven URL in build.gradle(Project) file under the repositories of buildscript, dependencies and allprojects, refer Add Configuration.
Java:
maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
10. Add the below plugin and dependencies in build.gradle(Module) file.
Java:
apply plugin: id 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
// Huawei Account Kit
implementation 'com.huawei.hms:hwid:6.3.0.301'
11. Now Sync the gradle.
12. Add the required permission to the AndroidManifest.xml file.
Java:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Let us move to development
I have created a project on Android studio with empty activity let us start coding.
In the MainActivity.kt we can find the business logic for Huawei login button and also introduction slides.
Java:
class MainActivity : AppCompatActivity() {
private var viewPager: ViewPager? = null
private var viewPagerAdapter: ViewPagerAdapter? = null
private lateinit var dots: Array<TextView?>
private var dotsLayout: LinearLayout? = null
companion object {
private lateinit var layouts: IntArray
}
// Account Kit variables
private var mAuthManager: AccountAuthService? = null
private var mAuthParam: AccountAuthParams? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewPager = findViewById(R.id.view_pager)
dotsLayout= findViewById(R.id.layoutDots)
// Introduction slides, create xml files under "app > res > layout"
layouts = intArrayOf(R.layout.slider_1, R.layout.slider_2, R.layout.slider_3,R.layout.slider_4)
addBottomDots(0)
// Making notification bar transparent
changeStatusBarColor()
viewPagerAdapter = ViewPagerAdapter()
viewPager!!.adapter = viewPagerAdapter
viewPager!!.addOnPageChangeListener(viewListener)
// For the next and previous buttons
btn_skip.setOnClickListener { view ->
val intent = Intent([email protected], Home::class.java)
startActivity(intent)
finish()
}
btn_next.setOnClickListener { view ->
val current: Int = getItem(+1)
if (current < layouts.size) {
// Move to another slide
viewPager!!.currentItem = current
} else {
val i = Intent([email protected], Home::class.java)
startActivity(i)
finish()
}
}
// Account kit button click Listener
btn_login.setOnClickListener(mOnClickListener)
}
// Dots functionality
private fun addBottomDots(position: Int) {
dots = arrayOfNulls(layouts!!.size)
val colorActive = resources.getIntArray(R.array.dot_active)
val colorInactive = resources.getIntArray(R.array.dot_inactive)
dotsLayout!!.removeAllViews()
for (i in dots.indices) {
dots!![i] = TextView(this)
dots[i]!!.text = Html.fromHtml("•")
dots[i]!!.textSize = 35f
dots[i]!!.setTextColor(colorInactive[position])
dotsLayout!!.addView(dots[i])
}
if (dots.size > 0) dots[position]!!.setTextColor(colorActive[position])
}
private fun getItem(i: Int): Int {
return viewPager!!.currentItem + i
}
// Viewpager change Listener
private var viewListener: OnPageChangeListener = object : OnPageChangeListener {
override fun onPageSelected(position: Int) {
addBottomDots(position)
// changing the next button text 'NEXT''
if (position == layouts!!.size - 1) {
btn_next.text = "Proceed "
btn_skip.visibility = View.GONE
} else {
btn_next.text = "Next "
btn_skip.visibility = View.VISIBLE
}
}
override fun onPageScrollStateChanged(state: Int) {}
override fun onPageScrolled( position: Int, positionOffset: Float, positionOffsetPixels: Int) {
}
}
// Making notification bar transparent
private fun changeStatusBarColor() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val window = window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = Color.TRANSPARENT
}
}
// PagerAdapter class which will inflate our sliders in our ViewPager
inner class ViewPagerAdapter : PagerAdapter() {
private var layoutInflater: LayoutInflater? = null
override fun instantiateItem(myContainer: ViewGroup, mPosition: Int): Any {
layoutInflater = getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater?
val v: View = layoutInflater!!.inflate(layouts[mPosition], myContainer, false)
myContainer.addView(v)
return v
}
override fun getCount(): Int {
return layouts.size
}
override fun isViewFromObject(mView: View, mObject: Any): Boolean {
return mView === mObject
}
override fun destroyItem(mContainer: ViewGroup, mPosition: Int, mObject: Any) {
val v = mObject as View
mContainer.removeView(v)
}
}
// Account kit, method to send an authorization request.
private fun signIn() {
mAuthParam = AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setIdToken()
.setAccessToken()
.setProfile()
.createParams()
mAuthManager = AccountAuthManager.getService([email protected], mAuthParam)
startActivityForResult(mAuthManager?.signInIntent, 1002)
}
private val mOnClickListener: View.OnClickListener = object : View.OnClickListener {
override fun onClick(v: View?) {
when (v?.id) {
R.id.btn_login -> signIn()
}
}
}
// Process the authorization result.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1002 ) {
val authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data)
if (authAccountTask.isSuccessful) {
Toast.makeText(this, "SigIn success", Toast.LENGTH_LONG).show()
val intent = Intent([email protected], Home::class.java)
startActivity(intent)
} else {
Toast.makeText(this, "SignIn failed: " + (authAccountTask.exception as ApiException).statusCode, Toast.LENGTH_LONG).show()
}
}
}
}
In the activity_main.xml we can create the UI screen for Huawei image button and slides operating buttons.
Java:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="500dp" />
<LinearLayout
android:id="@+id/layoutDots"
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="132dp"
android:gravity="center"
android:orientation="horizontal">
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="3dp"
android:alpha=".5"
android:layout_above="@id/layoutDots"
android:background="@android:color/white" />
<Button
android:id="@+id/btn_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:padding="5dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="85dp"
android:background="@null"
android:textSize="16sp"
android:text="Next"
android:textAllCaps="false"
android:textColor="@color/dot_dark_screen3" />
<Button
android:id="@+id/btn_skip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="85dp"
android:layout_marginLeft="10dp"
android:textSize="16sp"
android:background="@null"
android:textAllCaps="false"
android:text="Skip"
android:textColor="@color/dot_dark_screen3" />
<ImageView
android:id="@+id/btn_login"
android:layout_width="90dp"
android:layout_height="70dp"
android:layout_alignBottom="@id/btn_next"
android:layout_centerHorizontal="true"
android:layout_marginBottom="-83dp"
android:padding="5dp"
android:text="Sign In"
android:textAllCaps="false"
android:textColor="@color/dot_dark_screen1"
app:srcCompat="@drawable/hwid_auth_button_round_black" />
</RelativeLayout>
Create slider_1.xml and placed under layout folder for the slides view and also add the content image in drawable folder. Repeat the same process for another 3 slides also.
Java:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="600dp"
android:background="@drawable/slide_1">
</androidx.constraintlayout.widget.ConstraintLayout>
Demo
Tips and Tricks
1. Make sure you are already registered as Huawei developer.
2. Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.
3. Make sure you have added the agconnect-services.json file to app folder.
4. Make sure you have added SHA-256 fingerprint without fail.
5. Make sure all the dependencies are added properly.
Conclusion
In this article, we have learned how to integrate the Huawei Account Kit in Money Management app along with introduction slides. The sliders will provide the quick view of the app functionalities. So, I will provide the series of articles on this Money Management App, in upcoming articles will integrate other Huawei Kits.
I hope you have read this article. If you found it is helpful, please provide likes and comments.
Reference
Account Kit – Documentation
Account Kit – Training Video

Find the RecyclerView Item Click Listeners to Navigate to Different activities in Quiz Android app (Kotlin) – Part 4

{
"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"
}
Introduction
In this article, we can learn how to click the items of Recyclerview to navigate to different activities in Quiz App. Here, I have given the items in grid view to click each item. So, I will provide a series of articles on this Quiz App, in upcoming articles.
If you are new to this application, follow my previous articles.
https://forums.developer.huawei.com/forumPortal/en/topic/0202877278014350004
https://forums.developer.huawei.com/forumPortal/en/topic/0201884103719030016?fid=0101187876626530001
https://forums.developer.huawei.com/forumPortal/en/topic/0202890333711770040
Requirements
1. Any operating system (MacOS, Linux, and Windows).
2. Must have a Huawei phone with HMS 4.0.0.300 or later.
3. Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.
4. Minimum API Level 24 is required.
5. Required EMUI 9.0.0 and later version devices.
How to integrate HMS Dependencies
1. First register as Huawei developer and complete identity verification on the Huawei developers website, refer to register a Huawei ID.
2. Create a project in android studio, refer Creating an Android Studio Project.
3. Generate a SHA-256 certificate fingerprint.
4. To generate SHA-256 certificate fingerprint. On right-upper corner of android project click Gradle, choose Project Name > Tasks > android, and then click signingReport, as follows.
Note: Project Name depends on the user created name.
5. Create an App in AppGallery Connect.
6. Download the agconnect-services.json file from App information, copy and paste in android Project under app directory, as follows.
7. Enter SHA-256 certificate fingerprint and click Save button, as follows.
Note: Above steps from Step 1 to 7 is common for all Huawei Kits.
8. Add the below maven URL in build.gradle(Project) file under the repositories of buildscript, dependencies and allprojects, refer Add Configuration.
Java:
maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
9. Add the below plugin and dependencies in build.gradle(Module) file.
Java:
apply plugin: id 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
// Recyclerview
implementation 'androidx.recyclerview:recyclerview:1.2.1'
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
10. Now Sync the gradle.
Let us move to development
I have created a project on Android studio with empty activity let us start coding.
In the Home.kt we can find the business logic for button click listeners.
Java:
class Home : AppCompatActivity(), HomeAdapter.ItemListener {
private lateinit var recyclerView: RecyclerView
private lateinit var arrayList: ArrayList<QuesIcons>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
recyclerView = findViewById(R.id.recyclerview_list)
arrayList = ArrayList()
arrayList.add(QuesIcons("Android", R.drawable.android_icon, "#09A9FF"))
arrayList.add(QuesIcons("HMS", R.drawable.huawei_icon, "#3E51B1"))
arrayList.add(QuesIcons("Sports", R.drawable.sports_icon, "#673BB7"))
arrayList.add(QuesIcons("Country Flags", R.drawable.flags_icon, "#4BAA50"))
val adapter = HomeAdapter(applicationContext, arrayList, this)
recyclerView.adapter = adapter
recyclerView.layoutManager = GridLayoutManager(this, 2)
recyclerView.setHasFixedSize(true)
}
override fun onItemClick(item: Int) {
when(item ) {
0 -> {val intent = Intent([email protected], AndroidActivity::class.java)
startActivity(intent)
}
1 -> {val intent = Intent([email protected], HMSActivity::class.java)
startActivity(intent)
}
2 -> {val intent = Intent([email protected], SportsActivity::class.java)
startActivity(intent)
}
3 -> {val intent = Intent([email protected], QuizActivity::class.java)
startActivity(intent)
}
}
}
}
In the HomeAdapter.kt we can find the business logic to holder the adapter items.
Java:
class HomeAdapter(private val mContext: Context, private val mValues: ArrayList<QuesIcons>, private var mListener: ItemListener?) :
RecyclerView.Adapter<HomeAdapter.ViewHolder>() {
inner class ViewHolder(v: View) : RecyclerView.ViewHolder(v), View.OnClickListener {
private val textView: TextView
private val imageView: ImageView
private val relativeLayout: RelativeLayout
private var item: QuesIcons? = null
fun setData(item: QuesIcons) {
this.item = item
textView.text = item.heading
imageView.setImageResource(item.titleImage)
relativeLayout.setBackgroundColor(Color.parseColor(item.colour))
}
override fun onClick(view: View) {
if (mListener != null) {
item?.let { mListener!!.onItemClick(adapterPosition) }
}
}
init {
v.setOnClickListener(this)
textView = v.findViewById<View>(R.id.text_item) as TextView
imageView = v.findViewById<View>(R.id.img_icon) as ImageView
relativeLayout = v.findViewById<View>(R.id.relativeLayout) as RelativeLayout
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view: View = LayoutInflater.from(mContext).inflate(R.layout.home_list, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
viewHolder.setData(mValues[position])
}
override fun getItemCount(): Int {
return mValues.size
}
interface ItemListener {
fun onItemClick(position: Int)
}
}
Create QuesIcons.kt data class to find the declared the data.
Java:
data class QuesIcons(var heading: String, var titleImage: Int, var colour: String)
In the activity_home.xml we can create the recycler view list.
Java:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="8dp"
android:paddingRight="8dp"
tools:context=".Home">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
In the home_list.xml we can create customize view for items.
Java:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="170dp"
android:layout_margin="4dp"
card_view:cardCornerRadius="4dp">
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="10dp"
android:layout_gravity="center">
<ImageView
android:id="@+id/img_icon"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_centerInParent="true"
android:contentDescription="@null"
card_view:tint="@color/white" />
<TextView
android:id="@+id/text_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:textColor="@android:color/white"
android:textSize="16sp"
android:layout_below="@+id/img_icon" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
Demo
Tips and Tricks
1. Make sure you are already registered as Huawei developer.
2. Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.
3. Make sure you have added the agconnect-services.json file to app folder.
4. Make sure you have added SHA-256 fingerprint without fail.
5. Make sure all the dependencies are added properly.
Conclusion
In this article, we have learned how to click the items of Recyclerview to navigate to different activities in Quiz App. Here, we can find the items in grid view to click each item. So, I will provide a series of articles on this Quiz App, in upcoming articles. So, I will provide a series of articles on this Quiz App, in upcoming articles.
I hope you have read this article. If you found it helpful, please provide likes and comments.
Reference
Clik here - https://www.geeksforgeeks.org/android-recyclerview/

Search the hospitals using Huawei Map Kit, Site Kit and Location Kit in Patient Tracking Android app (Kotlin) – Part 5

{
"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"
}
Introduction
In this article, we can learn how to search the hospitals located by source and destination address with HMS Core Kits such as Map, Site, and Location Kits. Map kit is to display maps, it covers map data of more than 200 countries and regions for searching any location address. Location kit provides to get the current location and location updates, and it provides flexible location based services globally to the users. Site kit provides with convenient and secure access to diverse, place-related services to users.
So, I will provide a series of articles on this Patient Tracking App, in upcoming articles I will integrate other Huawei Kits.
If you are new to this application, follow my previous articles.
https://forums.developer.huawei.com/forumPortal/en/topic/0201902220661040078
https://forums.developer.huawei.com/forumPortal/en/topic/0201908355251870119
https://forums.developer.huawei.com/forumPortal/en/topic/0202914346246890032
https://forums.developer.huawei.com/forumPortal/en/topic/0202920411340450018
Map Kit
Map Kit covers map data of more than 200 countries and regions, and supports over 70 languages. User can easily integrate map-based functions into your apps using SDK. It optimizes and enriches the map detail display capability. Map Kit supports gestures including zoom, rotation, moving and tilt gestures to ensure smooth interaction experience.
Location Kit
Location Kit combines the GPS, Wi-Fi and base station location functionalities in your app to build up global positioning capabilities, allows to provide flexible location-based services targeted at users around globally. Currently, it provides three main capabilities: fused location, activity identification and geo-fence. You can call one or more of these capabilities as required.
Site Kit
Site Kit provides the place related services for apps. It provides that to search places with keywords, find nearby place, place suggestion for user search, and find the place details using the unique id.
Requirements
1. Any operating system (MacOS, Linux and Windows).
2. Must have a Huawei phone with HMS 4.0.0.300 or later.
3. Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.
4. Minimum API Level 24 is required.
5. Required EMUI 9.0.0 and later version devices.
How to integrate HMS Dependencies
1. First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a Huawei ID.
2. Create a project in android studio, refer Creating an Android Studio Project.
3. Generate a SHA-256 certificate fingerprint.
4. To generate SHA-256 certificate fingerprint. On right-upper corner of android project click Gradle, choose Project Name > Tasks > android, and then click signingReport, as follows.
Note: Project Name depends on the user created name.
5. Create an App in AppGallery Connect.
6. Download the agconnect-services.json file from App information, copy and paste in android Project under app directory, as follows.
7. Enter SHA-256 certificate fingerprint and click Save button, as follows.
Note: Above steps from Step 1 to 7 is common for all Huawei Kits.
8. Click Manage APIs tab and enable Map Kit, Site Kit and Location Kit.
9. Add the below maven URL in build.gradle(Project) file under the repositories of buildscript, dependencies and allprojects, refer Add Configuration.
Java:
maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
10. Add the below plugin and dependencies in build.gradle(Module) file.
Java:
apply plugin: 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
// Huawei Map
implementation 'com.huawei.hms:maps:6.2.0.301'
// Huawei Site Kit
implementation 'com.huawei.hms:site:6.2.0.301'
// Huawei Location Kit
implementation 'com.huawei.hms:location:6.2.0.300'
11. Now Sync the gradle.
12. Add the required permission to the AndroidManifest.xml file.
Java:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
// To obtain the coarse longitude and latitude of a user with Wi-Fi network or base station.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
// To receive location information from satellites through the GPS chip.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Let us move to development
I have created a project on Android studio with empty activity let us start coding.
In the SearchActivity.kt we can find the business logic.
Java:
class SearchActivity : AppCompatActivity(), OnMapReadyCallback, View.OnClickListener {
private lateinit var hmap: HuaweiMap
private lateinit var mMapView: MapView
private var mMarker: Marker? = null
private var mCircle: Circle? = null
private var isSourceAddressField: Boolean = false
private var pickupLat: Double = 0.0
private var pickupLng: Double = 0.0
private var dropLat: Double = 0.0
private var dropLng: Double = 0.0
private var searchService: SearchService? = null
private var searchIntent: SearchIntent? = null
private lateinit var mFusedLocationProviderClient: FusedLocationProviderClient
companion object {
private const val TAG = "MapViewDemoActivity"
private const val MAPVIEW_BUNDLE_KEY = "MapViewBundleKey"
private val LAT_LNG = LatLng(12.9716, 77.5946)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search)
// Get mapView
mMapView = findViewById(R.id.mapView)
var mapViewBundle: Bundle? = null
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY)
}
// Add "Your API key" in api_key field value
MapsInitializer.setApiKey("DAEDADRgIFzXbAJpOqImvjRAGRkmm3wGTux0O6JBiaddIPMNTJ4SawIN8ZHWu28dtc1f1H3Cqzh0LC1cgYIvBnl1edWVuWkjciH4NA==")
mMapView.onCreate(mapViewBundle)
// get map by async method
mMapView.getMapAsync(this)
//Checking permission
checkLocationPermission()
// Location service
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
//Initialize Search Service
getLocationFromService()
//Initialize OnClickListener
customCurrentLocation.setOnClickListener(this)
pickUpLocation.setOnClickListener(this)
dropLocation.setOnClickListener(this)
}
override fun onMapReady(map: HuaweiMap?) {
Log.d(TAG, "onMapReady: ")
// Get the HuaweiMap instance in this call back method.
hmap = map!!
// Move camera by CameraPosition param, latlag and zoom params can set here.
val build = CameraPosition.Builder().target(LatLng(13.0827, 80.2707)).zoom(10f).build()
val cameraUpdate = CameraUpdateFactory.newCameraPosition(build)
hmap.animateCamera(cameraUpdate)
hmap.setMaxZoomPreference(10f)
hmap.setMinZoomPreference(1f)
// Marker can be add by HuaweiMap
mMarker = hmap.addMarker(
MarkerOptions().position(LAT_LNG)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.garden_icon))
.clusterable(true))
mMarker?.showInfoWindow()
// circle can be add by HuaweiMap
mCircle = hmap.addCircle(
CircleOptions().center(LatLng(28.7041, 77.1025)).radius(45000.0).fillColor(Color.GREEN))
mCircle?.fillColor = Color.TRANSPARENT
}
override fun onStart() {
super.onStart()
mMapView.onStart()
}
override fun onStop() {
super.onStop()
mMapView.onStop()
}
override fun onDestroy() {
super.onDestroy()
mMapView.onDestroy()
}
override fun onPause() {
mMapView.onPause()
super.onPause()
}
override fun onResume() {
super.onResume()
mMapView.onResume()
}
private fun checkLocationPermission() {
// check location permission
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
if (ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
val strings = arrayOf(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION)
ActivityCompat.requestPermissions(this, strings, 1)
}
} else {
if (ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,"android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
val strings = arrayOf(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION,
"android.permission.ACCESS_BACKGROUND_LOCATION")
ActivityCompat.requestPermissions(this, strings, 2)
}
}
}
private fun getLocationFromService() {
// Add your API Key in encode
searchService = SearchServiceFactory.create(this,
URLEncoder.encode("Add your api_key"))
}
override fun onClick(v: View?) {
val id = v?.id
if (id == R.id.pickUpLocation) {
locationBox(100)
} else if (id == R.id.dropLocation) {
locationBox(101)
} else if (id == R.id.customCurrentLocation) {
getLastLocation()
}
}
private fun locationBox(requestcode: Int) {
searchIntent = SearchIntent()
searchIntent!!.setApiKey(URLEncoder.encode("DAEDADRgIFzXbAJpOqImvjRAGRkmm3wGTux0O6JBiaddIPMNTJ4SawIN8ZHWu28dtc1f1H3Cqzh0LC1cgYIvBnl1edWVuWkjciH4NA==", "utf-8"))
val intent = searchIntent!!.getIntent(this)
startActivityForResult(intent, requestcode)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, @Nullable data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 100) {
if (SearchIntent.isSuccess(resultCode)) {
isSourceAddressField = true
val site: Site = searchIntent!!.getSiteFromIntent(data)
pickUpLocation.setText(site.name)
querySuggestion()
}
}
if (requestCode == 101) {
if (SearchIntent.isSuccess(resultCode)) {
isSourceAddressField = false
val site: Site = searchIntent!!.getSiteFromIntent(data)
dropLocation.setText(site.name)
querySuggestion()
}
}
}
private fun querySuggestion() {
val request = QuerySuggestionRequest()
val query: String?
if (isSourceAddressField) {
query = pickUpLocation?.text.toString()
}else{
query = dropLocation?.text.toString()
}
if (!TextUtils.isEmpty(query)) {
request.query = query
}
searchService?.querySuggestion(
request,
searchResultListener as SearchResultListener<QuerySuggestionResponse>?
)
}
private var searchResultListener =
object : SearchResultListener<QuerySuggestionResponse> {
override fun onSearchResult(results: QuerySuggestionResponse?) {
val stringBuilder = StringBuilder()
results?.let {
val sites = results.sites
if (sites != null && sites.size > 0) {
for (site in sites) {
val location = site.location
if (isSourceAddressField) {
pickupLat = location.lat
pickupLng = location.lng
moveCamera(LatLng(pickupLat, pickupLng))
} else {
dropLat = location.lat
dropLng = location.lng
moveCamera(LatLng(dropLat, dropLng))
}
break
}
} else {
stringBuilder.append("0 results")
}
}
}
override fun onSearchError(status: SearchStatus) {
}
}
private fun getLastLocation() {
try {
val lastLocation = mFusedLocationProviderClient.lastLocation
lastLocation.addOnSuccessListener(OnSuccessListener { location ->
if (location == null) {
[email protected]
}
moveCamera(LatLng(location.latitude, location.longitude))
[email protected]
}).addOnFailureListener { e ->
}
} catch (e: Exception) {
}
}
private fun moveCamera(latLng: LatLng) {
hmap!!.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15f))
}
}
In the activity_search.xml we can create the UI screen.
Java:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".search.SearchActivity">
<com.huawei.hms.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.huawei.hms.maps.MapView>
<RelativeLayout
android:id="@+id/startpoint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="42dp"
android:layout_marginTop="42dp"
android:layout_marginRight="62dp"
android:background="@drawable/blue_border_rounded_cornwe">
<EditText
android:id="@+id/pickUpLocation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/start_loc"
android:background="@android:color/transparent"
android:hint="Choose starting point "
android:maxLines="1"
android:paddingLeft="17dp"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:textSize="13sp">
</EditText>
<ImageView
android:id="@+id/start_loc"
android:layout_width="20dp"
android:layout_height="17dp"
android:layout_centerVertical="true"
android:layout_marginLeft="17dp"
android:src="@drawable/start_icon" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="42dp"
android:layout_marginTop="23dp"
android:layout_marginRight="62dp"
android:layout_below="@+id/startpoint"
android:background="@drawable/blue_border_rounded_cornwe">
<EditText
android:id="@+id/dropLocation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/dest_loc"
android:background="@android:color/transparent"
android:hint="Password"
android:maxLines="1"
android:paddingLeft="17dp"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:textSize="13sp">
</EditText>
<ImageView
android:id="@+id/dest_loc"
android:layout_width="20dp"
android:layout_height="17dp"
android:layout_centerVertical="true"
android:layout_marginLeft="17dp"
android:src="@drawable/dest_icon" />
</RelativeLayout>
<ImageView
android:id="@+id/customCurrentLocation"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="10dp"
android:baselineAlignBottom="true"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="@drawable/location_icon"/>
</RelativeLayout>
Demo
Tips and Tricks
1. Make sure you are already registered as Huawei developer.
2. Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.
3. Make sure you have added the agconnect-services.json file to app folder.
4. Make sure you have added SHA-256 fingerprint without fail.
5. Make sure all the dependencies are added properly.
Conclusion
In this article, we can learn how to search the hospitals located by source and destination address with HMS Core Kits such as Map, Site, and Location Kits. Map kit is to display maps, it covers map data of more than 200 countries and regions for searching any location address. Location kit provides to get the current location and location updates, and it provides flexible location based services globally to the users. Site kit provides with convenient and secure access to diverse, place-related services to users.
I hope you have read this article. If you found it is helpful, please provide likes and comments.
Reference
Map Kit - Documentation
Map Kit – Training Video
Location Kit – Documentation
Location Kit – Training Video
Site Kit

Capture Hospital details using a Barcode scan by Huawei Scan kit in Android (Kotlin) – Part 6

{
"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"
}
Introduction
In this article, we can learn how to save the hospital details by scanning the barcode and saving the details in your contacts directory using Huawei Scan Kit. Due to busy days like journey, office work and personal work, users are not able to save many details. So, this app helps you to save the hospital information by just one scan of barcode from your phone such as Hospital Name, Contact Number, Email address, Website etc.
So, I will provide a series of articles on this Patient Tracking App, in upcoming articles I will integrate other Huawei Kits.
If you are new to this application, follow my previous articles.
https://forums.developer.huawei.com/forumPortal/en/topic/0201902220661040078
https://forums.developer.huawei.com/forumPortal/en/topic/0201908355251870119
https://forums.developer.huawei.com/forumPortal/en/topic/0202914346246890032
https://forums.developer.huawei.com/forumPortal/en/topic/0202920411340450018
https://forums.developer.huawei.com/forumPortal/en/topic/0202926518891830059
What is scan kit?
HUAWEI Scan Kit scans and parses all major 1D and 2D barcodes and generates QR codes, helps you to build quickly barcode scanning functions into your apps.
HUAWEI Scan Kit automatically detects, magnifies and identifies barcodes from a distance and also it can scan a very small barcode in the same way. It supports 13 different formats of barcodes, as follows.
1D barcodes: EAN-8, EAN-13, UPC-A, UPC-E, Codabar, Code 39, Code 93, Code 128 and ITF
2D barcodes: QR Code, Data Matrix, PDF 417 and Aztec
Requirements
1. Any operating system (MacOS, Linux and Windows).
2. Must have a Huawei phone with HMS 4.0.0.300 or later.
3. Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 installed.
4. Minimum API Level 19 is required.
5. Required EMUI 9.0.0 and later version devices.
How to integrate HMS Dependencies
1. First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a Huawei ID.
2. Create a project in android studio, refer Creating an Android Studio Project.
3. Generate a SHA-256 certificate fingerprint.
4. To generate SHA-256 certificate fingerprint. On right-upper corner of android project click Gradle, choose Project Name > Tasks > android, and then click signingReport, as follows.
Note: Project Name depends on the user created name.
5. Create an App in AppGallery Connect.
6. Download the agconnect-services.json file from App information, copy and paste in android Project under app directory, as follows.
7. Enter SHA-256 certificate fingerprint and click tick icon, as follows.
Note: Above steps from Step 1 to 7 is common for all Huawei Kits.
8. Add the below maven URL in build.gradle(Project) file under the repositories of buildscript, dependencies and allprojects, refer Add Configuration.
Java:
maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
9. Add the below plugin and dependencies in build.gradle(Module) file.
Java:
apply plugin: 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.5.0.300'
// Scan Kit
implementation 'com.huawei.hms:scan:1.2.5.300'
10. Now Sync the gradle.
11. Add the required permission to the AndroidManifest.xml file.
Java:
<!-- Camera permission -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- File read permission -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
Let us move to development
I have created a project on Android studio with empty activity let's start coding.
In the ScanActivity.kt we can find the button click.
Java:
class ScanActivity : AppCompatActivity() {
companion object{
private val CUSTOMIZED_VIEW_SCAN_CODE = 102
}
private var resultText: TextView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scan)
resultText = findViewById<View>(R.id.result) as TextView
requestPermission()
}
fun onCustomizedViewClick(view: View?) {
resultText!!.text = ""
this.startActivityForResult(Intent(this, BarcodeScanActivity::class.java), CUSTOMIZED_VIEW_SCAN_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode != RESULT_OK || data == null) {
return
}
// Get return value of HmsScan from the value returned by the onActivityResult method by ScanUtil.RESULT as key value.
val obj: HmsScan? = data.getParcelableExtra(ScanUtil.RESULT)
try {
val json = JSONObject(obj!!.originalValue)
// Log.e("Scan","Result "+json.toString())
val name = json.getString("hospital name")
val phone = json.getString("phone")
val mail = json.getString("email")
val web = json.getString("site")
val i = Intent(Intent.ACTION_INSERT_OR_EDIT)
i.type = ContactsContract.Contacts.CONTENT_ITEM_TYPE
i.putExtra(ContactsContract.Intents.Insert.NAME, name)
i.putExtra(ContactsContract.Intents.Insert.PHONE, phone)
i.putExtra(ContactsContract.Intents.Insert.EMAIL, mail)
i.putExtra(ContactsContract.Intents.Insert.COMPANY, web)
startActivity(i)
} catch (e: JSONException) {
e.printStackTrace()
Toast.makeText(this, "JSON exception", Toast.LENGTH_SHORT).show()
} catch (e: Exception) {
e.printStackTrace()
Toast.makeText(this, "Exception", Toast.LENGTH_SHORT).show()
}
}
private fun requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(arrayOf(android.Manifest.permission.CAMERA, READ_EXTERNAL_STORAGE),1001)
}
}
@SuppressLint("MissingSuperCall")
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String?>, grantResults: IntArray) {
if (permissions == null || grantResults == null || grantResults.size < 2 || grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) {
requestPermission()
}
}
}
In the BarcodeScanActivity.kt we can find the code to scan barcode.
Java:
class BarcodeScanActivity : AppCompatActivity() {
companion object {
private var remoteView: RemoteView? = null
//val SCAN_RESULT = "scanResult"
var mScreenWidth = 0
var mScreenHeight = 0
//scan view finder width and height is 350dp
val SCAN_FRAME_SIZE = 300
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_barcode_scan)
// 1. get screen density to calculate viewfinder's rect
val dm = resources.displayMetrics
val density = dm.density
// 2. get screen size
mScreenWidth = resources.displayMetrics.widthPixels
mScreenHeight = resources.displayMetrics.heightPixels
val scanFrameSize = (SCAN_FRAME_SIZE * density).toInt()
// 3. Calculate viewfinder's rect, it is in the middle of the layout.
// set scanning area(Optional, rect can be null. If not configure, default is in the center of layout).
val rect = Rect()
rect.left = mScreenWidth / 2 - scanFrameSize / 2
rect.right = mScreenWidth / 2 + scanFrameSize / 2
rect.top = mScreenHeight / 2 - scanFrameSize / 2
rect.bottom = mScreenHeight / 2 + scanFrameSize / 2
// Initialize RemoteView instance and set calling back for scanning result.
remoteView = RemoteView.Builder().setContext(this).setBoundingBox(rect).setFormat(HmsScan.ALL_SCAN_TYPE).build()
remoteView?.onCreate(savedInstanceState)
remoteView?.setOnResultCallback(OnResultCallback { result -> //judge the result is effective
if (result != null && result.size > 0 && result[0] != null && !TextUtils.isEmpty(result[0].getOriginalValue())) {
val intent = Intent()
intent.putExtra(ScanUtil.RESULT, result[0])
setResult(RESULT_OK, intent)
this.finish()
}else{
Log.e("Barcode","Barcode: No barcode recognized ")
}
})
// Add the defined RemoteView to page layout.
val params = FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
val frameLayout = findViewById<FrameLayout>(R.id.rim1)
frameLayout.addView(remoteView, params)
}
// Manage remoteView lifecycle
override fun onStart() {
super.onStart()
remoteView?.onStart()
}
override fun onResume() {
super.onResume()
remoteView?.onResume()
}
override fun onPause() {
super.onPause()
remoteView?.onPause()
}
override fun onDestroy() {
super.onDestroy()
remoteView?.onDestroy()
}
override fun onStop() {
super.onStop()
remoteView?.onStop()
}
}
In the activity_scan.xml we can create the UI screen.
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".scan.ScanActivity">
<Button
android:id="@+id/btn_click"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:textAllCaps="false"
android:textSize="20sp"
android:layout_gravity="center"
android:text="Click to Scan"
android:onClick="onCustomizedViewClick"
tools:ignore="OnClick" />
<TextView
android:id="@+id/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginTop="80dp"
android:textColor="#C0F81E"/>
</LinearLayout>
In the activity_barcode_scan.xml we can create the frame layout.
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".scan.BarcodeScanActivity">
// customize layout for camera preview to scan
<FrameLayout
android:id="@+id/rim1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#C0C0C0" />
// customize scanning mask
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:alpha="0.1"
android:background="#FF000000"/>
// customize scanning view finder
<ImageView
android:id="@+id/scan_view_finder"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:background="#1f00BCD4"
tools:ignore="MissingConstraints" />
</RelativeLayout>
Demo
Find the demo in attachment or click here for original content.
Tips and Tricks
1. Make sure you are already registered as Huawei developer.
2. Set minSDK version to 19 or later, otherwise you will get AndriodManifest merge issue.
3. Make sure you have added the agconnect-services.json file to app folder.
4. Make sure you have added SHA-256 fingerprint without fail.
5. Make sure all the dependencies are added properly.
Conclusion
In this article, we can learn how to save the hospital details by scanning the barcode and saving the details in your contacts directory using Huawei Scan Kit. Due to busy days like journey, office work and personal work, users are not able to save many details. So, this app helps you to save the hospital information by just one scan of barcode from your phone such as Hospital Name, Contact Number, Email address, Website etc.
Reference
Scan Kit - Customized View
Scan Kit - Training Video

Categories

Resources