我尝试使用GooglePlayServices最新版本在Android上实施Geofencing。
我决定使用Geofencing,因为我只有在移动时才需要知道用户的位置,因为我的应用程序在24/7全天候运行,所以我需要一些非常低的功耗。
在我的代码中,如果我没有实现" requestLocationUpdates"那么就不会触发地理围栏。 LocationServices。这真的很奇怪,因为我读到通常我们不需要使用它,并且它不再是低功耗。
是否有人使用最新的GooglePlayService实施地理围栏并且未实施" requestLocationUpdates"?
我的代码:
清单:
<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>
服务:
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());
}
}
接收者:
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));
}
}
}
感谢您的帮助
答案 0 :(得分:0)
您无需调用 requestLocationUpdates 来添加geoFence。
您只需要具有位置(纬度,经度)的地理围栏进行监控。并且无需为此使用服务( GeofencingService )。使用简单的活动并附上将在 GeofenceReceiver
中收到的mGeofencePendingIntent
当您使用Geofence.GEOFENCE_TRANSITION_ENTER