|
|
|
|
@ -1,28 +1,26 @@
|
|
|
|
|
package org.tasks.location;
|
|
|
|
|
|
|
|
|
|
import static com.google.android.gms.location.Geofence.NEVER_EXPIRE;
|
|
|
|
|
import static com.google.common.base.Predicates.notNull;
|
|
|
|
|
import static com.google.common.collect.Iterables.filter;
|
|
|
|
|
import static com.google.common.collect.Iterables.transform;
|
|
|
|
|
import static com.google.common.collect.Lists.newArrayList;
|
|
|
|
|
import static com.google.common.collect.Lists.transform;
|
|
|
|
|
import static java.util.Collections.singletonList;
|
|
|
|
|
|
|
|
|
|
import android.annotation.SuppressLint;
|
|
|
|
|
import android.app.PendingIntent;
|
|
|
|
|
import android.content.Context;
|
|
|
|
|
import android.content.Intent;
|
|
|
|
|
import com.google.android.gms.common.api.PendingResult;
|
|
|
|
|
import com.google.android.gms.common.api.Status;
|
|
|
|
|
import com.google.android.gms.location.Geofence;
|
|
|
|
|
import com.google.android.gms.location.GeofencingRequest;
|
|
|
|
|
import com.google.android.gms.location.GeofencingRequest.Builder;
|
|
|
|
|
import com.google.android.gms.location.LocationServices;
|
|
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import javax.inject.Inject;
|
|
|
|
|
import org.tasks.data.Location;
|
|
|
|
|
import org.tasks.injection.ForApplication;
|
|
|
|
|
import org.tasks.preferences.PermissionChecker;
|
|
|
|
|
import org.tasks.preferences.Preferences;
|
|
|
|
|
import timber.log.Timber;
|
|
|
|
|
|
|
|
|
|
public class GeofenceApi {
|
|
|
|
|
|
|
|
|
|
@ -38,40 +36,23 @@ public class GeofenceApi {
|
|
|
|
|
this.permissionChecker = permissionChecker;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void register(final List<Location> locations) {
|
|
|
|
|
if (locations.isEmpty() || !permissionChecker.canAccessLocation()) {
|
|
|
|
|
@SuppressLint("MissingPermission")
|
|
|
|
|
void register(final List<Location> locations) {
|
|
|
|
|
if (!permissionChecker.canAccessLocation()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
newClient(
|
|
|
|
|
client -> {
|
|
|
|
|
List<Geofence> requests = getRequests(locations);
|
|
|
|
|
if (requests.isEmpty()) {
|
|
|
|
|
client.disconnect();
|
|
|
|
|
} else {
|
|
|
|
|
@SuppressWarnings("ResourceType")
|
|
|
|
|
@SuppressLint("MissingPermission")
|
|
|
|
|
PendingResult<Status> result =
|
|
|
|
|
LocationServices.GeofencingApi.addGeofences(
|
|
|
|
|
client,
|
|
|
|
|
requests,
|
|
|
|
|
PendingIntent.getBroadcast(
|
|
|
|
|
context,
|
|
|
|
|
0,
|
|
|
|
|
new Intent(context, GeofenceTransitionsIntentService.Broadcast.class),
|
|
|
|
|
PendingIntent.FLAG_UPDATE_CURRENT));
|
|
|
|
|
result.setResultCallback(
|
|
|
|
|
status -> {
|
|
|
|
|
if (status.isSuccess()) {
|
|
|
|
|
Timber.i("Registered %s", locations);
|
|
|
|
|
} else {
|
|
|
|
|
Timber.e("Failed to register %s", locations);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client.disconnect();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
List<Geofence> requests = getRequests(locations);
|
|
|
|
|
if (!requests.isEmpty()) {
|
|
|
|
|
LocationServices.getGeofencingClient(context)
|
|
|
|
|
.addGeofences(
|
|
|
|
|
new Builder().addGeofences(requests).build(),
|
|
|
|
|
PendingIntent.getBroadcast(
|
|
|
|
|
context,
|
|
|
|
|
0,
|
|
|
|
|
new Intent(context, GeofenceTransitionsIntentService.Broadcast.class),
|
|
|
|
|
PendingIntent.FLAG_UPDATE_CURRENT));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void cancel(final Location location) {
|
|
|
|
|
@ -79,35 +60,24 @@ public class GeofenceApi {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void cancel(final List<Location> locations) {
|
|
|
|
|
if (locations.isEmpty() || !permissionChecker.canAccessLocation()) {
|
|
|
|
|
if (!permissionChecker.canAccessLocation()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<String> ids = Lists.transform(locations, geofence -> Long.toString(geofence.getId()));
|
|
|
|
|
|
|
|
|
|
newClient(
|
|
|
|
|
client ->
|
|
|
|
|
LocationServices.GeofencingApi.removeGeofences(client, ids)
|
|
|
|
|
.setResultCallback(
|
|
|
|
|
status -> {
|
|
|
|
|
if (status.isSuccess()) {
|
|
|
|
|
Timber.i("Removed %s", locations);
|
|
|
|
|
} else {
|
|
|
|
|
Timber.e("Failed to remove %s", locations);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client.disconnect();
|
|
|
|
|
}));
|
|
|
|
|
List<String> requestIds = getRequestIds(locations);
|
|
|
|
|
if (!requestIds.isEmpty()) {
|
|
|
|
|
LocationServices.getGeofencingClient(context).removeGeofences(requestIds);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void newClient(final GoogleApi.GoogleApiClientConnectionHandler handler) {
|
|
|
|
|
new GoogleApi(context).connect(handler);
|
|
|
|
|
@SuppressWarnings("ConstantConditions")
|
|
|
|
|
private List<String> getRequestIds(List<Location> locations) {
|
|
|
|
|
return transform(newArrayList(filter(locations, notNull())), l -> Long.toString(l.getId()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<com.google.android.gms.location.Geofence> getRequests(List<Location> locations) {
|
|
|
|
|
return newArrayList(
|
|
|
|
|
transform(
|
|
|
|
|
filter(locations, l -> l.isArrival() || l.isDeparture()), this::toGoogleGeofence));
|
|
|
|
|
return transform(
|
|
|
|
|
newArrayList(filter(locations, l -> l != null && (l.isArrival() || l.isDeparture()))),
|
|
|
|
|
this::toGoogleGeofence);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private com.google.android.gms.location.Geofence toGoogleGeofence(Location location) {
|
|
|
|
|
|