Overview

Location Kit combines the GNSS, Wi-Fi, and base station location functionalities into your app to build up global positioning capabilities, allowing you to provide flexible location-based services for global users. In this codelab, you will learn how to call capabilities of Location Kit to create an Android app (codelab app).
The following figure shows the basic architecture of the app. The codelab app will use the integrated Location SDK to call the location service in HMS Core (APK).

What You Will Create

In this codelab, you will create an app for obtaining device location information.

What You Will Learn

In this codelab, you will learn how to:

Hardware Requirements

Software Requirements

To integrate Location Kit, you must complete the following preparations:

For details, please refer to Preparations for Integrating HUAWEI HMS Core.

Configuring the Maven Repository Address for the SDK

The procedure for configuring the Maven repository address in Android Studio is different for Gradle plugin earlier than 7.0, Gradle plugin 7.0, and Gradle plugin 7.1 or later. Click a relevant link below to find the configuration procedure for the specific Gradle plugin version.

Gradle plugin earlier than 7.0 Gradle plugin 7.0 Gradle plugin 7.1 or later

Gradle plugin earlier than 7.0

Gradle plugin 7.0

Gradle plugin 7.1 or later

Adding Build Dependencies

  1. Open the app-level build.gradle file.
  2. Add a dependency on the Location SDK.
  3. dependencies { implementation 'com.huawei.hms:location:6.4.0.300' }

Before building the APK, configure the obfuscation configuration file to prevent the HMS Core SDK from being obfuscated.

  1. Open the obfuscation configuration file proguard-rules.pro of your Android project.
  2. Add the following configuration to exclude the HMS Core SDK from obfuscation:
    -ignorewarnings -keepattributes *Annotation* -keepattributes Exceptions -keepattributes InnerClasses -keepattributes Signature -keepattributes SourceFile,LineNumberTable -keep class com.huawei.hianalytics.**{*;} -keep class com.huawei.updatesdk.**{*;} -keep class com.huawei.hms.**{*;} -keep class * extends com.huawei.hms.core.aidl.IMessageEntity{ *; } -keep public class com.huawei.location.nlp.network.** {*; } -keep class com.huawei.wisesecurity.ucs.**{*;}
  3. If you are using AndResGuard, add its trustlist to the obfuscation configuration file.
    "R.string.hms*", "R.string.connect_server_fail_prompt_toast", "R.string.getting_message_fail_prompt_toast", "R.string.no_available_network_prompt_toast", "R.string.third_app_*", "R.string.upsdk_*", "R.layout.hms*", "R.layout.upsdk_*", "R.drawable.upsdk*", "R.color.upsdk*", "R.dimen.upsdk*", "R.style.upsdk*"
  4. (Optional) If you integrate the Location SDK 6.0.0.xxx (a three-digit number), add the following statement in the app-level build.gradle file to ensure proper running of your app. This is because SDKs of this series of versions use SO files for hardening and the SO files cannot be compressed after hardening.
    android { buildTypes { release { packagingOptions { // If the CPU architecture is ARMv7 or ARMv8, add the following configuration: doNotStrip "*/arm64-v8a/libucs-credential.so" doNotStrip "*/armeabi-v7a/libucs-credential.so" // If the CPU architecture is x86, add the following configuration: doNotStrip "*/x86/libucs-credential.so" doNotStrip "*/x86_64/libucs-credential.so" } } debug { packagingOptions { // If the CPU architecture is ARMv7 or ARMv8, add the following configuration: doNotStrip "*/arm64-v8a/libucs-credential.so" doNotStrip "*/armeabi-v7a/libucs-credential.so" // If the CPU architecture is x86, add the following configuration: doNotStrip "*/x86/libucs-credential.so" doNotStrip "*/x86_64/libucs-credential.so" } } } }

You can click here to download the demo source code and obtain the xxx.java file used during the demo development.

  1. Apply for location permissions.
    1. Declare the permissions for obtaining the precise and coarse locations in the AndroidManifest.xml file.
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    2. If your app needs to continuously locate the device when it runs in the background in Android 10, also declare the ACCESS_BACKGROUND_LOCATION permission in the AndroidManifest.xml file.
      <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
    3. Dynamically apply for required permissions.
      Java sample code:
      // check location permission if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { Log.i(TAG, "sdk < 28 Q"); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.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 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.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, 3); }else{ if (ActivityCompat.checkSelfPermission(this, "android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) { String[] permission = {"android.permission.ACCESS_BACKGROUND_LOCATION"}; ActivityCompat.requestPermissions(this, permission, 0); } } } else { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.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 = {android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION, "android.permission.ACCESS_BACKGROUND_LOCATION"}; ActivityCompat.requestPermissions(this, strings, 2); } }
      Kotlin sample code:
      // check location permission if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { Log.i(TAG, "sdk < 28 Q") if (checkSelfPermission( this, ACCESS_FINE_LOCATION ) != PERMISSION_GRANTED && checkSelfPermission( this, ACCESS_COARSE_LOCATION ) != PERMISSION_GRANTED ) { val strings = arrayOf( ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION ) requestPermissions(this, strings, 1) } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (checkSelfPermission( this, ACCESS_FINE_LOCATION ) != PERMISSION_GRANTED && checkSelfPermission( this, ACCESS_COARSE_LOCATION ) != PERMISSION_GRANTED ) { val strings = arrayOf(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION) ActivityCompat.requestPermissions(this, strings, 3) } else { if (checkSelfPermission( this, "android.permission.ACCESS_BACKGROUND_LOCATION" ) != PERMISSION_GRANTED ) { val permission = arrayOf("android.permission.ACCESS_BACKGROUND_LOCATION") ActivityCompat.requestPermissions(this, permission, 0) } } } else { if (checkSelfPermission(this@RequestLocationUpdatesWithCallbackActivity, ACCESS_FINE_LOCATION) != PERMISSION_GRANTED && checkSelfPermission( this@RequestLocationUpdatesWithCallbackActivity, ACCESS_COARSE_LOCATION ) != PERMISSION_GRANTED && checkSelfPermission( this@RequestLocationUpdatesWithCallbackActivity, "android.permission.ACCESS_BACKGROUND_LOCATION" ) != PERMISSION_GRANTED ) { val strings = arrayOf( ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, "android.permission.ACCESS_BACKGROUND_LOCATION" ) requestPermissions(this, strings, 2) } }
    4. Configure permission application result callback.
      Java sample code:
      @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 1) { if (grantResults.length > 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) { Log.i(TAG, "onRequestPermissionsResult: apply LOCATION PERMISSION successful"); } else { Log.i(TAG, "onRequestPermissionsResult: apply LOCATION PERMISSION failed"); } } if (requestCode == 2) { if (grantResults.length > 2 && grantResults[2] == PackageManager.PERMISSION_GRANTED && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) { Log.i(TAG, "onRequestPermissionsResult: apply ACCESS_BACKGROUND_LOCATION successful"); } else { Log.i(TAG, "onRequestPermissionsResult: apply ACCESS_BACKGROUND_LOCATION failed"); } } if (requestCode == 3) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED || grantResults[1] == PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.checkSelfPermission(this, "android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) { String[] permission = {"android.permission.ACCESS_BACKGROUND_LOCATION"}; ActivityCompat.requestPermissions(this, permission, 0); } } else { Log.i(TAG, "onRequestPermissionsResult: apply LOCATION PERMISSION failed"); } } }
      Kotlin sample code:
      override fun onRequestPermissionsResult( requestCode: Int, permissions: Array, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == 1) { if (grantResults.size > 1 && grantResults[0] == PERMISSION_GRANTED && grantResults[1] == PERMISSION_GRANTED ) { Log.i( TAG, "onRequestPermissionsResult: apply LOCATION PERMISSION successful" ) } else { Log.i( TAG, "onRequestPermissionsResult: apply LOCATION PERMISSION failed" ) } } if (requestCode == 2) { if (grantResults.size > 2 && grantResults[2] == PERMISSION_GRANTED && grantResults[0] == PERMISSION_GRANTED && grantResults[1] == PERMISSION_GRANTED ) { Log.i( TAG, "onRequestPermissionsResult: apply ACCESS_BACKGROUND_LOCATION successful" ) } else { Log.i( TAG, "onRequestPermissionsResult: apply ACCESS_BACKGROUND_LOCATION failed" ) } } if (requestCode == 3) { if (grantResults.isNotEmpty() && grantResults[0] == PERMISSION_GRANTED || grantResults[1] == PERMISSION_GRANTED ) { if (checkSelfPermission( this, "android.permission.ACCESS_BACKGROUND_LOCATION" ) != PERMISSION_GRANTED ) { val permission = arrayOf("android.permission.ACCESS_BACKGROUND_LOCATION") ActivityCompat.requestPermissions(this, permission, 0) } } else { Log.i( TAG, "onRequestPermissionsResult: apply LOCATION PERMISSSION failed" ) } } }
    5. You can refer to the RequestLocationUpdatesWithCallbackActivity.java or RequestLocationUpdatesWithCallbackActivity.kt file to complete subsequent steps.
  2. Create a location provider client and device setting client.
    Java sample code:
    // Define a location provider client. private FusedLocationProviderClient fusedLocationProviderClient; // Define a device setting client. private SettingsClient settingsClient; fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this); settingsClient = LocationServices.getSettingsClient(this);
    Kotlin sample code:
    // Define a location provider client. private lateinit var fusedLocationProviderClient: FusedLocationProviderClient // Define a device setting client. private lateinit var settingsClient: SettingsClient fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this) settingsClient = LocationServices.getSettingsClient(this)
  3. Create the location request body.
    Java sample code:
    LocationRequest mLocationRequest; mLocationRequest = new LocationRequest(); // Set the interval for requesting location updates (unit: ms). mLocationRequest.setInterval(10000); // Set the location type. mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    Kotlin sample code:
    var mLocationRequest: LocationRequest? = null // Set the interval for requesting location updates (unit: ms). // Set the location type. mLocationRequest = LocationRequest().apply { interval = 1000 needAddress = true priority = LocationRequest.PRIORITY_HIGH_ACCURACY }
  4. Create a location result callback.
    Java sample code:
    LocationCallback mLocationCallback; mLocationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { if (locationResult != null) { List<Location> locations = locationResult.getLocations(); if (!locations.isEmpty()) { for (Location location : locations) { Log.i(TAG,"onLocationResult location[Longitude,Latitude,Accuracy]:" + location.getLongitude() + "," + location.getLatitude() + "," + location.getAccuracy()); } } } } @Override public void onLocationAvailability(LocationAvailability locationAvailability) { if (locationAvailability != null) { boolean flag = locationAvailability.isLocationAvailable(); Log.i(TAG, "onLocationAvailability isLocationAvailable:" + flag); } } };
    Kotlin sample code:
    var mLocationCallback: LocationCallback? = null if (null == mLocationCallback) { mLocationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult?) { if (locationResult != null) { val locations: List<Location> = locationResult.locations if (locations.isNotEmpty()) { for (location in locations) { Log.i( TAG, "onLocationResult location[Longitude,Latitude,Accuracy]:${location.longitude} , ${location.latitude} , ${location.accuracy}" ) } } } } override fun onLocationAvailability(locationAvailability: LocationAvailability?) { locationAvailability?.let { val flag: Boolean = locationAvailability.isLocationAvailable Log.i(TAG, "onLocationAvailability isLocationAvailable:$flag") } } } }
  5. Request location updates.
    Java sample code:
    private void requestLocationUpdatesWithCallback() { try { LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); builder.addLocationRequest(mLocationRequest); LocationSettingsRequest locationSettingsRequest = builder.build(); // Check the device settings before requesting location updates. settingsClient.checkLocationSettings(locationSettingsRequest) .addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(LocationSettingsResponse locationSettingsResponse) { Log.i(TAG, "check location settings success"); // Request location updates. fusedLocationProviderClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper()).addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(Void aVoid) { Log.i(TAG, "requestLocationUpdatesWithCallback onSuccess"); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.e(TAG, "requestLocationUpdatesWithCallback onFailure:" + e.getMessage()); } }); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.e(TAG, "checkLocationSetting onFailure:" + e.getMessage()); } }); } catch (Exception e) { Log.e(TAG, "requestLocationUpdatesWithCallback exception:" + e.getMessage()); } }
    Kotlin sample code:
    private fun requestLocationUpdatesWithCallback() { try { val builder = LocationSettingsRequest.Builder() builder.addLocationRequest(mLocationRequest) val locationSettingsRequest = builder.build() // Check the device settings before requesting location updates. val locationSettingsResponseTask: Task = settingsClient.checkLocationSettings(locationSettingsRequest) locationSettingsResponseTask.addOnSuccessListener { locationSettingsResponse: LocationSettingsResponse? -> Log.i(TAG, "check location settings success {$locationSettingsResponse}") // Request location updates. fusedLocationProviderClient.requestLocationUpdates( mLocationRequest, mLocationCallback, Looper.getMainLooper() ) .addOnSuccessListener { Log.i(TAG, "requestLocationUpdatesWithCallback onSuccess") } .addOnFailureListener { e -> Log.e( TAG, "requestLocationUpdatesWithCallback onFailure:${e.message}" ) } } .addOnFailureListener { e: Exception -> Log.e(TAG, "checkLocationSetting onFailure:${e.message}") } } catch (e: Exception) { Log.e(TAG, "requestLocationUpdatesWithCallback exception:${e.message}") } }
  6. Stop requesting location updates.
    Java sample code:
    private void removeLocationUpdatesWithCallback() { try { fusedLocationProviderClient.removeLocationUpdates(mLocationCallback) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { Log.i(TAG, "removeLocationUpdatesWithCallback onSuccess"); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.e(TAG, "removeLocationUpdatesWithCallback onFailure:" + e.getMessage()); } }); } catch (Exception e) { Log.e(TAG, "removeLocationUpdatesWithCallback exception:" + e.getMessage()); } }
    Kotlin sample code:
    private fun removeLocationUpdatesWithCallback() { try { fusedLocationProviderClient.removeLocationUpdates(mLocationCallback) .addOnSuccessListener { Log.i( TAG, "removeLocationUpdatesWithCallback onSuccess" ) } .addOnFailureListener { e -> Log.e( TAG, "removeLocationUpdatesWithCallback onFailure:${e.message}" ) } } catch (e: Exception) { Log.e( TAG, "removeLocationUpdatesWithCallback exception:${e.message}" ) } }

Tap requestLocationUpdates with callback in the demo app. The obtained location information will be displayed on the app screen.

Well done. You have successfully completed this codelab and learned how to:

For more information, please read related documents.
You can click here to download the source code.

已复制代码