To use the location service API of HUAWEI Location Kit, you need to download and install HMS Core (APK) on your device, and integrate related SDKs into your project. For details, please refer to Preparations.
The Android OS provides two location permissions: ACCESS_COARSE_LOCATION (approximate location permission) and ACCESS_FINE_LOCATION (precise location permission). You need to apply for the permissions in the Manifest file.
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
In Android Q, if your app needs to continuously locate the device location 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" />
After adding the preceding information to the Manifest file, you need to dynamically apply for the permissions in the code (according to risky permission requirements in Android 6.0).
- 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);
- }
- }
Create a FusedLocationProviderClient instance in the OnCreate()method of the activity and use the instance to call location-related APIs.
- private FusedLocationProviderClient fusedLocationProviderClient;
- private LocationRequest mLocationRequest;
- protected void onCreate(Bundle savedInstanceState) {
- fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
- }
Device location settings will affect the location result of HUAWEI Location Kit. For example, if the location function is disabled on a device, the device location cannot be obtained. Therefore, you are advised to check whether the device settings meet the location requirements before continuously obtaining location information. HUAWEI Location Kit provides the capability of checking device location settings. Your app can obtain the SettingsClient instance using getSettingsClient(Activity activity) of LocationServices and call the checkLocationSettings( LocationSettingsRequest locationSettingsRequest) API to obtain the device location settings. If the location settings do not meet the location requirements, your app can prompt users to enable related permissions. (The location permission must be enabled for HMS Core. In Android Q, Location must be set to Always for HMS Core.)
Step 1: Obtain the service API of SettingsClient.
- SettingsClient settingsClient = LocationServices.getSettingsClient(this);
Step 2: Call checkLocationSettings() to check the device settings.
- LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
- mLocationRequest = new LocationRequest();
- builder.addLocationRequest(mLocationRequest);
- LocationSettingsRequest locationSettingsRequest = builder.build();
- //check Location Settings
- settingsClient.checkLocationSettings(locationSettingsRequest)
- .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
- @Override
- public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
- //Have permissions, send requests
- fusedLocationProviderClient
- .requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- //Interface call successfully processed
- }
- });
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- //Settings do not meet targeting criteria
- int statusCode = ((ApiException) e).getStatusCode();
- switch (statusCode) {
- case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
- try {
- ResolvableApiException rae = (ResolvableApiException) e;
- //Calling startResolutionForResult can pop up a window to prompt the user to open the corresponding permissions
- rae.startResolutionForResult(MainActivity.this, 0);
- } catch (IntentSender.SendIntentException sie) {
- //…
- }
- break;
- }
- }
- });
To enable your app to continuously obtain the device location, you can use the requestLocationUpdates() API provided by the HUAWEI Location Kit service. This API returns the location information in two different forms based on the input parameter type. One form is to call the defined LocationCallback.onLocationResult() method to return a LocationResult object containing the location information. The other form is to return the location information in the extended information of the PendingIntent object.
If your app does not need to receive location updates anymore, you shall stop location updates to reduce power consumption. To stop location updates, you can call the removeLocationUpdates() method, and transfer the LocationCallback or PendingIntent object corresponding to the requestLocationupdates() API.
Here, the callback method is used as an example. The code is as follows. For details about parameters, please refer to the location API description.
1. Set continuous location request parameters.
- LocationRequest mLocationRequest = new LocationRequest();
- //Set the location update interval (int milliseconds).
- mLocationRequest.setInterval(10000);
- //Set the weight.
- mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
2. Define the location update callback.
- LocationCallback mLocationCallback;
- mLocationCallback = new LocationCallback() {
- @Override
- public void onLocationResult(LocationResult locationResult) {
- if (locationResult != null) {
- //Process the location callback result.
- }
- }
- };
3. Call requestLocationUpdates() for continuous location.
- fusedLocationProviderClient
- .requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- //Processing when the API call is successful.
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- //Processing when the API call fails.
- }
- });
4. Call removeLocationUpdates() to stop location updates.
- //Note: When location updates are stopped, the mLocationCallback object must be the same as that of requestLocationUpdates().
- fusedLocationProviderClient.removeLocationUpdates(mLocationCallback)
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- //Location updates are stopped successfully.
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- //Failed to stop location updates.
- }
- });
An app can use the HUAWEI Location Kit service API to obtain the last known location of a device. In most cases, the last known location is the current location of the device. The following is the sample code for calling the getLastLocation() method to obtain the last known location:
- Task<Location> task = fusedLocationProviderClient.getLastLocation()
- .addOnSuccessListener(new OnSuccessListener<Location>() {
- @Override
- public void onSuccess(Location location) {
- if (location == null) {
- return;
- }
- //Processing logic of the Location object.
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- //Exception handling logic.
- }
- });
To use the mock location function, go to Settings > System & updates > Developer options > Select mock location app and select the app for using the mock location function. (If Developer options is unavailable, go to Settings > About phone and tap Build number for seven consecutive times. Then, Developer options will be displayed on System & updates.) The sample code is as follows:
1. Call setMockMode(boolean isMockMode) to set the mock mode.
- fusedLocationProviderClient.setMockMode(mockFlag)
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- Log.i(TAG, "setMockMode onSuccess");
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- Log.i(TAG, "setMockMode onFailure:" + e.getMessage());
- }
- });
2. Call setMockLocation(Location mockLocation) to set the mock location.
- fusedLocationProviderClient.setMockLocation(mockLocation)
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- Log.i(TAG, "setMockLocation onSuccess");
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- Log.i(TAG, "setMockLocation onFailure:" + e.getMessage());
- }
- });
To use the activity identification service API of HUAWEI Location Kit, you need to download and install HMS Core (APK) on your device, and integrate related SDKs into your project. For details, please refer to Preparations.
1. To use the activity identification service in versions earlier than Android Q, you need to configure the following permissions in the Manifest file:
- <uses-permission android:name="com.huawei.hms.permission.ACTIVITY_RECOGNITION"/>
2. To use the activity identification service in Android Q and later versions, you need to configure the following permissions in the Manifest file:
- <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
Create an ActivityIdentificationService instance in the OnCreate() method of the activity and use the instance to call APIs related to activity identification.
- //The way to get the PendingIntent and callback results can be customized. Here we use broadcast as an example.
private PendingIntent pendingIntent;
- private ActivityIdentificationService activityIdentificationService;
- protected void onCreate(Bundle savedInstanceState) {
- activityIdentificationService = ActivityIdentification.getService(this);
- pendingIntent = getPendingIntent();
- };
To use the activity identification service, you need to register receiving of activity identification updates to check the current user status, such as walking, bicycling, and motionless.
1. Create new PendingIntent.
- private PendingIntent getPendingIntent() {
- //The LocationBroadcastReceiver class is a custom class. For detailed implementation methods, please refer to the sample code.
- Intent intent = new Intent(this, LocationBroadcastReceiver.class);
- intent.setAction(LocationBroadcastReceiver.ACTION_PROCESS_LOCATION);
- return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
- }
2. Listen on activity identification update requests.
Call the createActivityIdentificationUpdates (long detectionIntervalMillis, PendingIntent pendingIntent) method. In the method, the first parameter indicates the detection interval and the second parameter indicates pendingIntent.
- activityIdentificationService.createActivityIdentificationUpdates(5000, pendingIntent)
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- Log.i(TAG, "createActivityIdentificationUpdates onSuccess");
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- Log.e(TAG, "createActivityIdentificationUpdates onFailure:" + e.getMessage());
- }
- });
3. Deregister receiving of activity identificationupdates.
After using activity identification, you need to remove the listening on activity identification update requests. The value of PendingIntent must be the same as that of createActivityIdentificationUpdates (long detectionIntervalMillis, PendingIntent callbackIntent).
- activityIdentificationService.deleteActivityIdentificationUpdates(pendingIntent)
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- Log.i(TAG, "deleteActivityIdentificationUpdates onSuccess");
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- Log.e(TAG, "deleteActivityIdentificationUpdates onFailure:" + e.getMessage());
- }
- });
4. Process the activity identification results.
Activity identification result
- public class LocationBroadcastReceiver extends BroadcastReceiver {
- public static final String ACTION_PROCESS_LOCATION = "com.huawei.hms.location.ACTION_PROCESS_LOCATION";
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent != null) {
- final String action = intent.getAction();
- if (ACTION_PROCESS_LOCATION.equals(action)) {
- ActivityIdentificationResponse activityIdentificationResponse = ActivityIdentificationResponse.getDataFromIntent(intent);
- List<ActivityIdentificationData> list = activityIdentificationResponse .getActivityIdentificationDatas();
- }
- }
- }
- }
The function of detecting activity conversions (activity entering and exit) is provided. For example, to detect user status change from walking to bicycling, the app can call the createActivityConversionUpdates(request, pendingIntent) method to obtain the activity conversion status change.
1. Set parameters for listening to activity conversion requests.
- int STILL = 103;
- ActivityConversionInfo activityConversionInfo1 = new ActivityConversionInfo(STILL, ActivityConversionInfo.ENTER_ACTIVITY_CONVERSION);
- ActivityConversionInfo activityConversionInfo2 = new ActivityConversionInfo(STILL, ActivityConversionInfo.EXIT_ACTIVITY_CONVERSION);
- List<ActivityConversionInfo> activityConversionInfos = new ArrayList<>();
- activityConversionInfos.add(activityConversionInfo1);
- activityConversionInfos.add(activityConversionInfo2);
- ActivityConversionRequest request = new ActivityConversionRequest();
- request.setActivityConversions(activityConversionInfos);
2. Listen to activity conversion updates.
- Task<Void> task = activityIdentificationService.createActivityConversionUpdates(request, pendingIntent);
- task.addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- Log.i(TAG, "createActivityConversionUpdates onSuccess");
- }
- }).addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- Log.e(TAG, "createActivityConversionUpdates onFailure:" + e.getMessage());
- }
- });
3. Deregister receiving of activity conversion updates.
If your app does not need to listen to activity conversions anymore, you need to call deleteActivityConversionUpdates(PendingIntent pendingIntent) to deregister receiving of activity conversion updates.
- activityIdentificationService.deleteActivityConversionUpdates(pendingIntent)
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- Log.i(TAG, "deleteActivityConversionUpdates onSuccess");
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- Log.e(TAG, "deleteActivityConversionUpdates onFailure:" + e.getMessage());
- }
- });
4. Process the result.
Activity conversion result
- public class LocationBroadcastReceiver extends BroadcastReceiver {
- public static final String ACTION_PROCESS_LOCATION = "com.huawei.hms.location.ACTION_PROCESS_LOCATION";
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent != null) {
- final String action = intent.getAction();
- if (ACTION_PROCESS_LOCATION.equals(action)) {
- ActivityConversionResponse activityConversionResponse = ActivityConversionResponse.getDataFromIntent(intent);
- List<ActivityConversionData> list = activityConversionResponse .getActivityConversionDatas();
- }
- }
- }
- }
To use the geofence service API of HUAWEI Location Kit, you need to download and install HMS Core (APK) on your device, and integrate related SDKs into your project. For details, please refer to Preparations.
1. To use the geofence service API of HUAWEI Location Kit, you need to apply for the ACCESS_FINE_LOCATION permission in the Manifest file.
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
2. In Android Q, you need to apply for the ACCESS_BACKGROUND_LOCATION permission in the Manifest file.
- <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Create a GeofenceService instance in the OnCreate() method of Activity and use the instance to call geofence-related APIs.
- private GeofenceService geofenceService;
- private ArrayList<String> idList;
- private ArrayList<Geofence> geofenceList;
- private String TAG;
- //The way to get the PendingIntent and callback results can be customized. Here we use broadcast as an example.
- private PendingIntent pendingIntent;
- protected void onCreate(Bundle savedInstanceState) {
- geofenceService = LocationServices.getGeofenceService(this);
- pendingIntent = getPendingIntent();
- idList = new ArrayList<String>();
- geofenceList = new ArrayList<Geofence>();
- TAG = "geoFence";
- }
You can create a geofence instance and construct a request to add a geofence. After you send the request, the system will notify you of the request result through Task.
1. Create a geofence instance.
- geofenceList.add(new Geofence.Builder()
- .setUniqueId("mGeofence")
- .setValidContinueTime(10000)
- //Incoming latitude and longitude information, radius of circular geofence (unit: meter)
- .setRoundArea(latitude, longitude, radius)
- //Callback when entering or exiting the fence
- .setConversions(Geofence.ENTER_GEOFENCE_CONVERSION | Geofence.EXIT_GEOFENCE_CONVERSION)
- .build());
- idList.add("mGeofence");
2. Construct a request to add a geofence.
- private GeofenceRequest getAddGeofenceRequest() {
- GeofenceRequest.Builder builder = new GeofenceRequest.Builder();
- //When the user is in the fence, the callback is triggered immediately after adding
- builder.setInitConversions(GeofenceRequest.ENTER_INIT_CONVERSION);
- builder.createGeofenceList(geofenceList);
- return builder.build();
- }
3. Create new PendingIntent.
- private PendingIntent getPendingIntent() {
- //The GeoFenceBroadcastReceiver class is a custom static broadcast class. For detailed implementation methods, refer to the sample code.
- Intent intent = new Intent(this, GeoFenceBroadcastReceiver.class);
- intent.setAction(GeoFenceBroadcastReceiver.ACTION_PROCESS_LOCATION);
- return PendingIntent.getBroadcast(this,0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
- }
4. Send the request to add a geofence.
- public void requestGeoFenceWithNewIntent() {
- geofenceService.createGeofenceList(getAddGeofenceRequest(), pendingIntent)
- .addOnCompleteListener(new OnCompleteListener<Void>() {
- @Override
- public void onComplete(Task<Void> task) {
- if (task.isSuccessful()) {
- Log.i(TAG, "add geofence success!");
- } else {
- Log.w(TAG, "add geofence failed : " + task.getException().getMessage());
- }
- }
- });
- }
5. Delete geofences using an ID list.
- public void removeWithID() {
- geofenceService.deleteGeofenceList(idList)
- .addOnCompleteListener(new OnCompleteListener<Void>() {
- @Override
- public void onComplete(Task<Void> task) {
- if (task.isSuccessful()) {
- Log.i(TAG, "delete geofence with ID success!");
- } else {
- Log.w(TAG, "delete geofence with ID failed ");
- }
- }
- });
- }
You can delete a geofence by geofence ID or through PendingIntent.
6. Process a geofence trigger event.
When detecting a geofence trigger event, the system broadcast a notification to the user through PendingIntent.
- public class GeoFenceBroadcastReceiver extends BroadcastReceiver {
- public static final String ACTION_PROCESS_LOCATION = "com.huawei.hmssample.geofence.GeoFenceBroadcastReceiver.ACTION_PROCESS_LOCATION";
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent != null) {
- final String action = intent.getAction();
- StringBuilder sb = new StringBuilder();
- String next = "\n";
- if (ACTION_PROCESS_LOCATION.equals(action)) {
- GeofenceData geofenceData = GeofenceData.getDataFromIntent(intent);
- if (geofenceData != null) {
- int errorCode = geofenceData.getErrorCode();
- int conversion = geofenceData.getConversion();
- List<Geofence> list = geofenceData.getConvertingGeofenceList();
- Location mLocation = geofenceData.getConvertingLocation();
- boolean status = geofenceData.isSuccess();
- sb.append("errorcode: " + errorCode + next);
- sb.append("conversion: " + conversion + next);
- for(int i = 0;i < list.size();i++){
- sb.append("geoFence id :" + list.get(i).getUniqueId() + next);
- }
- sb.append("location is :" + mLocation.getLongitude() + " " + mLocation.getLatitude() + next);
- sb.append("is successful :" + status);
- Log.i(TAG,sb.toString());
- }
- }
- }
- }
- }