2017-08-11 2 views
0

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

+1

haben Sie das Bewusstsein api für diese Art von Aufgabe in Betracht gezogen? –

+0

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

Antwort

0

Sie müssen requestLocationUpdates nicht nennen für das Hinzufügen von Geofence.

Sie benötigen nur einen Geofence mit Standort (Breite, Länge) zu überwachen. Und keine Notwendigkeit, Service (GeofencingService) dafür zu verwenden. Verwenden Sie einfache Aktivität und befestigen mGeofencePendingIntent die in GeofenceReceiver erhalten

Es benachrichtigt Sie in GeofenceReceiver, wenn Sie den Zaun betreten mit Geofence.GEOFENCE_TRANSITION_ENTER

Verwandte Themen