使用play-services-location 11.0.2进行Android Geofencing

时间:2017-08-11 11:07:35

标签: android google-play-services geofencing

我尝试使用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));
    }
}

}

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

  

您无需调用 requestLocationUpdates 来添加geoFence。

您只需要具有位置(纬度,经度)的地理围栏进行监控。并且无需为此使用服务( GeofencingService )。使用简单的活动并附上将在 GeofenceReceiver

中收到的mGeofencePendingIntent

当您使用Geofence.GEOFENCE_TRANSITION_ENTER

进入围栏时,它会在GeofenceReceiver中通知您