New Android Geofence Api - Sample code does not alert/notify when at location

a 夏天 提交于 2019-12-03 04:00:01

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!

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.

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.

@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.

  1. Go to Properties of your project > Android > Select Google APIs.
  2. 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.

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();

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.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!