[Huawei Developers] Mike-mei:
Background​

Lots of apps these days include an in-app map feature and the ability to mark places of interest on the map. HMS Core Map Kit enables you to implement such capabilities for your apps. With Map Kit, you can first draw a map and then add markers to the map, as well as configure the map to cluster markers depending on the level of zoom. This article will show you how to implement searching for nearby places using the keyword search capability of Site Kit and display the results on the map.

Application scenarios:

A travel app that allows users to search for scenic spots and shows the results on a map.

2.A bicycle sharing app that can show users nearby bicycles on a map.

Key functions used in the project:

Location service: Use Location Kit to obtain the current longitude-latitude coordinates of a device.

Keyword search: Use Site Kit to search for places such as scenic spots, businesses, and schools in the specified geographical area based on the specified keyword.

Map display: Use Map Kit to draw a map. Marker clustering: Use Map Kit to add markers to the map and configure the map to cluster markers depending on the level of zoom.

Integration Preparations​

1.Register as a developer and create a project in AppGallery Connect.

(1)Register as a developer Registration URL

View attachment 5456117

(2)Create an app, add the SHA-256 signing certificate fingerprint, enable Map Kit and Site Kit, and download the agconnect-services.json file of the app.

View attachment 5456119

2.Integrate the Map SDK and Site SDK.

(1)Copy the agconnect-services.json file to the app's directory of your project.

Go to allprojects > repositories and configure the Maven repository address for the HMS Core SDK.

Go to buildscript > repositories and configure the Maven repository address for the HMS Core SDK.

If the agconnect-services.json file has been added to the app, go to buildscript > dependencies and add the AppGallery Connect plugin configuration.

buildscript {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
classpath 'com.huawei.agconnect:agcp:1.3.1.300'
}
}
allprojects {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
google()
jcenter()
}
}

(2)Add build dependencies in the dependencies block.

dependencies {
implementation 'com.huawei.hms:maps:{version}'
implementation 'com.huawei.hms:site:{version}'
implementation 'com.huawei.hms:location:{version}'
}

(3)Add the following configuration to the file header:

apply plugin: 'com.huawei.agconnect'

(4)Copy the signing certificate generated in Generating a Signing Certificate to the app directory of your project, and configure the signing certificate in android in the build.gradle file.

signingConfigs {
release {
// Signing certificate.
storeFile file("**.**")
// KeyStore password.
storePassword "******"
// Key alias.
keyAlias "******"
// Key password.
keyPassword "******"
v2SigningEnabled true
v2SigningEnabled true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
debuggable true
}
debug {
debuggable true
}
}

Main Code and Used Functions​

1.Use Location Kit to obtain the device location.

private void getMyLoction() {

fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
SettingsClient settingsClient = LocationServices.getSettingsClient(this);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
mLocationRequest = new LocationRequest();
builder.addLocationRequest(mLocationRequest);
LocationSettingsRequest locationSettingsRequest = builder.build();
//Check the device location settings.
settingsClient.checkLocationSettings(locationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
//Initiate location requests when the location settings meet the requirements.
fusedLocationProviderClient
.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
// Processing when the API call is successful.
Log.d(TAG, "onSuccess: " + aVoid);
}
});
}
})

2.Implement the text search function using Site Kit to search for nearby places.

SearchResultListener<TextSearchResponse> resultListener = new SearchResultListener<TextSearchResponse>() {
// Return search results upon a successful search.
@Override
public void onSearchResult(TextSearchResponse results) {
List<Site> siteList;
if (results == null || results.getTotalCount() <= 0 || (siteList = results.getSites()) == null
|| siteList.size() <= 0) {
resultTextView.setText("Result is Empty!");
return;
}
updateClusterData(siteList);// Mark places on the map.
}

// Return the result code and description upon a search exception.
@Override
public void onSearchError(SearchStatus status) {
resultTextView.setText("Error : " + status.getErrorCode() + " " + status.getErrorMessage());
}
};
// Call the place search API.
searchService.textSearch(request, resultListener);

3.Draw a map

@Override
public void onMapReady(HuaweiMap huaweiMap) {
hMap = huaweiMap;
hMap.moveCamera(CameraUpdateFactory.newLatLngZoom(Constants.sMylatLng, 1));
hMap.setMyLocationEnabled(true);
hMap.getUiSettings().setMyLocationButtonEnabled(true);
initCluster(huaweiMap);

}

4.Cluster markers on the map.

private ClusterManager<MyItem> mClusterManager;
List<MyItem> items = new ArrayList<>();

private void initCluster(HuaweiMap hMap) {
mClusterManager = new ClusterManager<>(this, hMap);
hMap.setOnCameraIdleListener(mClusterManager);
// Add a custom InfoWindowAdapter by setting it to the MarkerManager.Collection object from
// ClusterManager rather than from GoogleMap.setInfoWindowAdapter
//refer: https://github.com/billtom20/3rd-maps-utils
mClusterManager.getMarkerCollection().setInfoWindowAdapter(new HuaweiMap.InfoWindowAdapter() {
@Override
public View getInfoWindow(Marker marker) {
final LayoutInflater inflater = LayoutInflater.from(SearchClusterActivity.this);
final View view = inflater.inflate(R.layout.custom_marker_window, null);
final TextView textView = view.findViewById(R.id.textViewTitle);
String text = (marker.getTitle() != null) ? marker.getTitle() : "Cluster Item";
textView.setText(text);
return view;
}

@Override
public View getInfoContents(Marker marker) {
return null;
}
});

}
// Update clustered markers.
private void updateClusterData(List<Site> siteList) {
items = new ArrayList<>();
mClusterManager.clearItems();
for (Site s:
siteList) {
Coordinate location = s.getLocation();
MyItem myItem = new MyItem(location.lat,location.lng,s.name,s.formatAddress);
items.add(myItem);
}
mClusterManager.addItems(items);
Coordinate coordinate = siteList.get(0).getLocation();
LatLng latLng = new LatLng(coordinate.lat,coordinate.lng);
mClusterManager.cluster();
hMap.animateCamera(CameraUpdateFactory.newLatLngZoom (latLng,14 ));
}

Results​

Enter a place or service in the Query box and tap Search. The figures below show how the search results are displayed as markers on the map.

View attachment 5456121

View attachment 5456123

The preceding four figures show the effect of searching for food and school, as well as the marker clustering effect at different zoom levels. Congratulations, you have now successfully integrated place search and marker clustering into your in-app map.

References​

For more details, you can go to:official website

Development Documentation page, to find the documents you need

Reddit to join our developer discussion

GitHub to download sample codes

Stack Overflow to solve any integration problems