Introduction

HUAWEI Location Kit combines GPS, Wi-Fi, and base station location data to allow you to quickly obtain precise user locations, giving you a global positioning capability and helping you deliver services to a global audience. In this codelab, you will create an Android app (codelab app) and integrate Location Kit into the 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 of HMS Core (APK).

What You Will Create

In this codelab, you will create an app that obtains device location information.

What You Will Learn

Hardware

Software

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

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

In this codelab, you need to create a project in Android Studio.

Main Configurations

1. Open the build.gradle file in the root directory of your Android Studio project.

2. Go to allprojects > repositories and configure the Maven repository address for the HMS Core SDK

allprojects { repositories { maven { url 'https://developer.huawei.com/repo/' } google() jcenter() } }

3. Go to buildscript > repositories and configure the Maven repository address for the HMS Core SDK.

buildscript { repositories { maven { url 'https://developer.huawei.com/repo/' } google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.3.2' } }

Adding Compile Dependencies

1. Open the build.gradle file in the app directory.

2. Add build dependencies.

dependencies { implementation 'com.huawei.hms:location:5.0.2.301' }

Before building the APK, configure obfuscation scripts to prevent the HMS Core SDK from being obfuscated. If obfuscation arises, the HMS Core SDK may not function properly.

1. Open the obfuscation configuration file proguard-rules.pro of your Android project.

2. Add configuration to exclude the HMS Core SDK from obfuscation.

-ignorewarnings -keepattributes *Annotation* -keepattributes Exceptions -keepattributes InnerClasses -keepattributes Signature -keepattributes SourceFile,LineNumberTable -keep class com.hianalytics.android.**{*;} -keep class com.huawei.updatesdk.**{*;} -keep class com.huawei.hms.**{*;}

3. If you are using AndResGuard, add it to the allowlist in the obfuscation script 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*"

1. Apply for location permissions.
Add related permissions to the AndroidManifest.xml file of the project.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

In Android Q, if your app needs to track the device location even when it runs in the background, you need to apply for the ACCESS_BACKGROUND_LOCATION permission in the AndroidManifest.xml file.

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

Add dynamic application for related permissions to the RequestLocationUpdatesWithCallbackActivity.Java file.

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

Add permission application result callback to the RequestLocationUpdatesWithCallbackActivity.Java file.

@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 PERMISSSION 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"); } } }

You can perform subsequent steps by referring to the RequestLocationUpdatesWithCallbackActivity.Java file.

2. Create a location provider client and device setting client.

//create a fusedLocationProviderClient fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this); //create a settingsClient settingsClient = LocationServices.getSettingsClient(this);

3. Create a location information request.

mLocationRequest = new LocationRequest(); // set the interval for location updates, in milliseconds. mLocationRequest.setInterval(10000); // set the priority of the request mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

4. Create a result callback.

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

5. Request location updates.

/** * function:Requests location updates with a callback on the specified Looper thread. * first:use SettingsClient object to call checkLocationSettings(LocationSettingsRequest locationSettingsRequest) method to check device settings. * second: use FusedLocationProviderClient object to call requestLocationUpdates (LocationRequest request, LocationCallback callback, Looper looper) method. */ private void requestLocationUpdatesWithCallback() { try { LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); builder.addLocationRequest(mLocationRequest); LocationSettingsRequest locationSettingsRequest = builder.build(); // check devices settings before request location updates. settingsClient.checkLocationSettings(locationSettingsRequest) .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() { @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<Void>() { @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()); int statusCode = ((ApiException) e).getStatusCode(); switch (statusCode) { case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: try { ResolvableApiException rae = (ResolvableApiException) e; rae.startResolutionForResult(RequestLocationUpdatesWithCallbackActivity.this, 0); } catch (IntentSender.SendIntentException sie) { Log.e(TAG, "PendingIntent unable to execute request."); } break; } } }); } catch (Exception e) { Log.e(TAG, "requestLocationUpdatesWithCallback exception:" + e.getMessage()); } }

6. Remove location updates.

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

In this codelab, you can click the button for requesting location updates to display the location information on the current interface.

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

For more details, please refer to Development Guide. If you encounter problem during development, please refer to FAQs.

For more information, please click the following links:

Documentation

You can click the button below to download the source code.

Download source code

Code copied