[Huawei Developers] Freemind R:
This article is orginally from HUAWEI Developer Forum.

Forum link: https://forums.developer.huawei.com/forumPortal/en/home

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407145406.93804900431034091613417683828556:50510527093639:2800:0C55244ABF58F8625C3886EAF4E9BBD678BD9A1398D3D901A230BFCACAA36CD6.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407145406.93804900431034091613417683828556:50510527093639:2800:0C55244ABF58F8625C3886EAF4E9BBD678BD9A1398D3D901A230BFCACAA36CD6.png[/IMG]​

Before we start learning about today’s topic, I strongly recommend you to go through my previous article i.e. HMS Site Map (Part 1). It will help you to have a clear picture.

Let’s Begin

In the previous article, we were successfully able to get details after selecting the place that we want to search using Site Kit. Today in this article we are going to see how to show a map using Map Kit after fetching the Latitude and Longitude from the details we selected. Also we are going to see how to use the Site APIs and Map APIs using POSTMAN in our Part 3 article.

One Step at a time

First we need to add Map Kit dependencies in the app gradle file and sync the app.

implementation 'com.huawei.hms:maps:4.0.1.300'

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407145434.24030143906039314762444197467295:50510527093639:2800:7C4D6362450D3B83AC2567DC819D6778F7B30F30690ABA4C0ABA0C9A37BCF4BC.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407145434.24030143906039314762444197467295:50510527093639:2800:7C4D6362450D3B83AC2567DC819D6778F7B30F30690ABA4C0ABA0C9A37BCF4BC.png[/IMG]​

After adding the dependencies we need to provide permission in AndroidManifest.xml file.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407142208.15816613106442677489467784966144:50510527093639:2800:A7FE54D73F204B383DF5818768ECDFD6999E71D5F62C45E6E0C170A72D0B521F.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407142208.15816613106442677489467784966144:50510527093639:2800:A7FE54D73F204B383DF5818768ECDFD6999E71D5F62C45E6E0C170A72D0B521F.png[/IMG]​

Let’s Code

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407142047.46277325003943508902688249778319:50510527093639:2800:654B43D618A1EA551130552160BDAD2F803FFD000ABE5D771685DA9541E51769.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407142047.46277325003943508902688249778319:50510527093639:2800:654B43D618A1EA551130552160BDAD2F803FFD000ABE5D771685DA9541E51769.gif[/IMG]​

Main Activity class

private void showDetails(String item) {
String pattern = Pattern.quote("\\" + "n");
String[] lines = item.split("\\n+");
autoCompleteTextView.setText(lines[0]);
mLat = lines[2]; // This is latitude
mLon = lines[3]; // This is longitude
title = lines[0]; // This is title or place name
String details = "<font color='red'>PLACE NAME : </font>" + lines[0] + "<br>"
+ "<font color='#CD5C5C'>COUNTRY : </font>" + lines[1] + "<br>"
+ "<font color='#8E44AD'>ADDRESS : </font>" + lines[4] + "<br>"
+ "<font color='#008000'>PHONE : </font>" + lines[5];

txtDetails.setText(Html.fromHtml(details, Html.FROM_HTML_MODE_COMPACT));

}
private void showMap(){
Intent intent = new Intent(MainActivity.this, MapActivity.class);
intent.putExtra("lat",mLat); // Here we are passing Latitude and Longitude
intent.putExtra("lon",mLon); // and titile from MainActivity class to
intent.putExtra("title",title);// MapActivity class…
startActivity(intent);
}v

Main Code

1) First we need to understand whether we are showing the map in view or fragment. Because there are two way we can show our map.

a) Fragment way

In fragment way we add MapFragment in the layout file of an activity.

<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.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:cameraTargetLat="48.893478"
map:cameraTargetLng="2.334595"
map:cameraZoom="10" />

b) MapView way

Here we add MapView in the layout file of an activity.

<com.huawei.hms.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:mapType="normal"
map:uiCompass="true"
map:uiZoomControls="true"
map:cameraTargetLat="51"
map:cameraTargetLng="10"
map:cameraZoom="8.5"/>

2) Here we are going with MapView.

3) For both Fragment as well as View, we need to implement OnMapReadyCallback API in our MapActivity to use a Map. After implementing this API, it will ask to implement onMapReady method.

public void onMapReady(HuaweiMap map) {
Log.d(TAG, "onMapReady: ");
hMap = map;
}

4) The only difference which we will see between MapFragment and MapView is instantiating Map.

a) MapFragement

private MapFragment mMapFragment;
mMapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.mapfragment_mapfragmentdemo);
mMapFragment.getMapAsync(this);

b) MapView

private MapView mMapView;
mMapView = findViewById(R.id.mapview_mapviewdemo);
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle("MapViewBundleKey");
}
mMapView.onCreate(mapViewBundle);
mMapView.getMapAsync(this);

5) Permission we need to check

//Put this in the top of the onCreate() method …
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
};
// This will placed in the onCreate() method …
if (!hasPermissions(this, RUNTIME_PERMISSIONS)) {
ActivityCompat.requestPermissions(this, RUNTIME_PERMISSIONS, REQUEST_CODE);
}
// Use this method to check Permission …
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;
}

MapActivity Class

public class MapActivity extends AppCompatActivity implements OnMapReadyCallback {

private static final String TAG = "MapActivity";
private MapView mMapView;
private HuaweiMap hmap;
private Marker mMarker;

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 String MAPVIEW_BUNDLE_KEY = "MapViewBundleKey";
private static final int REQUEST_CODE = 100;
private String mLatitude, mLongitude,mTitle;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);

mLatitude = getIntent().getExtras().getString("lat");
mLongitude = getIntent().getExtras().getString("lon");
mTitle = getIntent().getExtras().getString("title");
if (!hasPermissions(this, RUNTIME_PERMISSIONS)) {
ActivityCompat.requestPermissions(this, RUNTIME_PERMISSIONS, REQUEST_CODE);
}

mMapView = findViewById(R.id.mapView);
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY);
}
mMapView.onCreate(mapViewBundle);
mMapView.getMapAsync(this);

}

@Override
protected void onStart() {
super.onStart();
mMapView.onStart();
}

@Override
protected void onStop() {
super.onStop();
mMapView.onStop();
}

@Override
protected void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}

@Override
protected void onPause() {
mMapView.onPause();
super.onPause();
}

@Override
protected void onResume() {
super.onResume();
mMapView.onResume();
}

@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}

@Override
public void onMapReady(HuaweiMap huaweiMap) {
Log.d(TAG, "onMapReady: ");

hmap = huaweiMap;
hmap.setMyLocationEnabled(true);
hmap.setMapType(HuaweiMap.MAP_TYPE_NORMAL);
hmap.setMaxZoomPreference(15);
hmap.setMinZoomPreference(5);

CameraPosition build = new CameraPosition.Builder()
.target(new LatLng(Double.parseDouble(mLatitude), Double.parseDouble(mLongitude)))
.build();

CameraUpdate cameraUpdate = CameraUpdateFactory
.newCameraPosition(build);
hmap.animateCamera(cameraUpdate);

MarkerOptions options = new MarkerOptions()
.position(new LatLng(Double.parseDouble(mLatitude),
Double.parseDouble(mLongitude)))
.title(mTitle);
mMarker = hmap.addMarker(options);
mMarker.showInfoWindow();

hmap.setOnMarkerClickListener(new HuaweiMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {

Toast.makeText(getApplicationContext(), "onMarkerClick:" +
marker.getTitle(), Toast.LENGTH_SHORT).show();
return false;
}
});

}

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;
}
}

Core Functionality of Map

1) Types of Map

There are five types map:

· HuaweiMap.MAP_TYPE_NORMAL

· HuaweiMap.MAP_TYPE_NONE

· HuaweiMap.MAP_TYPE_SATELLITE

· HuaweiMap.MAP_TYPE_HYBRID

· HuaweiMap.MAP_TYPE_TERRAIN

But we can only use MAP_TYPE_NORMAL and MAP_TYPE_NONE. Normal type is a standard map, which shows roads, artificial structures, and natural features such as rivers. None type is an empty map without any data.

The Rest Map type is in development phase.

2) Camera Movement

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.

CameraPosition build = new CameraPosition.Builder().target(new
LatLng(Double.parseDouble(mLatitude),
Double.parseDouble(mLongitude))).build();

CameraUpdate cameraUpdate = CameraUpdateFactory
.newCameraPosition(build);
hmap.animateCamera(cameraUpdate);

In the above code we are using Map camera in animation mode. When moving the map camera in animation mode, you can set the animation duration and API to be called back when the animation stops. By default, the animation duration is 250 ms.

3) My Location in Map

We can get our location in our Map by simply enabling my-location layer. Also, we can display my-location icon in the Map.

hmap.setMyLocationEnabled(true);
hmap.getUiSettings().setMyLocationButtonEnabled(true);

4) Show Marker in Map

We can add markers to a map to identify locations such as stores and buildings, and provide additional information with information windows.

MarkerOptions options = new MarkerOptions()
.position(new LatLng(Double.parseDouble(mLatitude),
Double.parseDouble(mLongitude)))
.title(mTitle); // Adding the title here …
mMarker = hmap.addMarker(options);
mMarker.showInfoWindow();

We can customize our marker according to our need using BitmapDescriptor object.

Bitmap bitmap = ResourceBitmapDescriptor.drawableToBitmap(this,
ContextCompat.getDrawable(this, R.drawable.badge_ph));
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(bitmap);
mMarker.setIcon(bitmapDescriptor);

We can title to the Marker as shown in the above code. We can also make the marker clickable as shown below.

hmap.setOnMarkerClickListener(new HuaweiMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {

Toast.makeText(getApplicationContext(), "onMarkerClick:" +
marker.getTitle(), Toast.LENGTH_SHORT).show();
return false;
}
});

5) Map comes in shape

a) Polyline

b) Polygon

c) Circle

We can use Polyline if we need to show routes from one place to another. We can combine Direction API with Polyline to show routes for walking, bicycling and driving also calculating routes distance.

If we need to show radius like the location under 500 meter or something we use Circle shape to show in the map.

The Result

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407144641.79184854471151588455188918957529:50510527093639:2800:530F92EBD7D8F0E11F60AE47015D227A047DF2D212D563D7A59564D490AB8CA1.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407144641.79184854471151588455188918957529:50510527093639:2800:530F92EBD7D8F0E11F60AE47015D227A047DF2D212D563D7A59564D490AB8CA1.gif[/IMG]

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407144909.50924969095597818826129972375808:50510527093639:2800:95125418002CE97F3A744342734DB62C9606AB248D91306D8FFE37BBC0EEB294.jpg"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407144909.50924969095597818826129972375808:50510527093639:2800:95125418002CE97F3A744342734DB62C9606AB248D91306D8FFE37BBC0EEB294.jpg[/IMG]

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407144939.13686800604103481800112226867180:50510527093639:2800:C8C087BA6706D6DB17489CDA40B7DADBFE815D6A4AB19CAB35BDE4194A6AAE97.jpg"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200407144939.13686800604103481800112226867180:50510527093639:2800:C8C087BA6706D6DB17489CDA40B7DADBFE815D6A4AB19CAB35BDE4194A6AAE97.jpg[/IMG]

Any questions about this process, you can try to acquire answers from HUAWEI Developer Forum.​