116 lines
3.8 KiB
Java
116 lines
3.8 KiB
Java
package org.thoughtcrime.securesms.maps;
|
|
|
|
import android.Manifest;
|
|
import android.content.Context;
|
|
import android.content.pm.PackageManager;
|
|
import android.location.Location;
|
|
import android.location.LocationListener;
|
|
import android.location.LocationManager;
|
|
import android.location.LocationProvider;
|
|
import android.os.Bundle;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.core.content.ContextCompat;
|
|
import androidx.lifecycle.DefaultLifecycleObserver;
|
|
import androidx.lifecycle.LifecycleOwner;
|
|
|
|
import org.thoughtcrime.securesms.logging.Log;
|
|
import org.thoughtcrime.securesms.util.ServiceUtil;
|
|
|
|
/**
|
|
* A lifecycle-safe way to retrieve a single location update. If a cached location is available,
|
|
* we'll use that. Otherwise we'll listen for one.
|
|
*/
|
|
class LocationRetriever implements DefaultLifecycleObserver, LocationListener {
|
|
|
|
private static final String TAG = Log.tag(LocationRetriever.class);
|
|
|
|
private final Context context;
|
|
private final LocationManager locationManager;
|
|
private final SuccessListener successListener;
|
|
private final FailureListener failureListener;
|
|
|
|
LocationRetriever(@NonNull Context context, @NonNull LifecycleOwner lifecycleOwner, @NonNull SuccessListener successListener, @NonNull FailureListener failureListener) {
|
|
this.context = context;
|
|
this.locationManager = ServiceUtil.getLocationManager(context);
|
|
this.successListener = successListener;
|
|
this.failureListener = failureListener;
|
|
|
|
lifecycleOwner.getLifecycle().addObserver(this);
|
|
}
|
|
|
|
@Override
|
|
public void onStart(@NonNull LifecycleOwner owner) {
|
|
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
|
|
ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
|
|
{
|
|
Log.w(TAG, "No location permission!");
|
|
failureListener.onFailure();
|
|
}
|
|
|
|
LocationProvider provider = locationManager.getProvider(LocationManager.GPS_PROVIDER);
|
|
|
|
if (provider == null) {
|
|
Log.w(TAG, "GPS provider is null. Trying network provider.");
|
|
provider = locationManager.getProvider(LocationManager.NETWORK_PROVIDER);
|
|
}
|
|
|
|
if (provider == null) {
|
|
Log.w(TAG, "Network provider is null. Unable to retrieve location.");
|
|
failureListener.onFailure();
|
|
return;
|
|
}
|
|
|
|
Location lastKnown = locationManager.getLastKnownLocation(provider.getName());
|
|
|
|
if (lastKnown != null) {
|
|
Log.i(TAG, "Using last known location.");
|
|
successListener.onSuccess(lastKnown);
|
|
} else {
|
|
Log.i(TAG, "No last known location. Requesting a single update.");
|
|
locationManager.requestSingleUpdate(provider.getName(), this, null);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onStop(@NonNull LifecycleOwner owner) {
|
|
Log.i(TAG, "Removing any possible location listeners.");
|
|
locationManager.removeUpdates(this);
|
|
}
|
|
|
|
@Override
|
|
public void onLocationChanged(@Nullable Location location) {
|
|
if (location != null) {
|
|
Log.w(TAG, "[onLocationChanged] Successfully retrieved location.");
|
|
successListener.onSuccess(location);
|
|
} else {
|
|
Log.w(TAG, "[onLocationChanged] Null location.");
|
|
failureListener.onFailure();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onStatusChanged(@NonNull String provider, int status, @Nullable Bundle extras) {
|
|
Log.i(TAG, "[onStatusChanged] Provider: " + provider + " Status: " + status);
|
|
}
|
|
|
|
@Override
|
|
public void onProviderEnabled(@NonNull String provider) {
|
|
Log.i(TAG, "[onProviderEnabled] Provider: " + provider);
|
|
}
|
|
|
|
@Override
|
|
public void onProviderDisabled(@NonNull String provider) {
|
|
Log.i(TAG, "[onProviderDisabled] Provider: " + provider);
|
|
}
|
|
|
|
interface SuccessListener {
|
|
void onSuccess(@NonNull Location location);
|
|
}
|
|
|
|
interface FailureListener {
|
|
void onFailure();
|
|
}
|
|
}
|