Adding Map to Your Application Using HMS Core Map Kit — “My Diary” Study Case (Part 1)

Halimkenneth
10 min readJul 23, 2021

--

Team Name: The Clowns

Team Member: William Chrisandy, Hanna Nadia Savira, Halimkenneth

This is a case study that explains how to implement HMS Core in our application that can be downloaded at the following link:

My Diary

About The Apps

My Diary is an app to keep your memory that works like a physical diary. You can write multiple diaries and tag them with a date to keep you reminded of the events. You can also add some locations to each diary to keep you reminded where the event happened.

My Diary also provides you an alert dialog to prevent you from accidentally pressing back and lost all your changes. This application will also you many appropriate warn and completion statuses.

My Diary is made for you to ease up your life. You can find five or more locations at one time. You can click on the info window above the marker to select the location you wanted to add to the diary. To be able to use this feature, you have to grant access to the location permission. You can also view your location and explore the map in this feature. However, you can still run all the diary functionality, excluding the location feature without giving the location permission.

Here are some screenshots from the application:

Disclaimers

The following steps can also be found in the Huawei Developer documentation. This is just a step-by-step tutorial to use the HMS Core for your application.

Preparation

Before you get started, you must register as a Huawei developer and complete identity verification on HUAWEI Developers. For details, please refer to Registration and Verification.

We can follow instructions in Creating a Project to create a project. The signing certificate fingerprint is used to verify the authenticity of an app. Before releasing an app, you must generate a signing certificate fingerprint locally based on the signing certificate and configure it in AppGallery Connect. You can configure the Signing Certificate Fingerprint with the following steps:

  1. Sign in to AppGallery Connect and click My projects.
  2. Find your app project, and click the desired app name.
  3. Go to Project settings > General information. In the App information area, click the add icon next to SHA-256 certificate fingerprint, and enter the obtained SHA-256 certificate fingerprint.
  4. After completing the configuration, click on the check icon.

Add an app to your project. For details, please refer to Creating an App. Set relevant parameters as follows:

  • Platform: Android
  • Device: Mobile phone
  • App category: App or Game

The application use Recycler View to display the data and SQLite Database to save the data. For more information about this, you can refer to the link that can be accessed in the references section.

To use Map Kit, you need to enable it in AppGallery Connect. For details, please refer to Enabling a Service.

We can configure the Maven Repository Address for the HMS Core SDK with the following steps:

  1. Open the build.gradle file in the root directory of your Android Studio project.
  2. Add the AppGallery Connect plugin and the Maven repository.
  • Go to buildscript > repositories and configure the Maven repository address for the HMS Core SDK.
  • Go to allprojects > 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 {
google()
jcenter()
// Configure the Maven repository address for the HMS Core SDK.
maven {url 'https://developer.huawei.com/repo/'}
}
dependencies {
...
// Add the AppGallery Connect plugin configuration.
classpath 'com.huawei.agconnect:agcp:1.4.2.300'
}
}
allprojects {
repositories {
google()
jcenter()
// Configure the Maven repository address for the HMS Core SDK.
maven {url 'https://developer.huawei.com/repo/'}
}
}

We can add Build Dependencies with the following steps:

  • Open the app-level build.gradle file.
  • Add a build dependency in the dependencies block.
dependencies {
implementation 'com.huawei.hms:maps:{version}'
}
  • Add the following information under apply plugin: ‘com.android.application’ in the file header:
apply plugin: ‘com.huawei.agconnect’
  • 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.
android {
signingConfigs {
release {
// Signing certificate.
storeFile file("**.**")
// KeyStore password.
storePassword "******"
// Alias.
keyAlias "******"
// Key password.
keyPassword "******"
v2SigningEnabled true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
signingConfig signingConfigs.release
}
}
}

After completing the preceding configuration, click the synchronization icon on the toolbar to synchronize the Gradle files.

Add the following code to the application element in the AndroidManifest.xml file, prompting users to download HMS Core (APK):

<application ...>
<meta-data
android:name="com.huawei.hms.client.channel.androidMarket"
android:value="false" />
...
</application>

After HMS Core (APK) is downloaded, the HMS Core SDK will automatically install or update HMS Core (APK).

In Android 11, the way for an app to query other apps on the user device and interact with them has been changed. If targetSdkVersion is 30 or later for your app, add the <queries> element in the manifest element in AndroidManifest.xml to allow your app to access HMS Core (APK).

<manifest ...>
...
<queries>
<intent>
<action android:name="com.huawei.hms.core.aidlservice" />
</intent>
</queries>
...
</manifest>

To call capabilities of Map Kit, you must apply for the following permissions for your app in the AndroidManifest.xml file:

<!-- Allow the app to access Internet.-->
<uses-permission android:name="android.permission.INTERNET"/>
<!--Allow the app to query the network status.-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- Allow the app to read common data. -->
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
<!-- Allow the app to change the WLAN status. -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

To obtain the current device location, you need to add the following permissions to the AndroidManifest.xml file. In Android 6.0 and later, you need to apply for these permissions dynamically.

<!-- Allow the app to obtain the coarse longitude and latitude of a user through the Wi-Fi network or base station. -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- Allow the app to receive location information from satellites through the GPS chip. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

After declaring permissions in the AndroidManifest.xml file, apply for the permissions dynamically in the code (according to requirements for dangerous permissions in Android 6.0).

if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P)
{
if (ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
String[] strings = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
ActivityCompat.requestPermissions(this, strings, 1);
}
}
else
{
if (ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, "android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED)
{
String[] strings =
{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION
};
ActivityCompat.requestPermissions(this, strings, 2);
}
}

Implementation

The following describes how to create a map instance using SupportMapFragment.

  • Add a Fragment object in the layout file (for example, activity_location.xml), and set map attributes in the file.
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/mapfragment_mapfragmentdemo"
class="com.huawei.hms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:cameraTargetLat="48.893478"
map:cameraTargetLng="2.334595"
map:cameraZoom="10" />
  • To use a map in your app, implement the OnMapReadyCallback API. The sample code is as follows:
public class SupportMapDemoActivity extends AppCompatActivity implements OnMapReadyCallback {
...
}
  • In the activity, we need to initialize the map and then load SupportMapFragment in the onCreate() method and call getMapAsync() to register the callback. The sample code is as follows:
MapsInitializer.setApiKey(getString(R.string.api_key));super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location);
private SupportMapFragment mSupportMapFragment;
mSupportMapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapfragment_mapfragmentdemo);
mSupportMapFragment.getMapAsync(this);
public void onMapReady(HuaweiMap huaweiMap) {
Log.d(TAG, "onMapReady: ");
hMap = huaweiMap;
}
  • Run your project and then install your app to view the map in your app

You can also add the my-location function to the Map. The my-location function allows users to get their current locations when using your app. Before using this function, ensure that your app has been granted location permission. The Android OS provides two location permissions: ACCESS_COARSE_LOCATION (approximate location permission) and ACCESS_FINE_LOCATION (precise location permission). Call the setMyLocationEnabled(true) method of the HuaweiMap object to enable this function. The sample code is as follows:

@RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
@Override
public void onMapReady(HuaweiMap map){
hMap = map;
// Enable the my-location layer.
hMap.setMyLocationEnabled(true);
// Enable the my-location icon.
hMap.getUiSettings().setMyLocationButtonEnabled(true);
}

Once this function has been enabled, the my-location icon will be displayed in the lower right corner of the map by default and the user’s current location will be displayed as a blue dot. When a user taps this icon, the user’s current location (if obtained) will be displayed in the center of the screen. After you set a listener for the my-location icon and a user taps the icon, the onMyLocationButtonClick() callback of HuaweiMap.OnMyLocationButtonClickListener will be triggered. You can the map to do something with it. The sample code is as follows:

hMap.setOnMyLocationButtonClickListener(new HuaweiMap.OnMyLocationButtonClickListener() {
@Override
public boolean onMyLocationButtonClick() {
Toast.makeText(getApplicationContext(), "MyLocation button clicked", Toast.LENGTH_SHORT).show();
return false;
}
});

Huawei maps are moved by simulating camera movement. You can control the visible region of a map by changing the camera’s position. To change the camera’s position, create different types of CameraUpdate objects using the CameraUpdateFactory class, and use these objects to move the camera. The sample code is as follows:

// Method 1: Increase the camera zoom level by 1 and retain other attribute settings.
CameraUpdate cameraUpdate = CameraUpdateFactory.zoomIn();
// Method 2: Decrease the camera zoom level by 1 and retain other attribute settings.
CameraUpdate cameraUpdate1 = CameraUpdateFactory.zoomOut();
// Method 3: Set the camera zoom level to a specified value and retain other attribute settings.
float zoom = 8.0f;
CameraUpdate cameraUpdate2 = CameraUpdateFactory.zoomTo(zoom);
// Method 4: Increase or decrease the camera zoom level by a specified value.
float amount = 2.0f;
CameraUpdate cameraUpdate3 = CameraUpdateFactory.zoomBy(amount);
// Method 5: Move the camera to the specified center point and increase or decrease the camera zoom level
// by a specified value.
Point point = new Point(31, 118);
float amount = 2.0f;
CameraUpdate cameraUpdate4 = CameraUpdateFactory.zoomBy(amount, point);
// Method 6: Set the latitude and longitude of the camera and retain other attribute settings.
LatLng latLng1 = new LatLng(31.5, 118.9);
CameraUpdate cameraUpdate5 = CameraUpdateFactory.newLatLng(latLng1);
// Method 7: Set the visible region and padding.
int padding = 100;
LatLng latLng1 = new LatLng(31.5, 118.9);
LatLng latLng2 = new LatLng(32.5, 119.9);
LatLngBounds latLngBounds = new LatLngBounds(latLng1, latLng2);
CameraUpdate cameraUpdate6 = CameraUpdateFactory.newLatLngBounds(latLngBounds, padding);
// Method 8: Set the center point and zoom level of the camera.
float zoom = 0.0f;
LatLng latLng2 = new LatLng(32.5, 119.9);
CameraUpdate cameraUpdate7 = CameraUpdateFactory.newLatLngZoom(latLng2, zoom);
// Method 9: Scroll the camera by specified number of pixels.
float x = 100.0f;
float y = 100.0f;
CameraUpdate cameraUpdate8 = CameraUpdateFactory.scrollBy(x, y);
// Method 10: Specify the camera position.
// Set the tilt.
float tilt = 2.2f;
// Set the bearing.
float bearing = 31.5f;
CameraPosition cameraPosition = new CameraPosition(latLng1,zoom,tilt,bearing);
CameraUpdate cameraUpdate9 = CameraUpdateFactory.newCameraPosition(cameraPosition);

You can also add markers to a map to identify locations such as stores and buildings, and provide location details with information windows. The following sample code uses the default icon to add a simple marker to a map. The sample code is as follows:

private Marker mMarker;public void addMarker(View view) {
if (null != mMarker) {
mMarker.remove();
}
MarkerOptions options = new MarkerOptions()
.position(new LatLng(48.893478, 2.334595))
.title("Hello Huawei Map")
.snippet("This is a snippet!");
mMarker = hMap.addMarker(options);
}

You can also add a listener to the info window of the marker. The sample code is as follows:

hMap.setOnInfoWindowClickListener(new HuaweiMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
Toast.makeText(getApplicationContext(), "onInfoWindowClick:" + marker.getTitle(), Toast.LENGTH_SHORT).show();
}
});

In the My Diary application, we will add the marker after we use the HMS Core Site Kit. The info window is used to add the location to the database. For further information, you can check it in part 2 and part 3 of this case study.

Other Parts

Check out other parts of this study case here:

Adding Location Using HMS Core Site Kit Query Autocomplete — “My Diary” Study Case (Part 2)

Viewing Location Using HMS Core Site Kit Place Detail Search — “My Diary” Study Case (Part 3)

References

Google Developers Training Team. (2018). 4.5: RecyclerView. Retrieved July 22, 2021, from https://google-developer-training.github.io/android-developer-fundamentals-course-concepts-v2/unit-2-user-experience/lesson-4-user-interaction/4-5-c-recyclerview/4-5-c-recyclerview.html

Google Developers Training Team. (2018). 10.0: SQLite primer. Retrieved July 22, 2021, from https://google-developer-training.github.io/android-developer-fundamentals-course-concepts-v2/unit-4-saving-user-data/lesson-10-storing-data-with-room/10-0-c-sqlite-primer/10-0-c-sqlite-primer.html#sqlite

Huawei Developers. (2021). About The Service. Retrieved July 22, 2021, from https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-sdk-introduction-0000001061991291

Huawei Developers. (2021). About The Service. Retrieved July 22, 2021, from https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-sdk-about-the-service-0000001076188604

--

--