Geofencing when the application is dead

Google’s new Geofencing API does not trigger any of the events when the application is dead. I tried using PendingIntent.getBroadcast() and PendingIntent.getService() , but only the ability to receive transition events when the application opens.

I followed this tutorial from code labs, but adapted the code to use the new GeofencingClient

UPDATE

This is how I create the pending intent:

 private PendingIntent getGeofencePendingIntent() { if (mGeofencePendingIntent != null) { Log.d(TAG, "Pending intent is already there"); return mGeofencePendingIntent; } Log.d(TAG, "Creating a new pending intent"); // In case I'm using Service, the second parameter will be GeoIntentService.class Intent mIntent = new Intent(mContext, GeoReceiver.class); // In case I'm using Service, the method will be getService(...) mGeofencePendingIntent = PendingIntent.getBroadcast(mContext, 0, mIntent, PendingIntent.FLAG_UPDATE_CURRENT); return mGeofencePendingIntent; } 

The code is inside my GeoReceiver onReceive method. One way or another, the code is similar when using services inside the onHandleIntent method

 @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "onReceive"); if (intent == null) { Log.e(TAG, "Intent is null"); return; } final String action = intent.getAction(); if (ACTION_ADD_GEOFENCE.equals(action)) { GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); if (geofencingEvent.hasError()) { String errMsg = GeofenceExceptionMessages.getErrorString(context, geofencingEvent.getErrorCode()); Log.e(TAG, "onReceive Error: " + errMsg); return; } int geofenceTransition = geofencingEvent.getGeofenceTransition(); if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences(); NotificationHelper helper = new NotificationHelper(); String geofenceTransitionDetails = helper.getGeofenceTransitionDetails( context, geofenceTransition, triggeringGeofences ); helper.sendNotificaiton(context, geofenceTransitionDetails); Log.i(TAG, "onReceive: " + geofenceTransitionDetails); } } else { Log.d(TAG, "Diffirent Action: " + action); } } 
+5
source share
1 answer

Geofencing does not work because some devices only allow background services for any whitelist by default. If your application should also work this way, you must enable Autostart from the settings, the code below will help you enable Autostart for your application. If AutoPlay is enabled, your service will work well in the background.

For the phone to work better, some companies will stop all background services of the application ("Some whitelists will only have permission to execute services in the background, for example: WhatsApp, Google Apps and well-known applications."). So if our application should also work that way, we should enable Autostart Services.

Autostart:

When the Android system boots up, it sends a download completion event. Android applications can listen to and record this event to take certain actions, such as automatically starting an activity or service.

At the moment, it is impossible to determine whether Autostart is enabled or not. Thus, you can redirect them to the settings and tell the user to enable it. I provide redirection codes for most regular telephone companies that will kill background service. (Show it only to the user, control it using SharedPreference, as I said earlier there is no way to determine if it is enabled or disabled.)

To achieve this,

Declare permission in AndroidManifest.xml . Add the android.permission.RECEIVE_BOOT_COMPLETED permission to the application manifest file immediately before the node application declaration:

This is the function code to be called.

 private void enableAutoStart() { if (Build.BRAND.equalsIgnoreCase("xiaomi")) { new MaterialDialog.Builder(MainActivity.this).title("Enable AutoStart") .content( "Please allow AppName to always run in the background,else our services can't be accessed.") .theme(Theme.LIGHT) .positiveText("ALLOW") .onPositive(new MaterialDialog.SingleButtonCallback() { @Override public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")); startActivity(intent); } }) .show(); } else if (Build.BRAND.equalsIgnoreCase("Letv")) { new MaterialDialog.Builder(MainActivity.this).title("Enable AutoStart") .content( "Please allow AppName to always run in the background,else our services can't be accessed.") .theme(Theme.LIGHT) .positiveText("ALLOW") .onPositive(new MaterialDialog.SingleButtonCallback() { @Override public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity")); startActivity(intent); } }) .show(); } else if (Build.BRAND.equalsIgnoreCase("Honor")) { new MaterialDialog.Builder(MainActivity.this).title("Enable AutoStart") .content( "Please allow AppName to always run in the background,else our services can't be accessed.") .theme(Theme.LIGHT) .positiveText("ALLOW") .onPositive(new MaterialDialog.SingleButtonCallback() { @Override public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")); startActivity(intent); } }) .show(); } else if (Build.MANUFACTURER.equalsIgnoreCase("oppo")) { new MaterialDialog.Builder(MainActivity.this).title("Enable AutoStart") .content( "Please allow AppName to always run in the background,else our services can't be accessed.") .theme(Theme.LIGHT) .positiveText("ALLOW") .onPositive(new MaterialDialog.SingleButtonCallback() { @Override public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { try { Intent intent = new Intent(); intent.setClassName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity"); startActivity(intent); } catch (Exception e) { try { Intent intent = new Intent(); intent.setClassName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity"); startActivity(intent); } catch (Exception ex) { try { Intent intent = new Intent(); intent.setClassName("com.coloros.safecenter", "com.coloros.safecenter.startupapp.StartupAppListActivity"); startActivity(intent); } catch (Exception exx) { } } } } }) .show(); } else if (Build.MANUFACTURER.contains("vivo")) { new MaterialDialog.Builder(MainActivity.this).title("Enable AutoStart") .content( "Please allow AppName to always run in the background.Our app runs in background else our services can't be accesed.") .theme(Theme.LIGHT) .positiveText("ALLOW") .onPositive(new MaterialDialog.SingleButtonCallback() { @Override public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { try { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity")); startActivity(intent); } catch (Exception e) { try { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity")); startActivity(intent); } catch (Exception ex) { try { Intent intent = new Intent(); intent.setClassName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.BgStartUpManager"); startActivity(intent); } catch (Exception exx) { ex.printStackTrace(); } } } } }) .show(); } } 
0
source

Source: https://habr.com/ru/post/1273840/


All Articles