地理围栏不会触发我的服务

时间:2017-04-22 12:39:13

标签: android google-maps-android-api-2 geofencing android-geofence

我已经阅读了各种教程,论坛和官方Google文档,仍然无法理解为什么我的代码无法按预期工作。有相关部分:

活动

public class MainMap extends FragmentActivity implements OnMarkerClickListener, OnMapReadyCallback,
        ConnectionCallbacks, OnConnectionFailedListener, LocationListener, ActivityCompat.OnRequestPermissionsResultCallback, ResultCallback<Status> {

    private static final int REQUEST_ACCESS_FINE_LOCATION = 0;
    protected GoogleApiClient mGoogleApiClient;
    protected Location mCurrentLocation;
    protected LocationRequest mLocationRequest;
    private GoogleMap m_map;
    private SupportMapFragment m_map_fragment;

    protected ArrayList<Geofence> mGeofenceList;
    private PendingIntent mGeofencePendingIntent;
    private boolean m_geofences_added;
    private SharedPreferences m_preferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_map);
        m_preferences = this.getSharedPreferences("com.example",Context.MODE_PRIVATE);
        // map fragment
        m_map_fragment= (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        m_map_fragment.getMapAsync(this);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // location and geofences
        add_location_and_geofences();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        // remove geofences
        LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient, getGeofencePendingIntent());
        super.onStop();
        mGoogleApiClient.disconnect();
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        // permissions
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            request_fine_location_permission();
        }
        // location
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        // geofencing
        try {
            LocationServices.GeofencingApi.addGeofences(
                    mGoogleApiClient,
                    getGeofencingRequest(),
                    getGeofencePendingIntent()
            ).setResultCallback(this);
        } catch (SecurityException securityException) {
            Log.e(TAG, "Invalid location permission. " +
                    "You need to use ACCESS_FINE_LOCATION with geofences", securityException);
        }
    }

    public void onResult(Status status) {
        if (status.isSuccess()) {
        } else {
            String errorMessage = GeofenceErrorMessages.getErrorString(this,
                    status.getStatusCode());
            Log.e(TAG, errorMessage);
        }
    }

    private void add_location_and_geofences() {
        for (int i =0; i < 3; i++) {
            mGeofencePendingIntent = null;
            mGeofenceList = new ArrayList<>();
            mGeofenceList.add(new Geofence.Builder()
                    .setRequestId(Integer.toString(i)) // request id is the index so that I can later retrieve it
                    .setCircularRegion( /* I set coordinates here and a radius of 10meters*/)
                    .setExpirationDuration(NEVER_EXPIRE)
                    .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_DWELL)
                    .setLoiteringDelay(4000)
                    .build());
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
            mLocationRequest = new LocationRequest();
            mLocationRequest.setInterval(1000);
            mLocationRequest.setFastestInterval(500);
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        }
    }

    private PendingIntent getGeofencePendingIntent() {
        if (mGeofencePendingIntent != null) {
            return mGeofencePendingIntent;
        }
        Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
        return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private GeofencingRequest getGeofencingRequest() {
        GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
        builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL);
        builder.addGeofences(mGeofenceList);
        return builder.build();
    }
}

我的服务:

public class GeofenceTransitionsIntentService extends IntentService {

    private Intent m_intent;

    @Override
    public void onCreate() {
        super.onCreate();
        m_intent = new Intent(this, Guide.class);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
        if (geofencingEvent.hasError()) {
            String errorMessage = GeofenceErrorMessages.getErrorString(this,
                    geofencingEvent.getErrorCode());
            Log.e(TAG, errorMessage);
        } else {
            if (debug_mode) {
                Log.i(TAG, "something has been received");
            }
            int geofenceTransition = geofencingEvent.getGeofenceTransition();
            if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL) {
                List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
                for (Geofence geofence : triggeringGeofences) {
                        Log.i(TAG, "INSIDE GEOFENCE");
                }
            } else {
                Log.e(TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition));
            }
        }
    }
}

和我的清单

<service android:name="com.example.GeofenceTransitionsIntentService" />

使用此代码地理围栏无声地失败 - 我的服务永远不会被触发,无论是在室内使用wifi还是在户外使用3G / 4G网络。

1 个答案:

答案 0 :(得分:0)

您是在寻找停留事件,还是进入和退出活动?如果是后者,请将初始触发器设置为INITIAL_TRIGGER_ENTER,将转换类型设置为GEOFENCE_TRANSITION_ENTER| GEOFENCE_TRANSITION_EXIT

如果您正在寻找停留事件,您需要在地理围栏内停留约5分钟以获得初始触发。当你离开时,你不会得到任何关于它的事件,但是一旦你重新进入它,你需要再次在你的地理围栏中再呆5分钟才能举办你的活动。