java - 2022年如何应对后台地理围栏?

标签 java android geofencing android-geofence

情况是这样的:

当用户创建地理围栏时,我将其保存到后端并向操作系统注册地理围栏。但是每当我的应用程序重新启动时,我都会从后端获取地理围栏并再次向操作系统重新注册它们,因为它们一直在消失。

我有两个类 MainActivityFormActivity。这两个 Activity 都注册了 Geofences,所以我将实际注册提取到一个普通的 POJO Geofences.java

问题是:

现在奇怪的是,只有在屏幕上显示 map Activity 时才会收到触发器。我的应用程序中确实有 map Activity ,但它甚至不必是我的 map Activity ,即使我启动谷歌地图地理围栏触发器开始触发也是如此。

我做错了什么?

地理围栏.java:

public class Geofences {

    private final String TAG = Geofences.class.getSimpleName();
    private final float RADIUS = 150.0F; //meter
    private boolean success = false;

    private final int LOITERING_IN_MILLISECONDS = 30000;// 30 seconds

    public boolean doGeofenceStuff(GeoTemp newTemp, String geofenceId, PendingIntent pendingIntent, GeofencingClient geofencingClient) {

        Geofence geofence = createGeofence(newTemp, geofenceId);
        GeofencingRequest geofencingRequest = createGeofenceRequest(geofence);
        geofencingClient.addGeofences(geofencingRequest, pendingIntent)
                .addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        if (task.isSuccessful()) {
                            success = true;
                            Log.i(TAG, "onComplete: DEBUG-Message: Geofence has been added.");

                        } else {
                            success = false;
                            Log.i(TAG, "onComplete: Geofence could not be added");
                        }
                    }
                }); // handle error here
        return success;
    }

    // Create a Geofence
    private Geofence createGeofence(GeoTemp geoTemp, String geofenceId) {


        long expiration = getExpirationForCurrentGeofence();
        if (expiration < 1) {
            Log.e(TAG, "createGeofence: Can't create Geofence, since expiration is less than zero");
            return null;
        }
        Log.d(TAG, "createGeofence");
        return new Geofence.Builder()
                .setRequestId(geofenceId)
                .setCircularRegion(getLat(), getLong(), RADIUS)
                .setExpirationDuration(expiration)
                .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_DWELL | Geofence.GEOFENCE_TRANSITION_EXIT)
                .setLoiteringDelay(LOITERING_IN_MILLISECONDS)
                .build();
    }

    // Create a Geofence Request
    private GeofencingRequest createGeofenceRequest(Geofence geofence) {
        Log.d(TAG, "createGeofenceRequest");
        return new GeofencingRequest.Builder()
                .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL)
                .addGeofence(geofence)
                .build();
    }

}

这个 POJO Geofences.java 然后被我的两个 Activity 使用:

主要 Activity :

public class MainActivity extends AppCompatActivity {

    private static String TAG = "MainActivity";
    private final int GEOFENCE_REQ_CODE = 0;
    private GeofencingClient geofencingClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        geofencingClient = LocationServices.getGeofencingClient(this);
        getCurrentTemps();
    }

    private void refreshGeofence(GeoTemp temp, String id) {
        new Geofences().doGeofenceStuff(temp, id, createGeofencePendingIntent(), geofencingClient);
    }
    private void getCurrentTemps() {
        List<GeoTemp> currentGeofences = getUpdatedList();
        currentGeofences.forEach(geoTemp -> {
            refreshGeofence( geoTemp, id);
        });
    }
    private PendingIntent createGeofencePendingIntent() {
        Log.d(TAG, "createGeofencePendingIntent");
        Intent intent = new Intent(this, LocationAlertIntentService.class);
        return PendingIntent.getService(
                this, GEOFENCE_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }
}

还有一项 Activity 使用 Geofences.java 向操作系统注册地理围栏。

更新:

我发现,如果任何其他应用程序(包括我的应用程序)请求位置锁定,地理围栏就会触发。我需要它们在后台开火。

最佳答案

我在 android 中使用地理围栏时遇到了类似的问题。

发生这种情况是由于 background restrictions在 Android Oreo 及更高版本中添加。

操作系统不允许您的应用在后台启动服务,因此您不会收到地理围栏触发器。

要处理这个:

  • 添加广播接收器以接收 Intent 。 (这个接收器会得到 地理围栏警报,即使应用程序处于后台)
  • 用 JobIntentService 替换服务。 (这将使用 OS JobSchedular 甚至在有后台限制的情况下运行)
  • 从挂起的 Intent 而不是服务获取广播。

检查这个 sample project进一步说明。

关于java - 2022年如何应对后台地理围栏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55892711/

相关文章:

ios - Swift 区域监控本地通知触发器

android - 背景地理围栏真的适用于 Android 8+ 吗?

java - 使用 switch/if 语句将字母等级转换为数字等级?

android - 在关闭应用程序之前保存值?

java - 如何在ubuntu上安装apache-poi

java - 如何使用旋转项目

android - 在 SupportMapFragment 中引用 MapView

android - 当我使用 putExtra() 时地理围栏事件出错

java - html页面不会在android api 8 webview中呈现但在浏览器中可以

java - retrofit /Sphere 引擎 API 错误 : undefined reference to `main'