问题
I need some clarity on the sample code supplied with Geofence guide as posted here :
https://developer.android.com/training/location/geofencing.html
I ran the code and I see that geofences are created correctly, but what I really want is a way to get alerted when I drive to those geofenced locations. Right now, when I go past those geofenced spots, nothing happens (ReceiveTransitionsIntentService does not get called), no notifications nothing.
Do I also have to listen to periodic location updates and pass lat/lng to the above piece of code manually to indicate my current location? I thought this should be automatic when I add geofences to LocationClient, but I guess there is more.
I also tried registering a LocationRequest to the LocationClient instance, but still no alerts :
mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(LocationUtils.UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setFastestInterval(LocationUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS);
mLocationClient.requestLocationUpdates(mLocationRequest, (LocationListener)mActivity);
How does one integrate Geofence api with location tracking?
回答1:
I also had issues. Make sure your path is defined correctly when adding the service to your AndroidManifest. I also had to change the exported value to true.
<application>
...
<service
android:name=".ReceiveTransitionsIntentService"
android:exported="true" >
</service>
...
</application>
You also need to add the meta-data tag in your Manifest to specify your google gms version.
<application>
...
<meta-data
android:name="com.google.android.gms.version"
android:value="4242000" />
...
</application>
I've created a much simpler version of the Google example, with code and more explanation, here. Hope that helps!
回答2:
Unfortunately this seems to be the expected behaviour. The Geofence API is set-up to listen for automatic location updates on the device. This generally works when you settle at a location, but as you said, if you are driving through a fence or you have one with a radius of only a few meters you are likely to miss it. The API is said to automatically check your behaviour (walking, driving etc.) and update more frequently if so, but this does not seem to be the case.
You'll notice if you have Google Maps open and tracking your location, the fences will be triggered correctly.
You can therefore assume that the only real solution is to set up your own service which polls for location at defined intervals (Google recommend 20 seconds https://www.youtube.com/watch?v=Bte_GHuxUGc) which will then force a location broadcast at these intervals. Geofences are then automatically triggered if they are within this location.
回答3:
Some quick notes: Ensure that you have the proper transitions selected. You may want to set both the entrance and the exit transition.
The code snippet for Geofencing doesn't display a notification. That's deliberate; notifications are not always the best response to a transition. The sample application displays a notification, and you can see this if you download the sample.
Location Services does its best to identify your location.
Also remember that you have to request ACCESS_FINE_LOCATION.
You won't find anything specific regarding geofence tracking (or anything else related to location) in a background "process". All of it is within Google Play services.
回答4:
@andrewmolo I had that same issue when I tried. You should set-up proper build path and library for your project. It worked for me when I setup as following.
- Go to Properties of your project > Android > Select Google APIs.
- Properties > Java Build Path > Libraries.
Ensure you have
1. android-support-v4.jar
2. Google APIs
3. google-play-services_lib.jar
4. google-play-services.jar
Also in order and export you should have Google APIs at bottom position and all other selected.
回答5:
I had some trouble with the sample code as well. Here is what worked for me.
latitude = sharedPreferences.getFloat("storeAddress_lat", -1);
longitude = sharedPreferences.getFloat("storeAddress_lng", -1);
final ArrayList<Geofence> list = new ArrayList<Geofence>();
Builder builder = new Geofence.Builder();
builder.setRequestId("near_store_geofence");
builder.setCircularRegion(latitude, longitude, 50);
builder.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER);
builder.setExpirationDuration(Geofence.NEVER_EXPIRE);
list.add(builder.build());
builder = new Geofence.Builder();
builder.setRequestId("leave_store_geofence");
builder.setCircularRegion(latitude, longitude, 50);
builder.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT);
builder.setExpirationDuration(Geofence.NEVER_EXPIRE);
list.add(builder.build());
final GooglePlayServicesClient.ConnectionCallbacks connectionCallbacks = new GooglePlayServicesClient.ConnectionCallbacks(){
@Override
public void onConnected(Bundle connectionHint) {
Log.i("GEOFENCE","onConnected");
// Create an explicit Intent
Intent intent = new Intent(getBaseContext(), ReceiveTransitionsIntentService.class);
/*
* Return the PendingIntent
*/
PendingIntent pendingIntent = PendingIntent.getService(
getBaseContext(),
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
locationClient.addGeofences(list,pendingIntent, new OnAddGeofencesResultListener(){public void onAddGeofencesResult(int statusCode, String[] geofenceRequestIds) {
Log.i("GEOFENCE","onAddGeofencesResult");
}});
LocationRequest locationrequest = LocationRequest.create();
locationrequest.setPriority(locationrequest.PRIORITY_HIGH_ACCURACY);
locationrequest.setInterval(5000);
locationClient.requestLocationUpdates(locationrequest, new LocationListener(){
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
}});
}
@Override
public void onDisconnected() {
Log.i("GEOFENCE","onDisconnected");
}
};
GooglePlayServicesClient.OnConnectionFailedListener onConnectionFailedListener = new GooglePlayServicesClient.OnConnectionFailedListener(){
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.i("GEOFENCE","onConnectionFailed");
}
};
locationClient = new LocationClient(getBaseContext(), connectionCallbacks, onConnectionFailedListener);
locationClient.connect();
回答6:
GPS is never enabled by the geofencing API (which is awful, I need responsive geofences dammit and don't care about power consumption). This is also not mentioned anywhere in the documentation. Also, without GPS you can't possibly hope to have smaller geofences due to the lack of accuracy with wifi/cell.
You have to poll the GPS separately with a null handler so that the worthwhile locations provided to that null handler also get provided to the geofencing API, reliably triggering your geofences.
回答7:
Note the the example contains an error that will make your fences expire after 12 minutes instead of the intended 12 hours... To fix change
private static final long SECONDS_PER_HOUR = 60;
to
private static final long SECONDS_PER_HOUR = 60*60;
in MainActivity
来源:https://stackoverflow.com/questions/16692550/new-android-geofence-api-sample-code-does-not-alert-notify-when-at-location