We use essential cookies for the website to function, as well as analytics cookies for analyzing and creating statistics of the website performance. To agree to the use of analytics cookies, click "Accept All". You can manage your preferences at any time by clicking "Cookie Settings" on the footer. More Information.

Only Essential Cookies
Accept All
Sunset Announcement: The HMS Toolkit service will no longer receive version updates. Services in overseas regions will be decommissioned on December 30, 2026, and will no longer be available after sunset.
Tools GuidesHMS ToolkitUsage GuideConvertor Manual Conversion GuideMap Kit Manual Conversion Guide

Map Kit Manual Conversion Guide

Precautions

Preparations

  • If you want your app to support Map Kit, complete the following steps described in Preparations:
    1. Configure app information in AppGallery Connect.
    2. Integrate the HMS Core SDK.
    3. Configure obfuscation scripts.
    4. Apply for permissions.
  • If your app needs to support not-recommended methods such as Map.getMylocation() and Map.setOnMyLocationChangeListener(), you can use the methods provided by Location Kit instead. For details, please refer to API Reference and the sample code in Substitute Solutions for Certain Deprecated APIs.

gradle File Configuration

  • In the Add HMS API or To HMS API policy, ensure that minSdkVerison is 19 or later, targetSdkVerison is 29 or later, compileSdkVersion is 29 or later, and buildTooslVerison is '29.0.2' or later in defaultConfig{} in the module-level build.gradle file.
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. compileSdkVersion 29
    2. buildToolsVersion '29.0.2'
    3. defaultConfig {
    4. minSdkVersion 19
    5. targetSdkVersion 29
    6. }
  • Add the androidx.appcompat:appcompat dependency to the gradle file in module.
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. implementation 'androidx.appcompat:appcompat:1.1.0'
    2. implementation 'androidx.recyclerview:recyclerview:1.1.0'
  • Ensure that the AppCompatActivity inherited by Activity for initially instantiating SupportMapFragment is in the adnroidx.appcompat:appcompat package.
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. public class CameraDemoActivity extends androidx.appcompat.app.AppCompatActivity
  • In the Add HMS API scenario, the Google base and basement plug-in version added in the gradle file in module must be 17.1.0 or later.
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. implementation 'com.google.android.gms:play-services-base:17.1.0'
    2. implementation 'com.google.android.gms:play-services-basement:17.1.0'
  • The dependency on JDK 1.8 is added to the Android configuration item.
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. compileOptions {sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8}

Conversion from switch-case to if-else

After the conversion is complete, case expressions must be constant expression is displayed for some statements selected using switch-case. The case in switch must be an exception expressed in a constant. This method needs to be converted to the if-else format to resolve the switch exception.

Original sample code:

Collapse
Word wrap
Dark theme
Copy code
  1. switch (reason) {
  2. // REASON_GESTURE: gesture
  3. case OnCameraMoveStartedListener.REASON_GESTURE:
  4. currPolylineOptions.color(Color.BLUE);
  5. reasonText = "GESTURE";
  6. break;
  7. //REASON_API_ANIMATION: API animation
  8. case OnCameraMoveStartedListener.REASON_API_ANIMATION:
  9. currPolylineOptions.color(Color.RED);
  10. reasonText = "API_ANIMATION";
  11. break;
  12. //REASON_DEVELOPER_ANIMATION: developer animation
  13. case OnCameraMoveStartedListener.REASON_DEVELOPER_ANIMATION:
  14. currPolylineOptions.color(Color.GREEN);
  15. reasonText = "DEVELOPER_ANIMATION";
  16. break;
  17. }

Modified sample code:

Collapse
Word wrap
Dark theme
Copy code
  1. if (OnCameraMoveStartedListener.getREASON_GESTURE() == reason) {
  2. this.currPolylineOptions.color(Color.BLUE);
  3. reasonText = "GESTURE";
  4. } else if (OnCameraMoveStartedListener.getREASON_API_ANIMATION() == reason) {
  5. this.currPolylineOptions.color(Color.RED);
  6. reasonText = "API_ANIMATION";
  7. } else if (OnCameraMoveStartedListener.getREASON_DEVELOPER_ANIMATION() == reason) {
  8. this.currPolylineOptions.color(Color.GREEN);
  9. reasonText = "DEVELOPER_ANIMATION";
  10. } else {
  11. reasonText = "UNKNOWN_REASON";
  12. }

fragment

After the Add HMS API conversion is complete, you can configure the ClassLoader (simple, only resource import and configuration file modification are required) or manually write code (complex, heavy manual conversion workload) to implement the compatibility of Google APIs and HMS for activity displayed in fragment.

Currently, the ClassLoader solution does not support the plug-in or hot fix framework in projects, and does not support ClassLoader customization. If your app has such requirements, manually write the code.

For more information about the ClassLoader solution, please refer to Basic Principles of the XClassLoader Solution.

Configuring the ClassLoader

Currently, the ClassLoader does not support Add HMS API conversion in Library mode. Select the App mode when using the tool for conversion.

NOTICE

After automatic conversion, manually convert APIs in dummy state in all files through Conversion.

  1. Modify the project-related configuration files.
    1. If Generate code for creating app dependent only on GMS SDK is selected and the single xmsg flavor variant is enabled, modify the reference configuration in the project-level settings.gradle file as follows:
      Collapse
      Word wrap
      Dark theme
      Copy code
      1. include ':xmsadapter:xmsaux', 'xmsadapter:xmsaux:xg', 'xmsadapter:xmsaux:xapi'
      If Generate code for creating app dependent only on HMS SDK is selected and the single xmsh flavor variant is enabled, modify the reference configuration in the project-level settings.gradle file as follows:
      Collapse
      Word wrap
      Dark theme
      Copy code
      1. include ':xmsadapter:xmsaux', 'xmsadapter:xmsaux:xh', 'xmsadapter:xmsaux:xapi'
      If any of the preceding modes is selected and the single xmsgh flavor variant is enabled, modify the reference configuration in the project-level settings.gradle file as follows:
      Collapse
      Word wrap
      Dark theme
      Copy code
      1. include ':xmsadapter:xmsaux', 'xmsadapter:xmsaux:xg', 'xmsadapter:xmsaux:xh', 'xmsadapter:xmsaux:xapi'

      For details about the flavor variants, please refer to Using Convertor to Generate Multiple Variant APKs.

    2. In the dependencies {} section of the project-level build.gradle file, set the Gradle plug-in version to 3.5.0 or later.
      Collapse
      Word wrap
      Dark theme
      Copy code
      1. buildscript {
      2. dependencies {
      3. classpath 'com.android.tools.build:gradle:3.5.0'
      4. }
      5. }
    3. In the project-level gradle/wrapper/gradle-wrapper.properties file, set the Gradle version to 5.4.1 or later.
      Collapse
      Word wrap
      Dark theme
      Copy code
      1. distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
    4. For a multi-module project, add the following configuration to the gradle.properties file in the project-level directory:
      Collapse
      Word wrap
      Dark theme
      Copy code
      1. android.enableD8=false
      2. android.enableD8.desugaring=false
  2. Call the init method at the program entry to initialize the program.
    1. Implement a program entry class that inherits android.app.Application in the app and override the onCreate method in the class.
      Collapse
      Word wrap
      Dark theme
      Copy code
      1. public class MyApp extends Application {
      2. @Override
      3. public void onCreate() {
      4. super.onCreate();
      5. GlobalEnvSetting.init(this,null);
      6. XLoader.init(this);
      7. }
      8. }
    2. Modify the application name attribute in the app-level src/main/AndroidManifest.xml file and add the new application subclass in the first entry.
      Collapse
      Word wrap
      Dark theme
      Copy code
      1. <application
      2. android:name=".MyApp"
      3. </application>
  3. Handle the exception.
    1. If a rescanning is performed, you will see the message shown in the following figure. In this case, back up and remove the xh, xg, and xmsaux folders from the xmsadapter folder. After the rescanning is complete, restore the backup to the xmsadapter folder.

    1. To ensure your app security, Huawei provides the security verification function for the xg.apk and xh.apk resource files in the assets directory of the APK. If the error message "Apk File is corrupted" is displayed during the running process, the resource files have been tampered with or damaged. Clean and rebuild the entire project before APK packaging.

    2. If the following error message is displayed when your app is running on an Android device of an earlier version,

      Add the following configuration to app/build.gradle:

      Collapse
      Word wrap
      Dark theme
      Copy code
      1. android {
      2. defaultConfig {
      3. multiDexEnabled false
      4. }
      5. }

Manually Writing Code

  1. Modify the layout resource files.

    In the Add HMS API scenario, Google APIs and HMS need to use independent layout resource files. The <fragment/>class paths in the resource files are different.

    Reference for the fragment definition in the HMS layout resource file:

    Collapse
    Word wrap
    Dark theme
    Copy code
    1. <fragment
    2. android:id="@+id/map"
    3. android:layout_width="match_parent"
    4. android:layout_height="match_parent"
    5. class="com.huawei.hms.maps.SupportMapFragment" />

    Reference for the fragment definition in the Google API layout resource file:

    Collapse
    Word wrap
    Dark theme
    Copy code
    1. <fragment
    2. android:id="@+id/map"
    3. android:layout_width="match_parent"
    4. android:layout_height="match_parent"
    5. class="com.google.android.gms.maps.SupportMapFragment" />
    Resource file reference:
    • basic_demo: original layout resource file.
    • basic_demo_hms: layout resource file of HMS.

    Each layout resource file must be in duplicate, one for HMS and the other for Google APIs. The files are used together with the code for compatible redirection.

  1. Modify the code.

    If Fragment is used, you can use if-else in the onCreate() method of activity to make a copy of the code compatible with both HMS and Google APIs. The modification method is as follows:

    Original sample code:
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. protected void onCreate(Bundle savedInstanceState) {
    2. super.onCreate(savedInstanceState);
    3. // Configure the GMS resource file.
    4. setContentView(R.layout.events_demo);
    5. mTapTextView = (TextView) findViewById(R.id.tap_text);
    6. mCameraTextView = (TextView) findViewById(R.id.camera_text);
    7. // Load SupportMapFragment in the onCreate() method of the Activity.
    8. SupportMapFragment mapFragment =
    9. (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    10. // Call getMapAsync() to register a callback.
    11. mapFragment.getMapAsync(this);
    12. }

    Modified sample code:

    Collapse
    Word wrap
    Dark theme
    Copy code
    1. protected void onCreate(Bundle savedInstanceState) {
    2. super.onCreate(savedInstanceState);
    3. // Create according to G or H based on the current type.
    4. if (org.xms.g.utils.GlobalEnvSetting.isHms()) {
    5. createAsH();
    6. } else {
    7. createAsG();
    8. }
    9. }
    10. /**
    11. * HMS creation process.
    12. */
    13. private void createAsH() {
    14. Log.d(TAG, "create as hms");
    15. // Set the HMS resource file.
    16. setContentView(R.layout.events_demo_hms);
    17. // Initialize the parameter.
    18. initMember();
    19. // Obtain the HMS fragment based on the ID.
    20. com.huawei.hms.maps.SupportMapFragment hMapFragment =
    21. (com.huawei.hms.maps.SupportMapFragment) this.getSupportFragmentManager().findFragmentById(R.id.map);
    22. // Load a map.
    23. hMapFragment.getMapAsync(this.getHInstanceOnMapReadyCallback());
    24. }
    25. /**
    26. * GMS creation process.
    27. */
    28. private void createAsG() {
    29. Log.d(TAG, "create as gms");
    30. // Configure the GMS resource file.
    31. setContentView(R.layout.events_demo);
    32. // Initialize the parameter.
    33. initMember();
    34. // Obtain the GMS fragment based on the ID.
    35. com.google.android.gms.maps.SupportMapFragment gMapFragment =
    36. (com.google.android.gms.maps.SupportMapFragment) this.getSupportFragmentManager()
    37. .findFragmentById(R.id.map);
    38. // Load a map.
    39. gMapFragment.getMapAsync(this.getGInstanceOnMapReadyCallback());
    40. }
    41. /**
    42. * Initialize member variables and extract them into independent methods.
    43. */
    44. private void initMember() {
    45. this.mTapTextView = (TextView) findViewById(R.id.tap_text);
    46. this.mCameraTextView = (TextView) findViewById(R.id.camera_text);
    47. }
    Specify Google APIs or HMS to load map resources based on isHms in the current environment variable. The options are as follows:
    • void initMember(): initialization position of private member variables and code that can be shared.
    • void createAsG(): Google API creation process.
    • void createAsH(): HMS creation process.

Map Constants

After the conversion is complete, please refer to the following table if an exception occurs in the reference of constants. In Google Maps, constants are directly used. However, in the Add HMS API scenario, constants are used in Getter mode. For example:

For BitmapDescriptorFactory.HUE_ORANGE, the new method is to use BitmapDescriptorFactory.getHUE_ORANGE() in Getter mode.

Expand

Obtaining Google Maps Constants

Obtaining Add HMS API Constants

import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_HYBRID (directly used after reference)

ExtensionMap.getMAP_TYPE_NORMAL()

BitmapDescriptorFactory.HUE_ORANGE

BitmapDescriptorFactory.getHUE_ORANGE()

HuaweiMap.OnCameraMoveStartedListener.REASON_API_ANIMATION

HuaweiMap.OnCameraMoveStartedListener.getREASON_API_ANIMATION()

Expand

Obtaining Google Maps Constants

Obtaining To HMS API Constants

import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_HYBRID (directly used after reference)

import static com.huawei.hms.maps.HuaweiMap.MAP_TYPE_HYBRID (directly used after reference)

Special Fragment Scenarios (OnMapAndViewReadyListener)

Some demos such as Marker implement the OnMapAndViewReadyListener.OnGlobalLayoutAndMapReadyListener API. The Fragment used supports conversion in the OnMapAndViewReadyListener class in the Add HMS API scenario. The modification is as follows.

  • Modify the constructor. The parameter type of the constructor mapFragment needs to be converted from SupportMapFragment to the parent class Fragment.
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. public OnMapAndViewReadyListener(
    2. Fragment mapFragment, OnGlobalLayoutAndMapReadyListener devCallback) {}
  • The sample code for OnMapAndViewReadyListener to be compatible with Google APIs and HMS is as follows:
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. public class OnMapAndViewReadyListener implements OnGlobalLayoutListener, OnMapReadyCallback {
    2. /**
    3. * A listener that needs to wait for both the GoogleMap and the View to be initialized.
    4. */
    5. public interface OnGlobalLayoutAndMapReadyListener {
    6. void onMapReady(ExtensionMap googleMap);
    7. }
    8. private final View mapView;
    9. private final OnGlobalLayoutAndMapReadyListener devCallback;
    10. private boolean isViewReady;
    11. private boolean isMapReady;
    12. private ExtensionMap googleMap;
    13. public OnMapAndViewReadyListener(
    14. Fragment mapFragment, OnGlobalLayoutAndMapReadyListener devCallback) {
    15. // HMS processing.
    16. if (org.xms.g.utils.GlobalEnvSetting.isHms()) {
    17. com.huawei.hms.maps.SupportMapFragment hMapFragment = (com.huawei.hms.maps.SupportMapFragment) mapFragment;
    18. mapView = mapFragment.getView();
    19. this.devCallback = devCallback;
    20. registerListeners();
    21. // GoogleMap. Note if the GoogleMap is already ready it will still fire the callback later.
    22. hMapFragment.getMapAsync(this.getHInstanceOnMapReadyCallback());
    23. } else {
    24. // GMS processing.
    25. com.google.android.gms.maps.SupportMapFragment gMapFragment = (com.google.android.gms.maps.SupportMapFragment) mapFragment;
    26. mapView = mapFragment.getView();
    27. this.devCallback = devCallback;
    28. registerListeners();
    29. // GoogleMap. Note if the GoogleMap is already ready it will still fire the callback later.
    30. gMapFragment.getMapAsync(this.getGInstanceOnMapReadyCallback());
    31. }
    32. }
    33. private void registerListeners() {
    34. isViewReady = false;
    35. isMapReady = false;
    36. googleMap = null;
    37. // View layout.
    38. if ((mapView.getWidth() != 0) && (mapView.getHeight() != 0)) {
    39. // View has already completed layout.
    40. isViewReady = true;
    41. } else {
    42. // Map has not undergone layout, register a View observer.
    43. mapView.getViewTreeObserver().addOnGlobalLayoutListener(this);
    44. }
    45. }
    46. @Override
    47. public void onMapReady(ExtensionMap googleMap) {
    48. // NOTE: The GoogleMap API specifies the listener is removed just prior to invocation.
    49. this.googleMap = googleMap;
    50. isMapReady = true;
    51. fireCallbackIfReady();
    52. }
    53. @SuppressWarnings("deprecation") // We use the new method when supported
    54. @SuppressLint("NewApi") // We check which build version we are using.
    55. @Override
    56. public void onGlobalLayout() {
    57. // Remove our listener.
    58. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
    59. mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
    60. } else {
    61. mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    62. }
    63. isViewReady = true;
    64. fireCallbackIfReady();
    65. }
    66. private void fireCallbackIfReady() {
    67. if (isViewReady && isMapReady) {
    68. devCallback.onMapReady(googleMap);
    69. }
    70. }
    71. }
  • In the Add HMS API scenario, the sample code of onCreate() modification for activity to call OnMapAndViewReadyListener is as follows:
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. @Override
    2. protected void onCreate(Bundle savedInstanceState) {
    3. super.onCreate(savedInstanceState);
    4. // Create according to G or H based on the current type.
    5. if (org.xms.g.utils.GlobalEnvSetting.isHms()) {
    6. createAsH();
    7. } else {
    8. createAsG();
    9. }
    10. }
    11. private void createAsH() {
    12. Log.d(TAG, "create as hms");
    13. setContentView(R.layout.marker_demo_hms);
    14. // Initialize the parameter.
    15. initMember();
    16. // Obtain the HMS fragment based on the ID.
    17. com.huawei.hms.maps.SupportMapFragment hMapFragment = (com.huawei.hms.maps.SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    18. // Create an OnMapAndViewReadyListener listener.
    19. new OnMapAndViewReadyListener(hMapFragment, this);
    20. }
    21. private void createAsG() {
    22. Log.d(TAG, "create as gms");
    23. setContentView(R.layout.marker_demo);
    24. initMember();
    25. com.google.android.gms.maps.SupportMapFragment hMapFragment = (com.google.android.gms.maps.SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    26. new OnMapAndViewReadyListener(hMapFragment, this);
    27. }
    28. private void initMember() {
    29. this.mTopText = (TextView) findViewById(R.id.top_text);
    30. this.mRotationBar = (SeekBar) findViewById(R.id.rotationSeekBar);
    31. this.mRotationBar.setMax(360);
    32. this.mRotationBar.setOnSeekBarChangeListener(this);
    33. this.mFlatBox = (CheckBox) findViewById(R.id.flat);
    34. this.mOptions = (RadioGroup) findViewById(R.id.custom_info_window_options);
    35. this.mOptions.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    36. @Override
    37. public void onCheckedChanged(RadioGroup group, int checkedId) {
    38. if (MarkerDemoActivity.this.mLastSelectedMarker != null && MarkerDemoActivity.this.mLastSelectedMarker.isInfoWindowShown()) {
    39. // Refresh the info window when the info window's content has changed.
    40. MarkerDemoActivity.this.mLastSelectedMarker.showInfoWindow();
    41. }
    42. }
    43. });
    44. }

streetViewPanoramaFragment

In the Add HMS API scenario, the call method of fragment (please refer to fragment) is slightly different from that of streeViewPanoramaFragment. However, the basic approach is to perform if-else processing based on the system type. The reference is as follows.

Sample code of modifying onCreate in activity

Original sample code:

Collapse
Word wrap
Dark theme
Copy code
  1. protected void onCreate(final Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. setContentView(R.layout.street_view_panorama_basic_demo);
  4. SupportStreetViewPanoramaFragment streetViewPanoramaFragment =
  5. (SupportStreetViewPanoramaFragment)
  6. getSupportFragmentManager().findFragmentById(R.id.streetviewpanorama);
  7. // Set a callback object, which will be triggered when the GoogleMap instance is ready.
  8. streetViewPanoramaFragment.getStreetViewPanoramaAsync(
  9. new OnStreetViewPanoramaReadyCallback() {
  10. // Called when the streetscape panorama is ready.
  11. @Override
  12. public void onStreetViewPanoramaReady(StreetViewPanorama panorama) {
  13. // Only set the panorama to SYDNEY on startup (when no panoramas have been
  14. // loaded which is when the savedInstanceState is null).
  15. if (savedInstanceState == null) {
  16. panorama.setPosition(SYDNEY);
  17. }
  18. }
  19. });
  20. }
Modified sample code:
Collapse
Word wrap
Dark theme
Copy code
  1. @Override
  2. protected void onCreate(final Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. if (org.xms.g.utils.GlobalEnvSetting.isHms()) {
  5. createAsH(savedInstanceState);
  6. } else {
  7. createAsG(savedInstanceState);
  8. }
  9. }
  10. private void createAsH(final Bundle savedInstanceState) {
  11. Log.d(TAG, "create as hms");
  12. setContentView(R.layout.street_view_panorama_basic_demo_hms);
  13. initMember();
  14. com.huawei.hms.maps.SupportStreetViewPanoramaFragment hStreetViewPanoramaFragment =
  15. (com.huawei.hms.maps.SupportStreetViewPanoramaFragment) getSupportFragmentManager().findFragmentById(R.id.streetviewpanorama);
  16. hStreetViewPanoramaFragment.getStreetViewPanoramaAsync(panorama -> {
  17. // Only set the panorama to SYDNEY on startup (when no panoramas have been
  18. // loaded which is when the savedInstanceState is null).
  19. // Convert to org.xms for HMS.
  20. org.xms.g.maps.StreetViewPanorama xmsStreetViewPanorama =
  21. new org.xms.g.maps.StreetViewPanorama(null, panorama);
  22. if (savedInstanceState == null) {
  23. xmsStreetViewPanorama.setPosition(SYDNEY);
  24. }
  25. });
  26. }
  27. private void createAsG(final Bundle savedInstanceState) {
  28. Log.d(TAG, "create as gms");
  29. setContentView(R.layout.street_view_panorama_basic_demo);
  30. initMember();
  31. com.google.android.gms.maps.SupportStreetViewPanoramaFragment gStreetViewPanoramaFragment =
  32. (com.google.android.gms.maps.SupportStreetViewPanoramaFragment) getSupportFragmentManager().findFragmentById(R.id.streetviewpanorama);
  33. gStreetViewPanoramaFragment.getStreetViewPanoramaAsync(panorama -> {
  34. // Only set the panorama to SYDNEY on startup (when no panoramas have been
  35. // loaded which is when the savedInstanceState is null).
  36. // Convert HMS into org.xms.
  37. org.xms.g.maps.StreetViewPanorama xmsStreetViewPanorama =
  38. new org.xms.g.maps.StreetViewPanorama(panorama, null);
  39. if (savedInstanceState == null) {
  40. xmsStreetViewPanorama.setPosition(SYDNEY);
  41. }
  42. });
  43. }
  44. private void initMember() {
  45. }

For details about how to call streeViewPanoramaFragment, please refer to the sample code to make adjustment.

Substitute Solutions for Certain Deprecated APIs

If Location Kit APIs are used in the To HMS API scenario, the Location dependency needs to be added. For details about the version number in ${version}, please refer to Version Change History of Location Kit.

Collapse
Word wrap
Dark theme
Copy code
  1. implementation 'com.huawei.hms:location:${version}'

To use the Location function, ensure that you have obtained the location permission.

Sample code for obtaining the location permission:

Collapse
Word wrap
Dark theme
Copy code
  1. /**
  2. * only have permission of location, location function is enable
  3. **/
  4. if(enableMyLocation()){
  5. getMyLocation();
  6. setOnMyLocationChangeListener();
  7. }
  8. /**
  9. * Request code for location permission request.
  10. *
  11. * @see #onRequestPermissionsResult(int, String[], int[])
  12. */
  13. private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;
  14. /**
  15. * Enables the My Location layer if the fine location permission has been granted.
  16. */
  17. private boolean enableMyLocation() {
  18. // Dynamically apply for the ACCESS_FINE_LOCATION permission.
  19. if (ContextCompat.checkSelfPermission(this,
  20. Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  21. // Permission to access the location is missing.
  22. PermissionUtils.requestPermission(this, LOCATION_PERMISSION_REQUEST_CODE,
  23. Manifest.permission.ACCESS_FINE_LOCATION, true);
  24. return false;
  25. }else {
  26. return true;
  27. }
  28. }

HuaweiMap.getMyLocation()

This API can be replaced by the FusedLocationProviderClient.getLastLocation() method of Location Kit. For details about the API function, please refer to the getLastLocation() method in FusedLocationProviderClient of Location Kit.

To HMS API sample code:

Collapse
Word wrap
Dark theme
Copy code
  1. // Current position.
  2. private android.location.Location myLocation;
  3. /**
  4. * this is an Example:
  5. * using location kit getLastLocation ,replace HuaweiMap.getMylocation() function
  6. */
  7. private void getMyLocation(){
  8. // Call the getLastLocation() method to obtain the last known location.
  9. com.huawei.hmf.tasks.Task<android.location.Location> locationTask = LocationServices
  10. .getFusedLocationProviderClient(this).getLastLocation();
  11. // Define callback for success in requesting location updates.
  12. locationTask.addOnCompleteListener(param0 -> {
  13. if (locationTask != null) {
  14. // Obtain the latitude and longitude.
  15. myLocation = locationTask.getResult();
  16. double Lat = myLocation.getLatitude();
  17. double Lng = myLocation.getLongitude();
  18. Log.d(TAG, " Lat is : " + Lat +", Lng is : "+Lng);
  19. }// Define callback for failure in checking the device location settings.
  20. }).addOnFailureListener(param0 -> Log.d(TAG,"lastLocation is error"));
  21. }

Add HMS API sample code:

Collapse
Word wrap
Dark theme
Copy code
  1. //current location
  2. private android.location.Location myLocation;
  3. /**
  4. * this is an Example:
  5. * using location kit getLastLocation ,replace HuaweiMap.getMylocation() function
  6. */
  7. private void getMyLocation(){
  8. // Call the getLastLocation() method to obtain the last known location.
  9. org.xms.g.tasks.Task<android.location.Location> locationTask = LocationServices
  10. .getFusedLocationProviderClient(this).getLastLocation();
  11. // Define callback for success in requesting location updates.
  12. locationTask.addOnCompleteListener(param0 -> {
  13. if (locationTask != null) {
  14. // Obtain the latitude and longitude.
  15. myLocation = locationTask.getResult();
  16. double Lat = myLocation.getLatitude();
  17. double Lng = myLocation.getLongitude();
  18. Log.d(TAG, " Lat is : " + Lat +", Lng is : "+Lng);
  19. }// Define callback for failure in checking the device location settings.
  20. }).addOnFailureListener(param0 -> Log.d(TAG,"lastLocation is error"));
  21. }

HuaweiMap.setOnMyLocationListener()

This API can be replaced by the FusedLocationProviderClient.requestLocationUpdates(LocationRequest request, LocationCallback callback, Looper looper) method of Location Kit. For details about the API description, please refer to FusedLocationProviderClient.

To HMS API sample code:

Collapse
Word wrap
Dark theme
Copy code
  1. /**
  2. * this is an Example
  3. * using location kit requestLocationUpdates(Request,LocationCallback,Looper) ,replace HuaweiMap.setOnMyLocationChangeListener()
  4. */
  5. private void setOnMyLocationChangeListener(){
  6. // When you construct request parameters, please refer to the development guide of the Location Kit.
  7. // Set parameters for continuously requesting device locations.
  8. com.huawei.hms.location.LocationRequest request = new com.huawei.hms.location.LocationRequest();
  9. // Set the location update interval (in milliseconds).
  10. request.setInterval(2000);
  11. // Call requestLocationUpdates() for continuous location.
  12. LocationServices
  13. .getFusedLocationProviderClient(this).requestLocationUpdates(request, new LocationCallback() {
  14. @Override
  15. public void onLocationResult( com.huawei.hms.location.LocationResult locationResult) {
  16. if (locationResult != null) {
  17. // Process the location callback result.
  18. List<Location> locations = locationResult.getLocations();
  19. if (!locations.isEmpty()) {
  20. for (Location location : locations) {
  21. Log.i(TAG,
  22. "onLocationResult location[Longitude,Latitude,Accuracy]:"
  23. + location.getLongitude() + "," + location.getLatitude() + ","
  24. + location.getAccuracy());
  25. }
  26. }
  27. }
  28. }
  29. @Override
  30. public void onLocationAvailability(LocationAvailability locationAvailability) {
  31. if (locationAvailability != null) {
  32. // Check whether the locating is available.
  33. boolean flag = locationAvailability.isLocationAvailable();
  34. Log.i(TAG, "onLocationAvailability isLocationAvailable:" + flag);
  35. }
  36. }
  37. }, android.os.Looper.myLooper()).addOnSuccessListener(new OnSuccessListener<Void>() {
  38. @Override
  39. public void onSuccess(Void param0) {
  40. Log.d(TAG,"onSuccess.....");
  41. }
  42. });
  43. }

Add HMS API sample code:

Collapse
Word wrap
Dark theme
Copy code
  1. /**
  2. * this is an Example
  3. * using location kit requestLocationUpdates(Request,LocationCallback,Looper) ,replace HuaweiMap.setOnMyLocationChangeListener()
  4. */
  5. private void setOnMyLocationChangeListener(){
  6. // When you construct request parameters, please refer to the development guide of Location Kit.
  7. org.xms.g.location.LocationRequest request = new org.xms.g.location.LocationRequest();
  8. // Set the location update interval (in milliseconds).
  9. request.setInterval(2000);
  10. // Call requestLocationUpdates() for continuous location.
  11. LocationServices
  12. .getFusedLocationProviderClient(this).requestLocationUpdates(request, new LocationCallback() {
  13. @Override
  14. public void onLocationResult( org.xms.g.location.LocationResult locationResult) {
  15. if (locationResult != null) {
  16. // Process the location callback result.
  17. List<Location> locations = locationResult.getLocations();
  18. if (!locations.isEmpty()) {
  19. for (Location location : locations) {
  20. Log.i(TAG,
  21. "onLocationResult location[Longitude,Latitude,Accuracy]:"
  22. + location.getLongitude() + "," + location.getLatitude() + ","
  23. + location.getAccuracy());
  24. }
  25. }
  26. }
  27. }
  28. @Override
  29. public void onLocationAvailability(LocationAvailability locationAvailability) {
  30. if (locationAvailability != null) {
  31. // Check whether the locating is available.
  32. boolean flag = locationAvailability.isLocationAvailable();
  33. Log.i(TAG, "onLocationAvailability isLocationAvailable:" + flag);
  34. }
  35. }
  36. }, android.os.Looper.myLooper()).addOnSuccessListener(new OnSuccessListener<Void>() {
  37. @Override
  38. public void onSuccess(Void param0) {
  39. Log.d(TAG,"onSuccess.....");
  40. }
  41. });
  42. }

HuaweiMap.setOnCameraChangeListener()

This method can be replaced by the setOnCameraMoveStartedListener, setOnCameraMoveListener, and setOnCameraIdleListener methods for listening to the moveCamera event.

The sample code is as follows:

Collapse
Word wrap
Dark theme
Copy code
  1. /**
  2. * this is an Example
  3. * using setOnCameraMoveStartedListener, setOnCameraMoveListener, setOnCameraIdleListener to
  4. * replace to HuaweiMap.setOnCameraChangeListener.
  5. */
  6. private void setOnCameraChangeListener() {
  7. Log.d(TAG, " start addMoveListener...");
  8. // Set a callback function, which is called when the camera starts to move.
  9. this.mMap.setOnCameraMoveStartedListener(i -> Log.d(TAG," start camera move..."));
  10. //Set a callback function to be repeatedly called when the camera is in motion state.
  11. this.mMap.setOnCameraMoveListener(() -> Log.d(TAG," camera moving..."));
  12. // Set a callback function called when the camera stops moving.
  13. this.mMap.setOnCameraIdleListener(() -> {
  14. Log.d(TAG," idle camera move... ");
  15. });
  16. }

setMapStyle()

JSON resource files need to be loaded for map style settings (options: retro, night, grayscale, and simple). The JSON file format used by HuaweiMap is different from that used by Google Maps. As a result, they cannot share the same JSON resource file. Compatibility adaptation is required at the service code layer. To download the map style JSON files for HuaweiMap, please visit the download link.

Modification in the To HMS API Policy

  1. Download the Huawei JSON files.
  2. In the res/raw directory of the project (that is, the directory of the map style JSON resource files, which may vary according to projects), replace the resource files with those of the same names. The following figure shows the files for replacement.

Modification in the Add HMS API Policy

  1. Download the Huawei JSON files.
  2. Add mapstyle_grayscale_hms.json, mapstyle_night_hms.json, and mapstyle_retro_hms.json to the res/raw directory of the project (the directory may vary according to projects) as the map style resource files of Map Kit. These files coexist with the map style resource files of Google Maps. The following figure shows the files after the addition.

  3. The following is the sample code for Add HMS API compatibility after the modification. Load different JSON resource files based on system settings.
    Collapse
    Word wrap
    Dark theme
    Copy code
    1. private void setSelectedStyle() {
    2. MapStyleOptions style;
    3. switch (this.mSelectedStyleId) {
    4. case R.string.style_label_retro:
    5. // Sets the retro style via raw resource JSON.
    6. if(GlobalEnvSetting.isHms()){
    7. style = MapStyleOptions.loadRawResourceStyle(this, R.raw.mapstyle_retro_hms);
    8. }else{
    9. style = MapStyleOptions.loadRawResourceStyle(this, R.raw.mapstyle_retro);
    10. }
    11. break;
    12. case R.string.style_label_night:
    13. // Sets the night style via raw resource JSON.
    14. if(GlobalEnvSetting.isHms()){
    15. style = MapStyleOptions.loadRawResourceStyle(this, R.raw.mapstyle_night_hms);
    16. }else{
    17. style = MapStyleOptions.loadRawResourceStyle(this, R.raw.mapstyle_night);
    18. }
    19. break;
    20. case R.string.style_label_grayscale:
    21. // Sets the grayscale style via raw resource JSON.
    22. if(GlobalEnvSetting.isHms()){
    23. style = MapStyleOptions.loadRawResourceStyle(this, R.raw.mapstyle_grayscale_hms);
    24. }else{
    25. style = MapStyleOptions.loadRawResourceStyle(this, R.raw.mapstyle_grayscale);
    26. }
    27. break;
    28. case R.string.style_label_no_pois_no_transit:
    29. // Sets the no POIs or transit style via JSON string.
    30. style = new MapStyleOptions("[" + " {" + " \"featureType\":\"poi.business\","
    31. + " \"elementType\":\"all\"," + " \"stylers\":[" + " {"
    32. + " \"visibility\":\"off\"" + " }" + " ]" + " }," + " {"
    33. + " \"featureType\":\"transit\"," + " \"elementType\":\"all\"," + " \"stylers\":["
    34. + " {" + " \"visibility\":\"off\"" + " }" + " ]" + " }" + "]");
    35. break;
    36. case R.string.style_label_default:
    37. // Removes previously set style, by setting it to null.
    38. style = null;
    39. break;
    40. default:
    41. return;
    42. }
    43. // Set the basic map style. If this parameter is set to null, the previous customized style is cleared.
    44. this.mMap.setMapStyle(style);
    45. }
Search in Operation Guide
Enter a keyword.