[Huawei Developers] muraliameakula:
Overview

In this article, I will create HMS Map Kit based Demo App which highlights the use case of Basic Map and Polyline. I have integrated HMS Map Kit which is based on Cross-platform Technology Xamarin.

HMS Map Kit Service Introduction

HMS Core Map SDK is a set of APIs for map development in Android. The map data covers most countries outside China and supports multiple languages. The Map SDK uses the WGS 84 GPS coordinate system, which can meet most requirements of map development outside China. You can easily add map-related functions in your Android app, including:

1. Map display: Displays buildings, roads, water systems, and Points of Interest (POIs).

2. Map interaction: Controls the interaction gestures and buttons on the map.

3. Map drawing: Adds location markers, map layers, overlays, and various shapes

Prerequisite

1. Xamarin Framework

2. Huawei phone

3. Visual Studio 2019

App Gallery Integration process

1. Sign In and Create or Choose a project on AppGallery Connect portal.

2. Navigate to Project settings > download the configuration file and Add SHA-256 key.

3. Navigate to General Information > Data Storage location.

4. Navigate to Manage APIs > Enable APIs to require by an application.

Xamarin Map Kit Setup Process

1. Download Xamarin Plugin all the aar and zip files.

2. Open the XHms-Map-Kit-Library-Project.sln solution in Visual Studio.

3. Navigate to Solution Explorer and Right-click on jar Add > Existing Item and choose aar file which downloads in Step 1.

4. Right-click on added aar file then choose Properties > Build Action > LibraryProjectZip.

Note: Repeat Step 3 and 4 for all aar file.

5. Build the Library and make dll files.

Xamarin App Development

1. Open Visual Studio 2019 and Create a new project.

2. Navigate to Solution Explore > Project > Assets > Add Json file.

3. Navigate to Solution Explore > Project > Add > Add New Folder.

4. Navigate to Folder(created) > Add > Add Existing and add all DLL files.

5. Right click > Properties > Build Action > None.

6. Navigate to Solution Explore > Project > Reference > Right Click > Add References then Navigate to Browse and add all DLL files from the recently added Folder.

7. Added reference, then click Ok.

MainActivity.cs

This activity display type of map in 2 buttons.

using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using Android.Views;
using Android;
using Android.Content;
using Android.Support.V4.App;
using Android.Content.PM;
using Android.Util;
using Com.Huawei.Hms.Maps.Model;

namespace XamarinMap
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity, View.IOnClickListener
{
private const string TAG = "MainActivity";

//Required permissions
private static readonly string[] RUNTIME_PERMISSIONS = {
Manifest.Permission.WriteExternalStorage,
Manifest.Permission.ReadExternalStorage,
Manifest.Permission.AccessCoarseLocation,
Manifest.Permission.AccessFineLocation,
Manifest.Permission.Internet
};

//Permission request code.
private const int REQUEST_CODE = 100;

protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);

SetContentView(Resource.Layout.activity_main);

//Check permissions
if (!HasPermissions(this, RUNTIME_PERMISSIONS))
{
ActivityCompat.RequestPermissions(this, RUNTIME_PERMISSIONS, REQUEST_CODE);
}

Button BasicMap = (Button)FindViewById(Resource.Id.BasicMap);

Button PolylineDemo = (Button)FindViewById(Resource.Id.PolylineDemo);

BasicMap.SetOnClickListener(this);

PolylineDemo.SetOnClickListener(this);

}

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

public void OnClick(View v)
{
switch (v.Id)
{
case Resource.Id.BasicMap:
Log.Info(TAG, "OnClick: BasicMap");
StartActivity(new Intent(this, typeof(BasicMapDemoActivity)));
break;

case Resource.Id.PolylineDemo:
Log.Info(TAG, "OnClick: PolylineDemo");
StartActivity(new Intent(this, typeof(PolylineDemoActivity)));
break;

default:
break;
}
}
/// <summary>
/// Check whether permissions are granted
/// </summary>
private static bool HasPermissions(Context context, string[] permissions)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.M && permissions != null)
{
foreach (string permission in permissions)
{
if (ActivityCompat.CheckSelfPermission(context, permission) != Permission.Granted)
{
return false;
}
}
}
return true;
}
}
}

MapViewDemoActivity.cs

This activity display a basic view of Huawei Map.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using Com.Huawei.Hms.Maps;
using Com.Huawei.Hms.Maps.Model;

namespace XamarinMap
{
[Activity(Label = "MapViewDemoActivity")]
public class MapViewDemoActivity : Activity, IOnMapReadyCallback
{
private const string TAG = "MapViewDemoActivity";

private const string MAPVIEW_BUNDLE_KEY = "MapViewBundleKey";

private HuaweiMap hMap;

private MapView mMapView;

protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);

SetContentView(Resource.Layout.activity_mapview_demo);
mMapView = (MapView)FindViewById(Resource.Id.mapView);
Bundle mapViewBundle = null;
if (savedInstanceState != null)
{
mapViewBundle = savedInstanceState.GetBundle(MAPVIEW_BUNDLE_KEY);
}

MapsInitializer.SetApiKey(Constants.API_KEY);
mMapView.OnCreate(mapViewBundle);
mMapView.GetMapAsync(this);
}

protected override void OnStart()
{
base.OnStart();
mMapView.OnStart();
}

protected override void OnStop()
{
base.OnStop();
mMapView.OnStop();
}

protected override void OnDestroy()
{
base.OnDestroy();
mMapView.OnDestroy();
}

protected override void OnPause()
{
base.OnPause();
mMapView.OnPause();
}

protected override void OnResume()
{
base.OnResume();
mMapView.OnResume();
}

public override void OnLowMemory()
{
base.OnLowMemory();
mMapView.OnLowMemory();
}

public void OnMapReady(HuaweiMap map)
{
Log.Debug(TAG, "onMapReady: ");
hMap = map;
hMap.MyLocationEnabled = false;
hMap.MoveCamera(CameraUpdateFactory.NewLatLngZoom(new LatLng(48.893478, 2.334595), 10));
}
}
}

PolylineDemoActivity.cs

This activity draws a polyline between the two points in the Huawei map.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using Android.Util;
using Android.Views;
using Android.Widget;
using Com.Huawei.Hms.Maps;
using Com.Huawei.Hms.Maps.Model;
using Java.Lang;
using static Com.Huawei.Hms.Maps.HuaweiMap;

namespace XamarinMap
{
[Activity(Label = "PolylineDemoActivity")]
public class PolylineDemoActivity : AppCompatActivity, IOnMapReadyCallback, IOnPolylineClickListener
{
private const string TAG = "PolylineDemoActivity";

private MapFragment mSupportMapFragment;

private HuaweiMap hMap;

private Polyline mPolyline;

private TextView polylineShown;

private EditText oneLatitude;

private EditText oneLongtitude;

private EditText polylineStokeWidth;

private EditText polylineTag;

private IList<LatLng> points = new List<LatLng>();
protected override void OnCreate(Bundle savedInstanceState)
{
Log.Debug(TAG, "OnCreate: ");
base.OnCreate(savedInstanceState);

SetContentView(Resource.Layout.activity_polyline_demo);
mSupportMapFragment = (MapFragment)FragmentManager.FindFragmentById(Resource.Id.mapInPolyline);
mSupportMapFragment.GetMapAsync(this);

polylineShown = (TextView)FindViewById(Resource.Id.polylineShown);
oneLatitude = (EditText)FindViewById(Resource.Id.oneLatitude);
oneLongtitude = (EditText)FindViewById(Resource.Id.oneLongtitude);
polylineStokeWidth = (EditText)FindViewById(Resource.Id.polylineStokeWidth);
polylineTag = (EditText)FindViewById(Resource.Id.polylineTag);

points.Add(Constants.HUAWEI_CENTER);
points.Add(Constants.APARTMENT_CENTER);
points.Add(Constants.EPARK_CENTER);
}

public void OnMapReady(HuaweiMap map)
{
Log.Debug(TAG, "OnMapReady: ");
hMap = map;
hMap.MyLocationEnabled = true;
hMap.MoveCamera(CameraUpdateFactory.NewLatLngZoom(new LatLng(48.893478, 2.334595), 10));
}

/// <summary>
/// Add polyline to the map.
/// </summary>
[Java.Interop.Export("AddPolyline")]
public void AddPolyline(View view)
{
if (hMap == null)
{
return;
}
if (mPolyline != null)
{
mPolyline.Remove();
}
mPolyline = hMap.AddPolyline(
new PolylineOptions().Add(Constants.FRANCE, Constants.FRANCE1, Constants.FRANCE2, Constants.FRANCE3)
.InvokeColor(Color.Blue)
.InvokeWidth(3));
hMap.SetOnPolylineClickListener(this);
}

public void OnPolylineClick(Polyline polyline)
{
Log.Info(TAG, "OnMapReady:OnPolylineClick ");
Toast.MakeText(ApplicationContext, "Polyline is clicked.", ToastLength.Long).Show();
}

/// <summary>
/// Remove the polyline
/// </summary>
[Java.Interop.Export("RemovePolyline")]
public void RemovePolyline(View view)
{
if (null != mPolyline)
{
mPolyline.Remove();
}
points.Clear();
points.Add(Constants.HUAWEI_CENTER);
points.Add(Constants.APARTMENT_CENTER);
points.Add(Constants.EPARK_CENTER);
}

/// <summary>
/// Set the point position information of the polyline.
/// </summary>
[Java.Interop.Export("SetOnePoint")]
public void SetOnePoint(View v)
{
if (null != mPolyline)
{
string latitude = oneLatitude.Text.ToString().Trim();
string longtitude = oneLongtitude.Text.ToString().Trim();
if (CheckUtils.CheckIsEdit(latitude) || CheckUtils.CheckIsEdit(longtitude))
{
Toast.MakeText(this, "Please make sure the latitude & longtitude is Edited", ToastLength.Short).Show();
}
else
{
if (!CheckUtils.CheckIsRight(latitude) || !CheckUtils.CheckIsRight(longtitude))
{
Toast.MakeText(this, "Please make sure the latitude & longtitude is right", ToastLength.Short).Show();

}
else
{
points.Add(new LatLng(System.Double.Parse(latitude), System.Double.Parse(longtitude)));
mPolyline.Points = points;
}
}
}
}

/// <summary>
/// Get the point position information of the polyline.
/// </summary>
[Java.Interop.Export("GetPoints")]
public void GetPoints(View v)
{
if (null != mPolyline)
{
System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
for (int i = 0; i < mPolyline.Points.ToArray().Length; i++)
{
stringBuilder.Append(mPolyline.Points.ElementAt(i).ToString());
}
Toast.MakeText(this, "Polyline points is " + stringBuilder, ToastLength.Long).Show();
}
}

/// <summary>
/// Set the outline color of the polyline.
/// </summary>
[Java.Interop.Export("SetStokeColor")]
public void SetStokeColor(View v)
{
if (null != mPolyline)
{
mPolyline.Color = Color.Yellow;
}
}

/// <summary>
/// Get the outline color of the polyline.
/// </summary>
[Java.Interop.Export("GetStokeColor")]
public void GetStokeColor(View v)
{
if (null != mPolyline)
{
polylineShown.Text = "Polyline color is " + Integer.ToHexString(mPolyline.Color);
}
}

/// <summary>
/// Set the width of the polyline.
/// </summary>
[Java.Interop.Export("SetWidth")]
public void SetWidth(View v)
{
if (null != mPolyline)
{
string width = polylineStokeWidth.Text.ToString().Trim();
if (CheckUtils.CheckIsEdit(width))
{
Toast.MakeText(this, "Please make sure the width is Edited", ToastLength.Short).Show();
}
else
{
if (!CheckUtils.CheckIsRight(width))
{
Toast.MakeText(this, "Please make sure the width is right", ToastLength.Short).Show();
}
else
{
if (Single.Parse(width) < 0.0F)
{
Toast.MakeText(this,
"Please make sure the width is right, this value must be non-negative",
ToastLength.Short).Show();
return;
}
mPolyline.Width = Single.Parse(width);
}
}
}
}

/// <summary>
/// Get the width of the polyline.
/// </summary>
[Java.Interop.Export("GetWidth")]
public void GetWidth(View v)
{
if (null != mPolyline)
{
polylineShown.Text = ("Polyline width is " + mPolyline.Width);
}
}

/// <summary>
/// Set the tag of the polyline.
/// </summary>
[Java.Interop.Export("SetTag")]
public void SetTag(View v)
{
if (null != mPolyline)
{
string tag = polylineTag.Text.ToString().Trim();
if (CheckUtils.CheckIsEdit(tag))
{
Toast.MakeText(this, "Please make sure the tag is Edited", ToastLength.Short).Show();
}
else
{
mPolyline.Tag = tag;
}
}
}

/// <summary>
/// Get the tag of the polyline.
/// </summary>
[Java.Interop.Export("GetTag")]
public void GetTag(View v)
{
if (null != mPolyline)
{
polylineShown.Text = ((mPolyline.Tag == null ? "Tag is null" : mPolyline.Tag).ToString());
}
}

/// <summary>
/// Add polyline click event.
/// </summary>
[Java.Interop.Export("AddClickEvent")]
public void AddClickEvent(View v)
{
if (null != mPolyline)
{
hMap.SetOnPolylineClickListener(this);
}
}

/// <summary>
/// Set polyline clickable.
/// </summary>
[Java.Interop.Export("SetClickableTrue")]
public void SetClickableTrue(View v)
{
if (null != mPolyline)
{
mPolyline.Clickable = true;
}
}

/// <summary>
/// Set polyline are not clickable.
/// </summary>
[Java.Interop.Export("SetClickableFalse")]
public void SetClickableFalse(View v)
{
if (null != mPolyline)
{
mPolyline.Clickable = false;
}
}
}
}

Xamarin App Build Result

1. Navigate to Solution Explore > Project > Right Click > Archive/View Archive to generate SHA-256 for build release and Click on Distribute.

2. Choose Distribution Channel > Ad Hoc to sign apk.

3. Choose Demo Keystore to release apk.

4. Build succeed and Save apk file.

5. Final Result.

Tips and Tricks

1. Xamarin requires the ADB daemon to be started over port 5037. If the ADB daemon runs on a different port, Visual Studio will not be able to detect your device.

2. Map Kit needs to read appid and other attributes from the AppGallery Connect configuration file. In some conditions, Map Kit can't read appid.

Conclusion

In this article, we have learned how to integrate HMS Map Kit in Xamarin based Android application. In this application, I have explained the use case of Map kit with Polyline draw.

Thanks for reading this article.

Be sure to like and comments on this article, if you found it helpful. It means a lot to me.

References

Xamarin Map Kit Plugin

Original Source