当应用程序死亡时进行地理围栏

Mot*_*lal 5 android geofencing android-geofence google-location-services

来自Google的新Geofencing API在应用程序耗尽时不会触发任何事件.我尝试使用PendingIntent.getBroadcast(),PendingIntent.getService()但只能在应用程序打开时获得转换事件.

我从代码实验室学习了教程,但修改了代码以使用新的GeofencingClient

UPDATE

这是我创建待定意图的方式:

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;
 }
Run Code Online (Sandbox Code Playgroud)

我的GeoReceiver onReceive方法中的代码.在使用Services inside onHandleIntent方法时,代码类似

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Sac*_*rma 0

地理围栏不起作用,因为某些设备默认情况下仅允许某些白名单应用程序提供后台服务。如果您的应用程序也必须像这样工作,这意味着您必须从设置中启用自动启动,下面的代码将帮助您让用户为您的应用程序启用自动启动。如果启用了自动启动,您的服务将在后台正常运行。

为了手机更好的性能,一些公司会停止应用程序的所有后台服务(“一些列入白名单的应用程序将只有权在后台执行服务,例如:WhatsApp,Google Apps和知名应用程序。”)。如果我们的应用程序也必须像这样工作,则意味着我们必须启用自动启动服务。

自动启动:

当Android系统启动时,它会发出启动完成事件。Android 应用程序可以侦听并捕获此事件以采取特定操作,例如自动启动活动或服务。

目前还没有办法判断是否自动启动是否启用。因此,您可以将它们重定向到设置并告诉用户启用它。我正在为大多数常见手机公司提供重定向代码,这将杀死后台服务。(仅向用户显示一次,使用 SharedPreference 进行管理,正如我之前所说无法确定它是启用还是禁用。)

为了达成这个,

在AndroidManifest.xml中声明权限。将android.permission.RECEIVE_BOOT_COMPLETED权限添加到应用程序声明节点之前的应用程序清单文件中:

这是必须调用的功能代码。

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();
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • 如果您从自己的项目中复制代码,至少取出所有细节 (2认同)