package pl.charmas.android.reactivelocation.sample;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingRequest;
import pl.charmas.android.reactivelocation.ReactiveLocationProvider;
import pl.charmas.android.reactivelocation.sample.utils.DisplayTextOnViewAction;
import pl.charmas.android.reactivelocation.sample.utils.LocationToStringFunc;
import rx.Observable;
import rx.Subscription;
import rx.functions.Action1;
import rx.functions.Func1;
import static pl.charmas.android.reactivelocation.sample.utils.UnsubscribeIfPresent.unsubscribe;
public class GeofenceActivity extends BaseActivity {
private static final String TAG = "GeofenceActivity";
private ReactiveLocationProvider reactiveLocationProvider;
private EditText latitudeInput;
private EditText longitudeInput;
private EditText radiusInput;
private TextView lastKnownLocationView;
private Subscription lastKnownLocationSubscription;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
reactiveLocationProvider = new ReactiveLocationProvider(this);
setContentView(R.layout.activity_geofence);
initViews();
}
private void initViews() {
lastKnownLocationView = (TextView) findViewById(R.id.last_known_location_view);
latitudeInput = (EditText) findViewById(R.id.latitude_input);
longitudeInput = (EditText) findViewById(R.id.longitude_input);
radiusInput = (EditText) findViewById(R.id.radius_input);
findViewById(R.id.add_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addGeofence();
}
});
findViewById(R.id.clear_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clearGeofence();
}
});
}
@Override
protected void onLocationPermissionGranted() {
lastKnownLocationSubscription = reactiveLocationProvider
.getLastKnownLocation()
.map(new LocationToStringFunc())
.subscribe(new DisplayTextOnViewAction(lastKnownLocationView));
}
@Override
protected void onStop() {
super.onStop();
unsubscribe(lastKnownLocationSubscription);
}
private void clearGeofence() {
reactiveLocationProvider.removeGeofences(createNotificationBroadcastPendingIntent()).subscribe(new Action1<Status>() {
@Override
public void call(Status status) {
toast("Geofences removed");
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
toast("Error removing geofences");
Log.d(TAG, "Error removing geofences", throwable);
}
});
}
private void toast(String text) {
Toast.makeText(GeofenceActivity.this, text, Toast.LENGTH_SHORT).show();
}
private PendingIntent createNotificationBroadcastPendingIntent() {
return PendingIntent.getBroadcast(this, 0, new Intent(this, GeofenceBroadcastReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
}
private void addGeofence() {
final GeofencingRequest geofencingRequest = createGeofencingRequest();
if (geofencingRequest == null) return;
final PendingIntent pendingIntent = createNotificationBroadcastPendingIntent();
reactiveLocationProvider
.removeGeofences(pendingIntent)
.flatMap(new Func1<Status, Observable<Status>>() {
@Override
public Observable<Status> call(Status pendingIntentRemoveGeofenceResult) {
return reactiveLocationProvider.addGeofences(pendingIntent, geofencingRequest);
}
})
.subscribe(new Action1<Status>() {
@Override
public void call(Status addGeofenceResult) {
toast("Geofence added, success: " + addGeofenceResult.isSuccess());
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
toast("Error adding geofence.");
Log.d(TAG, "Error adding geofence.", throwable);
}
});
}
private GeofencingRequest createGeofencingRequest() {
try {
double longitude = Double.parseDouble(longitudeInput.getText().toString());
double latitude = Double.parseDouble(latitudeInput.getText().toString());
float radius = Float.parseFloat(radiusInput.getText().toString());
Geofence geofence = new Geofence.Builder()
.setRequestId("GEOFENCE")
.setCircularRegion(latitude, longitude, radius)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
.build();
return new GeofencingRequest.Builder().addGeofence(geofence).build();
} catch (NumberFormatException ex) {
toast("Error parsing input.");
return null;
}
}
}