1

On provider changed my geofences stops working otherwise everything else working fine. here is my code of broadcast receiver where i try to re-register my geofences .

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

public class LocationProviderChangedReceiver extends BroadcastReceiver implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,ResultCallback<Status> {
    int i=0;
    protected GoogleApiClient mGoogleApiClient;
    Geofence geofence;
    Context context;

    @Override
    public void onReceive(Context context, Intent intent) {
        i=i++;
        this.context=context;
        Toast.makeText(context,"Provider changed ,Geofencing restarted.",Toast.LENGTH_LONG).show();
        Log.wtf("senpai","oooooo"+i);
        LatLng latLng=new LatLng(28.5795613,77.3136267);

        geofence=new Geofence.Builder()
                .setRequestId("x").setCircularRegion(latLng.latitude,latLng.longitude, Constants.GEOFENCE_RADIUS_IN_METERS)
                .setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)
                .setLoiteringDelay(500)
                .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT|Geofence.GEOFENCE_TRANSITION_DWELL)
                .build();

        mGoogleApiClient = new GoogleApiClient.Builder(context)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        try {
            LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient, getGeofencePendingIntent()).setResultCallback(this); // Result processed in onResult().
            LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, getGeofencingRequest(), getGeofencePendingIntent()).setResultCallback(this); // Result processed in onResult().
        } catch (SecurityException securityException) {
            // Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission.
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onResult(@NonNull Status status) {

    }

    private PendingIntent getGeofencePendingIntent() {
        Intent intent = new Intent("ACTION_RECEIVE_GEOFENCE");
        // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling addgeoFences()
        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private GeofencingRequest getGeofencingRequest() {
        GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
        builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
        builder.addGeofence(geofence);
        return builder.build();
    }
}

In my activity i have done the same . How do i restart my geofencing?

user6265154
  • 353
  • 1
  • 6
  • 19
  • Please see [my answer to a similar question](https://stackoverflow.com/a/50869301/766755) as I believe it should cover all the cases where you should re-register geofences based on the documentation. – Michael Krause Jul 26 '18 at 21:13

1 Answers1

1

To keep your geo-fences running, you have to re-register your geo-fences on (a) location provider changes and also (b) device reboot:

Here are some snippets from my working Geofencer example, which tests Google Play Geofencing and compares it to another library:

Register a broadcast-receiver in the manifest for both events:

    <!-- Listen for the device starting up for re-registration tasks -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
    <receiver
        android:name=".geo.GeoRestartReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <category android:name="android.intent.category.DEFAULT" />

            <action android:name="android.intent.action.BOOT_COMPLETED" /> <!-- android.intent.action.LOCKED_BOOT_COMPLETED would be triggered earlier, in case we don't need access to credential secure storage -->
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            <action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
            <action android:name="android.location.PROVIDERS_CHANGED" />
        </intent-filter>
    </receiver>

Create a receiver that (re)starts your GeoFencing (by re-creating geofence-requests:

public class GeoRestartReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (!GeoLocationUtil.isGpsEnabled(context) || !GeoLocationUtil.hasGpsPermissions(context))
            return;

        GeofenceSettings settings = new GeofenceSettings(context);
        if (!settings.isGeofencingActive()) {
            return;
        }

        GeofenceProvider geofenceProvider = new PlayGeofenceProvider(context);
        geofenceProvider.start(homeLocation, enterRadius, exitRadius,
            initTrigger, usePolling);
    }
}

Most of the Google-Geofencing API logic is encapsuled within my custom classes. Just check out the Geofencer repo to see more details.

b3nk4n
  • 1,101
  • 1
  • 11
  • 17