地理围栏不会触发

时间:2016-02-27 19:05:45

标签: android service geofencing

我正在尝试构建地理围栏并对其进行监控,但似乎我的服务从未被调用过。这是我的Activity的代码:

public class GeofenceActivity extends AppCompatActivity implements
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, OnMapReadyCallback, ResultCallback<Status> {

List<Geofence> mGeofenceList = new ArrayList<Geofence>();

private PendingIntent mGeofencePendingIntent;

protected GoogleApiClient mGoogleApiClient;

public void startGeoService() {

        mGeofenceList.add(new Geofence.Builder()
                .setRequestId(mFormatted)

                .setCircularRegion(
                        mLatitude,
                        mLongitude,
                        mRadius
                )
                .setExpirationDuration(Geofence.NEVER_EXPIRE)
                .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
                        Geofence.GEOFENCE_TRANSITION_EXIT)
                .build());

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        LocationServices.GeofencingApi.addGeofences(
                mGoogleApiClient,
                getGeofencingRequest(),
                getGeofencePendingIntent()
        ).setResultCallback(this);

        Intent i = new Intent(GeofenceActivity.this, StatusActivity.class);
        startActivity(i);
    }

}

private GeofencingRequest getGeofencingRequest() {
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
    builder.addGeofences(mGeofenceList);
    Log.d("Geofencing", "getGeofencing request");
    return builder.build();
}

private PendingIntent getGeofencePendingIntent() {
    // Reuse the PendingIntent if we already have it.
    if (mGeofencePendingIntent != null) {
        return mGeofencePendingIntent;
    }
    Log.d("Geofencing", "PendingIntent");
    Intent intent = new Intent(this, GeofenceService.class);
    // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when
    // calling addGeofences() and removeGeofences().
    return PendingIntent.getService(this, 0, intent, PendingIntent.
            FLAG_UPDATE_CURRENT);
}

@Override
public void onConnected(Bundle connectionHint) {
    Log.i("mGoogleApiClient", "Connected to GoogleApiClient");
}

@Override
public void onConnectionFailed(ConnectionResult result) {
    // Refer to the javadoc for ConnectionResult to see what error codes might be returned in
    // onConnectionFailed.
    Log.i("mGoogleApiClient", "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}

@Override
public void onConnectionSuspended(int cause) {
    // The connection to Google Play services was lost for some reason.
    Log.i("mGoogleApiClient", "Connection suspended");

    // onConnected() will be called again automatically when the service reconnects
}

@Override
public void onResult(Status status) {
    if (status.isSuccess()) {

        Log.d("resultcallback", "success result");
    }
}

我的Service

public class GeofenceService extends IntentService  {


/**
 * Creates an IntentService.  Invoked by your subclass's constructor.
 *
 * @param name Used to name the worker thread, important only for debugging.
 */
public GeofenceService(String name) {
    super("GeofenceService");
}

protected void onHandleIntent(Intent intent) {
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
    if (geofencingEvent.hasError()) {

        Log.e("GEOFENCING", "error");
        return;
    }

    // Get the transition type.
    int geofenceTransition = geofencingEvent.getGeofenceTransition();
    Log.d("Geofencing", "SERVICE CALLED");
    // Test that the reported transition was of interest.
    if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
            geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {


        Log.d("GEOFENCING", String.valueOf(geofenceTransition));
        Log.d("GEOFENCING", "its working !!!");
    } else {
        // Log the error.
        Log.e("error", "invalid type");
    }


}
}

我的日志表明我正在浏览getGeofencingRequest()PendingIntent,但从未到GeofenceService。有什么建议吗?感谢。

1 个答案:

答案 0 :(得分:0)

确保在即将设置地理围栏时启用了位置服务。把它放在onCreate

// Kick off the request to build GoogleApiClient.
buildGoogleApiClient();

LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
        !locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
    locationSettingsRequest();
}

//如果没有提示用户将其打开 //我从另一个答案中得到了这部分代码。

//将此添加到您的活动

public void locationSettingsRequest()
{
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(30 * 1000);
    locationRequest.setFastestInterval(5 * 1000);
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest);
    builder.setAlwaysShow(true); //this is the key ingredient

PendingResult<LocationSettingsResult> result =
        LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
    @Override
    public void onResult(LocationSettingsResult result) {
        final Status status = result.getStatus();
        final LocationSettingsStates state = result.getLocationSettingsStates();
        switch (status.getStatusCode()) {
            case LocationSettingsStatusCodes.SUCCESS:
                // All location settings are satisfied. The client can initialize location
                // requests here.
                break;
            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                // Location settings are not satisfied. But could be fixed by showing the user
                // a dialog.
                try {
                    // Show the dialog by calling startResolutionForResult(),
                    // and check the result in onActivityResult().
                    status.startResolutionForResult(EventDetailsFragmentActivity.this, REQUEST_CHECK_SETTINGS);
                } catch (IntentSender.SendIntentException e) {
                    // Ignore the error.
                }
                break;
            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                // Location settings are not satisfied. However, we have no way to fix the
                // settings so we won't show the dialog.
                break;
        }
    }
});

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        // Check for the integer request code originally supplied to startResolutionForResult().
        case REQUEST_CHECK_SETTINGS:
            switch (resultCode) {
                case Activity.RESULT_OK:
                    break;
                case Activity.RESULT_CANCELED:
                    //locationSettingsRequest();
                    break;
            }
            break;
    }
}