Ich versuche, Geofencing auf Android mit der neuesten Version von GooglePlayServices zu implementieren.Android Geofencing mit Play-Services-Standort 11.0.2
Ich habe mich für Geofencing entschieden, weil ich den Standort des Benutzers nur dann kennen muss, wenn er sich bewegt, und ich brauche etwas sehr geringen Stromverbrauch, weil meine Apps rund um die Uhr im Hintergrund laufen.
In meinem Code wird das Geofencing nicht ausgelöst, wenn ich die "requestLocationUpdates" von LocationServices nicht implementiere. Es ist wirklich komisch, weil ich gelesen habe, dass wir das normalerweise nicht brauchen, und es ist kein niedriger Stromverbrauch mehr damit.
Wird jemals Geofencing mit dem neuesten GooglePlayService und ohne Implementierung von "requestLocationUpdates" implementiert?
Mein Code:
Manifest:
<service
android:name=".gps.GeofencingService"
android:enabled="true"
android:exported="true" />
<receiver
android:name=".gps.GeofenceReceiver"
android:exported="true"
>
<intent-filter>
<action android:name="android.location.MODE_CHANGED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
<action android:name="android.location.PROVIDERS_CHANGED" />
</intent-filter>
</receiver>
Service:
public class GeofencingService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
//My singleton
private static GeofencingService mInstant;
public static GeofencingService getInstant(){
return mInstant;
}
@Override
public void onCreate() {
super.onCreate();
mInstant = this;
mFusedLocationClient = getFusedLocationProviderClient(this);
mGeofencingClient = LocationServices.getGeofencingClient(this);
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
public void addGeofence() {
if (mGoogleApiClient.isConnected()) {
LocationRequest mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(100); // Update location every second
//use to initiate the geofence region on my position
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location != null) {
mGeofenceList = new ArrayList();
mGeofenceList.add(new Geofence.Builder()
// Set the request ID of the geofence. This is a string to identify this
// geofence.
.setRequestId(idGeofence)
.setCircularRegion(
location.getLatitude(),
location.getLongitude(),
Constantes.GEOFENCE_RADIUS_IN_METERS
)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
mGeofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent())
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "Geofence added");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// Failed to add geofences
Log.d(TAG, "Failed to add geofences");
e.printStackTrace();
}
});
//if this line is removed, geofence is not triggered anymore
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//super.onStartCommand(intent, flags, startId);
mGoogleApiClient.connect();
return START_STICKY;
}
@Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "GoogleApiClient connected");
addGeofence();
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "GoogleApiClient connection has been suspend");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "GoogleApiClient connection has failed");
}
public void getCurrentLocation() {
//mFusedLocationClient.getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() {
FusedLocationProviderClient locationClient = getFusedLocationProviderClient(this);
locationClient.getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
Log.d(TAG, location.getLatitude() + "/" + location.getLongitude());
} else {
}
}
});
}
private PendingIntent getGeofencePendingIntent() {
// Reuse the PendingIntent if we already have it.
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
//Call a BroadcastReceiver
mGeofencePendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, GeofenceReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
return mGeofencePendingIntent;
}
private GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_EXIT);
builder.addGeofences(mGeofenceList);
return builder.build();
}
@Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Location Changed : " + location.getLatitude() + "/" + location.getLongitude());
}
}
Empfänger:
public class GeofenceReceiver extends BroadcastReceiver {
protected static final String TAG = "GeofenceReceiver";
protected Context applicationContext;
@Override
public void onReceive(final Context context, final Intent intent) {
applicationContext = context;
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
String errorMessage = GeofenceErrorMessages.getErrorString(context, geofencingEvent.getErrorCode());
Log.e(TAG, errorMessage);
return;
}
// Get the transition type.
int geofenceTransition = geofencingEvent.getGeofenceTransition();
// Test that the reported transition was of interest.
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
// Get the geofences that were triggered. A single event can trigger
// multiple geofences.
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
// Get the transition details as a String.
String geofenceTransitionDetails = getGeofenceTransitionDetails(geofenceTransition, triggeringGeofences);
Log.d(TAG, geofenceTransitionDetails);
Toast.makeText(context, geofenceTransitionDetails, Toast.LENGTH_LONG).show();
// Send notification and log the transition details.
sendNotification(geofenceTransitionDetails);
Log.i(TAG, geofenceTransitionDetails);
} else {
// Log the error.
Log.e(TAG, context.getString(R.string.geofence_transition_invalid_type,
geofenceTransition));
}
}
}
Danke für Ihre Hilfe
haben Sie das Bewusstsein api für diese Art von Aufgabe in Betracht gezogen? –
Nein, es ist das erste Mal, dass ich von dieser API gehört habe! Scheint mächtig zu sein! Ich werde nachsehen, ob ich es benutzen kann ... Danke Tim! – Anthony