[ShareLocation] Switched to FusedLocationProvider

Replaced the previous locationManager subscription with the gms
based FusedLocationProviderClient subscription for better battery
optimization.
This commit is contained in:
Alexander Dörflinger
2025-03-25 16:41:17 +01:00
parent aecbaf91c8
commit 9256fa69c7

View File

@@ -5,6 +5,9 @@ import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static com.aldo.apps.familyhelpers.utils.GlobalConstants.SHARE_LOCATION_CANCEL_ACTION;
import static com.aldo.apps.familyhelpers.utils.GlobalConstants.SHARE_LOCATION_CHANNEL_ID;
import static com.aldo.apps.familyhelpers.utils.GlobalConstants.SHARE_LOCATION_NOTIFICATION_ID;
import static com.google.android.gms.location.Granularity.GRANULARITY_FINE;
import static com.google.android.gms.location.Priority.PRIORITY_BALANCED_POWER_ACCURACY;
import static com.google.android.gms.location.Priority.PRIORITY_HIGH_ACCURACY;
import android.app.Activity;
import android.app.Notification;
@@ -28,6 +31,11 @@ import com.aldo.apps.familyhelpers.R;
import com.aldo.apps.familyhelpers.ShareLocationActivity;
import com.aldo.apps.familyhelpers.model.LocationObject;
import com.aldo.apps.familyhelpers.ui.NotificationHelper;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import java.lang.ref.WeakReference;
import java.util.List;
@@ -38,7 +46,7 @@ import io.reactivex.rxjava3.subjects.BehaviorSubject;
* Helper class to encapsulate all Location specific calls into one utility class.
* TODO: Change logic to make use of the FusedLocationProvider.
*/
public final class LocationHelper implements LocationListener {
public final class LocationHelper {
/**
* Tag for debugging purpose.
@@ -60,9 +68,32 @@ public final class LocationHelper implements LocationListener {
private static LocationHelper sInstance;
/**
* The {@link LocationManager} object to listen to location updates.
* The {@link FusedLocationProviderClient} to get the most accurate and battery optimized location.
*/
private final LocationManager mLocationManager;
private final FusedLocationProviderClient mFusedLocationProvider;
private final LocationCallback mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(@NonNull final LocationResult locationResult) {
super.onLocationResult(locationResult);
if (locationResult == null) {
Log.d(TAG, "onLocationResult: No Location available, skip update");
return;
}
for (final Location location : locationResult.getLocations()) {
if (location.hasSpeed()) {
Log.d(TAG, "onLocationResult: Location with speed received, continue...");
final LocationObject locationObject = LocationObject.fromLocation(location);
Log.d(TAG, "onLocationChanged: Received update with " + locationObject);
mLocationSubject.onNext(locationObject);
mDbHelper.insertOrUpdateLocation(locationObject);
return;
}
}
Log.d(TAG, "onLocationResult: Haven't receive a location with speed, skip this update...");
}
};
/**
* The {@link BehaviorSubject} for the {@link LocationObject} for clients to subscribe to.
* TODO: Check if needed.
@@ -91,7 +122,7 @@ public final class LocationHelper implements LocationListener {
* @param context The {@link Context) from where this was instantiated.
*/
private LocationHelper(final Context context) {
mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
mFusedLocationProvider = LocationServices.getFusedLocationProviderClient(context);
mNotificationHelper = new NotificationHelper(context);
mDbHelper = new DatabaseHelper();
mNotificationHelper.createAndRegisterNotificationChannel(
@@ -189,13 +220,12 @@ public final class LocationHelper implements LocationListener {
return true;
}
if (ContextCompat.checkSelfPermission(context, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationManager.requestLocationUpdates(
LocationManager.FUSED_PROVIDER,
minIntervalMillis,
minDistance,
this,
Looper.getMainLooper()
);
final LocationRequest locationRequest = new LocationRequest.Builder(minIntervalMillis)
.setGranularity(GRANULARITY_FINE)
.setMinUpdateDistanceMeters(minDistance)
.setPriority(PRIORITY_BALANCED_POWER_ACCURACY)
.build();
mFusedLocationProvider.requestLocationUpdates(locationRequest, mLocationCallback, Looper.getMainLooper());
mIsSubscribed = true;
} else {
mIsSubscribed = false;
@@ -212,7 +242,7 @@ public final class LocationHelper implements LocationListener {
Log.d(TAG, "stopLocationUpdates: Subscription already ended, no need to end again");
return;
}
mLocationManager.removeUpdates(this);
mFusedLocationProvider.removeLocationUpdates(mLocationCallback);
mIsSubscribed = false;
mSharingStateSubject.onNext(false);
mDbHelper.cancelOngoingLocationSharing();
@@ -265,32 +295,4 @@ public final class LocationHelper implements LocationListener {
.setStyle(new NotificationCompat.BigTextStyle())
.build();
}
@Override
public void onLocationChanged(@NonNull final Location location) {
final LocationObject locationObject = LocationObject.fromLocation(location);
Log.d(TAG, "onLocationChanged: Received update with " + locationObject);
mLocationSubject.onNext(locationObject);
mDbHelper.insertOrUpdateLocation(locationObject);
}
@Override
public void onLocationChanged(@NonNull final List<Location> locations) {
LocationListener.super.onLocationChanged(locations);
}
@Override
public void onFlushComplete(final int requestCode) {
LocationListener.super.onFlushComplete(requestCode);
}
@Override
public void onProviderEnabled(@NonNull final String provider) {
LocationListener.super.onProviderEnabled(provider);
}
@Override
public void onProviderDisabled(@NonNull final String provider) {
LocationListener.super.onProviderDisabled(provider);
}
}