【问题标题】:How to deal with background geofencing in 2019?2019年如何应对后台地理围栏?
【发布时间】:2019-04-28 17:13:28
【问题描述】:

情况如下:

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

我有两个课程MainActivityFormActivity。这两个活动都注册了地理围栏,所以我将实际注册提取到一个普通的 POJO Geofences.java

问题出在这里:

现在奇怪的是,只有当地图活动在屏幕上时才会收到触发器。我的应用中确实有一个地图活动,但它甚至不必是我的地图活动,即使我启动谷歌地图地理围栏触发器开始触发。

我做错了什么?

地理围栏.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 然后被我的两个活动使用:

主活动:

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);
    }
}

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

更新:

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

【问题讨论】:

  • 我想知道您是否有解决方案,我正在努力解决同样的问题。
  • 不,永远找不到真正的解决方案:D

标签: java android geofencing android-geofence


【解决方案1】:

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

这是由于在 Android Oreo 及更高版本中添加了background restrictions

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

处理这个问题:

  • 添加广播接收器以接收意图。 (此接收器将获得 即使应用在后台也能发出地理围栏警报)
  • 将服务替换为 JobIntentService。 (这将使用 OS JobSchedular 即使有后台限制也能运行)
  • 从待处理的意图而不是服务获取广播。

查看此sample project 以获得进一步说明。

【讨论】:

  • 但我确实得到了触发器,只有当任何应用程序请求地理修复时。
  • @Marci-man 您找到解决方案了吗?即使你的应用被杀死(Activity 被刷掉)?
  • 每当操作系统获取位置(由您或任何其他应用程序请求)时,如果满足其要求,即用户移入或移出地理围栏,就会触发地理围栏。
  • 一种解决方案是在 5 或 10 分钟等固定间隔后获取位置修复。这样,当操作系统获取位置并将其与注册的地理围栏进行比较时,就会触发地理围栏。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 2016-09-30
  • 2016-11-10
  • 1970-01-01
相关资源
最近更新 更多