[Huawei Developers] Berk Özyurt:
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.

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.

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.

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.

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:

<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.

<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.

<?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.

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:

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:

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.

searchService = SearchServiceFactory.create(getContext(), “API KEY HERE”);

Finally, mapView should be created like this :

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 :

@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.

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 :

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.