How To Optimize Native Android Positioning for High Precision and Low Power Consumption
Have you run into the problem that the position data obtained by your app is inaccurate? Read on to find out how to solve this problem.
Join the DZone community and get the full member experience.
Join For FreeI recently encountered a problem with GPS positioning in my app.
My app needs to call the GPS positioning service and has been assigned all required permissions. What's more, my app uses a Wi-Fi network and 4G network and has no restrictions on power consumption and Internet connectivity. However, the GPS position and speed data obtained by calling standard Android APIs are very inaccurate.
Advantages and Disadvantages of Native Android Positioning
Native Android positioning provides two positioning modes: GPS positioning and network positioning. GPS positioning supports offline positioning based on satellites, which can work when no network is connected and achieve a high location precision. However, this mode will consume more power because the GPS positioning module on the device needs to be enabled. In addition, satellite data collection and calculation are time-consuming, causing slow initial positioning. GPS positioning needs to receive satellite signals, which are vulnerable to the influence of environments and geographical locations (such as weather and buildings). High-rise buildings, densely situated buildings, roofs, and walls will all affect GPS signals, resulting in inaccurate positioning.
Network positioning is fast and can instantly obtain the position anywhere, even in indoor environments, as long as the Wi-Fi network or cellular network is connected. It consumes less power, but its accuracy is prone to interference. In places with few base stations or Wi-Fi hotspots or with weak signals, positioning accuracy is poor or unusable. This mode requires a network connection for positioning.
Both modes have their own advantages and disadvantages. Traditional GPS positioning through native Android APIs is accurate to between 3 and 7 meters, which cannot meet the requirements for lane-level positioning. Accuracy will further decrease in urban roads and urban canyons.
Is there an alternative way for positioning besides calling the native APIs? Fortunately, there is.
HMS Core Location Kit
HMS Core Location Kit combines the Global Navigation Satellite System (GNSS), Wi-Fi, and base station location functionalities to help the app quickly pinpoint the user location.
Currently, the kit provides three main capabilities: fused location, activity identification, and geofence. You can call relevant capabilities as needed.
Activity identification can identify user activity status through the acceleration sensor, cellular network information, and magnetometer, helping developers adapt their apps to user behavior. Geofence allows developers to set an area of interest through an API so that their apps can receive a notification when a specified action (such as leaving, entering, or staying in the area) occurs. The fused location function combines location data from GNSS, Wi-Fi networks, and base stations to provide a set of easy-to-use APIs. With these APIs, an app can quickly pinpoint the device location with ease.
Precise Location Results for Fused Location
As the 5G communications technology develops, the fused location technology combines all currently available location modes, including GNSS, Wi-Fi, base station, Bluetooth, and sensor.
When an app uses GNSS, which has to search for satellites before performing location for the first time, Location Kit helps make the location faster and increases the success rate in case of weak GNSS signals. Location Kit also allows your app to choose an appropriate location method as required. For example, it preferentially chooses a location mode other than GNSS when the device's battery level is low to reduce power consumption.
Requesting Device Locations Continuously
The requestLocationUpdates()
method provided by Location Kit can be used to enable an app to continuously obtain the locations of the device. Based on the input parameter type, the method returns the device location by either calling the defined onLocationResult()
method in the LocationCallback
class to return a LocationResult
object containing the location information, or returning the location information in the extended information of the PendingIntent
object.
If the app no longer needs to receive location updates, stop requesting location updates to reduce power consumption. To do so, call the removeLocationUpdates()
method, and pass the LocationCallback
or PendingIntent
object that is used for calling the requestLocationUpdates()
method. The following code example uses the callback method as an example. For details about parameters, please refer to the description of LocationService
on the official website.
1. Set parameters to continuously request device locations.
LocationRequest mLocationRequest = new LocationRequest();
// Set the interval for requesting location updates (in milliseconds).
mLocationRequest.setInterval(10000);
// Set the location type.
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 requesting location updates.
// Note: When requesting location updates is stopped, the mLocationCallback object must be the same as LocationCallback in the requestLocationUpdates method.
fusedLocationProviderClient.removeLocationUpdates(mLocationCallback)
// Define callback for success in stopping requesting location updates.
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
// ...
}
})
// Define callback for failure in stopping requesting location updates.
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// ...
}
});
Published at DZone with permission of Jackson Jiang. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments