Well, maybe a little late, but I will send an answer to the question of how I myself fixed this problem. Two things:
1) I added geo objects every time I launch the MainActivity API and geofences, fires the geofencing event if you add geo-images when you are already in the specified geoprobe (i.e., starting from the geofence application when you are already in the geoforum) . Therefore, I changed my code in the onConnected method to add geo objects only if they have not been added before. (Implemented verification using general settings)
public void onConnected(Bundle bundle) { Log.i(TAG, "Connected to GoogleApiClient"); SharedPreferences sharedPrefs = MainActivity.this.getSharedPreferences("GEO_PREFS", Context.MODE_PRIVATE); String geofencesExist = sharedPrefs.getString("Geofences added", null); if (geofencesExist == null) { LocationServices.GeofencingApi.addGeofences( mGoogleApiClient, getGeofencingRequest(), getGeofencePendingIntent(this) ).setResultCallback(new ResultCallback<Status>() { @Override public void onResult(Status status) { if (status.isSuccess()) { SharedPreferences sharedPrefs = MainActivity.this.getSharedPreferences("GEO_PREFS", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPrefs.edit(); editor.putString("Geofences added", "1"); editor.commit(); } } }); } }
2) . It turned out that the reasons for not receiving notifications when the application is unavailable were
i) Either I switched location services to the device (on / off / battery saving / device only / high accuracy) at least once after adding geo-images or
ii) The device rebooted.
To overcome this, I added a broadcast receiver to listen for device reboots and switching location services. In the receiver, I add geo objects again if the device rebooted or the search services switched.
public class BootReceiver extends BroadcastReceiver implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> { private static GoogleApiClient mGoogleApiClient; private static List<Geofence> mGeofenceList; private static PendingIntent mGeofencePendingIntent; private static final String TAG = "BootReceiver"; Context contextBootReceiver; @Override public void onReceive(final Context context, Intent intent) { contextBootReceiver = context; SharedPreferences sharedPrefs; SharedPreferences.Editor editor; if ((intent.getAction().equals("android.location.MODE_CHANGED") && isLocationModeAvailable(contextBootReceiver)) || (intent.getAction().equals("android.location.PROVIDERS_CHANGED") && isLocationServciesAvailable(contextBootReceiver))) { // isLocationModeAvailable for API >=19, isLocationServciesAvailable for API <19 sharedPrefs = context.getSharedPreferences("GEO_PREFS", Context.MODE_PRIVATE); editor = sharedPrefs.edit(); editor.remove("Geofences added"); editor.commit(); if (!isGooglePlayServicesAvailable()) { Log.i(TAG, "Google Play services unavailable."); return; } mGeofencePendingIntent = null; mGeofenceList = new ArrayList<Geofence>(); mGeofenceList.add(new Geofence.Builder() .setRequestId("1") .setCircularRegion( Constants.MyAPP_LOCATION_LATITUDE, Constants.MyAPP_LOCATION_LONGITUDE, Constants.MyAPP_LOCATION_RADIUS ) .setExpirationDuration(Constants.GEOFENCE_EXPIRATION_TIME) .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_DWELL | Geofence.GEOFENCE_TRANSITION_EXIT) .setLoiteringDelay(30000) .build()); mGoogleApiClient = new GoogleApiClient.Builder(contextBootReceiver) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); mGoogleApiClient.connect(); } } private boolean isLocationModeAvailable(Context context) { if (Build.VERSION.SDK_INT >= 19 && getLocationMode(context) != Settings.Secure.LOCATION_MODE_OFF) { return true; } else return false; } public boolean isLocationServciesAvailable(Context context) { if (Build.VERSION.SDK_INT < 19) { LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); return (lm.isProviderEnabled(LocationManager.GPS_PROVIDER) || lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)); } else return false; } public int getLocationMode(Context context) { try { return Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE); } catch (Settings.SettingNotFoundException e) { e.printStackTrace(); } return 0; } @Override public void onConnected(Bundle bundle) { Log.i(TAG, "Connected to GoogleApiClient"); SharedPreferences sharedPrefs = contextBootReceiver.getSharedPreferences("GEO_PREFS", Context.MODE_PRIVATE); String geofencesExist = sharedPrefs.getString("Geofences added", null); if (geofencesExist == null) { LocationServices.GeofencingApi.addGeofences( mGoogleApiClient, getGeofencingRequest(), getGeofencePendingIntent(contextBootReceiver) ).setResultCallback(new ResultCallback<Status>() { @Override public void onResult(Status status) { if (status.isSuccess()) { SharedPreferences sharedPrefs = contextBootReceiver.getSharedPreferences("GEO_PREFS", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPrefs.edit(); editor.putString("Geofences added", "1"); editor.commit(); } } }); } } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(ConnectionResult connectionResult) { if (connectionResult.hasResolution()) { try { connectionResult.startResolutionForResult((android.app.Activity) contextBootReceiver, Constants.CONNECTION_FAILURE_RESOLUTION_REQUEST); } catch (IntentSender.SendIntentException e) { Log.i(TAG, "Exception while resolving connection error.", e); } } else { int errorCode = connectionResult.getErrorCode(); Log.i(TAG, "Connection to Google Play services failed with error code " + errorCode); } } @Override public void onResult(Status status) { } private boolean isGooglePlayServicesAvailable() { int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(contextBootReceiver); if (resultCode != ConnectionResult.SUCCESS) { if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) { GooglePlayServicesUtil.getErrorDialog(resultCode, (android.app.Activity) contextBootReceiver, Constants.PLAY_SERVICES_RESOLUTION_REQUEST).show(); } else { Log.i(TAG, "This device is not supported."); } return false; } return true; } static GeofencingRequest getGeofencingRequest() { GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL); builder.addGeofences(mGeofenceList); return builder.build(); } static PendingIntent getGeofencePendingIntent(Context context) { if (mGeofencePendingIntent != null) { return mGeofencePendingIntent; } Intent intent = new Intent(context, GeofenceTransitionsIntentService.class); return PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); }
}
Android Manifest
. . . <receiver android:name=".BootReceiver" android:enabled="true" android:exported="false" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.location.MODE_CHANGED" /> <action android:name="android.location.PROVIDERS_CHANGED" /> </intent-filter> </receiver> . .