Introduction

HUAWEI Location Kit combines GPS, Wi-Fi, and base station location data to allow app developers to quickly obtain precise user locations, giving developers a global positioning capability and helping them deliver services to a global audience. In this codelab, you will call Location Kit to create an Android app (codelab app). The following figure shows the basic architecture of the app. The codelab app will integrate the Location SDK, and then use the Location SDK to call the location service of Huawei Mobile Services (APK).

What You Will Create

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

What You Will Learn

Hardware

Software

HUAWEI HMS Core integration requires the following preparations

For details, see the HUAWEI HMS Core Integration Preparation.

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

Main Configurations

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

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

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

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

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

Adding Compile Dependencies

Open the build.gradle file in the app directory.

Configure build dependencies.

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

Before building the APK, configure obfuscation scripts to prevent the HMS SDK from being obfuscated. If obfuscation arises, the HMS 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 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 have used AndResGuard, add it to the whitelist 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 manifest 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 manifest 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 for 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:

For more information about HUAWEI Location Kit, please visit our official website. If you encounter any problem during development, see the FAQs.

For more information, please click the following links:

Documentation
Download the demo source code used in this codelab from the following address:

Download source code

Code copied