扫描信标并定期在前台获取位置

问题描述 投票:0回答:1

我正在使用信标库来扫描具有前台服务和持久通知的信标。我已经在Android 9.0和7.0上测试了这个,并且应用程序按预期工作,并且每隔30秒将扫描的信标发送到服务器。现在,我正在尝试将位置扫描添加到应用程序,以便它每30秒检索一次位置更新。我正在使用Google Play API,并设置间隔为30秒的位置请求。然后,我在我的应用程序类中创建了一个FusedLocationProvider客户端,所以我给了它我的应用程序(不是活动的)上下文。然后,我向客户提出了我的请求和以下回调:

locationCallback = new LocationCallback()
  {
     @Override
     public void onLocationResult(LocationResult locationResult)
     {
        if ( locationResult != null )
        {
           Log.d(TAG, "location acquired: " + locationResult.getLastLocation());
           beaconContainer.setLocation(locationResult.getLastLocation());
        }
     }
  };

beaconContainer对象包含信标列表和最新位置(以及使用LocalTime.now()获取最新位置的时间戳),并每隔30秒将这些信息发送到服务器。首先,应用程序似乎工作,位置时间戳在发送服务器请求的30秒内。但是,经过一段时间后(屏幕已关闭一段时间),似乎没有调用回调中的onLocationResult方法,并且没有更新位置。例如,服务器请求是在12:34进行的,但位置在10:21更新。请注意,信标扫描仍按预期正确执行。

我想知道这是因为我测试过的手机是静止的,还是因为我没有使用服务进行位置更新。对我来说,它似乎是前者,因为我的应用程序有一个前台服务(ble扫描程序)和持久通知,所以根据文档,它是在前台,它不应受到背景限制。如果是后者,我如何将信标库的前台服务与我的位置扫描融合,以便它们都按预期运行。

谢谢。

编辑:

以下是电池历史记录的屏幕截图,显示了在间歇性使用GPS时如何定期和一致地使用BLE。 Battery historian

android bluetooth-lowenergy android-location ibeacon-android foreground-service
1个回答
1
投票

FusedLocationProviderClient的文档表明,在Android 8+上,如果应用程序不在前台,您只能获得“每小时几次”的更新。见here。这可能是因为Google Play服务中的实施使用Android 8+上的JobScheduler来克服后台服务限制,并且作业仅限于在后台运行每15分钟+/- 5分钟。由于Google Play Services API是封闭源代码和专有API,因此很难详细说明其内部实现,但它不太可能考虑到您的应用程序具有前台服务。 (相比之下,Android Beacon Library明确设计为在使用Foreground Service配置时表现不同,因此您可以获得更频繁的更新。)

目前还不清楚FusedLocationProviderClient在Android 7的后台运行方式有何不同。它可能根本无法有所不同,并且如果您的应用程序针对SDK 26或更高版本,可能会在后台中遵循上述模式。您必须进行测试以确保 - 有效地逆向设计Google Play服务。即使您确定了这一点,行为也可能会在下一个Google Play服务版本中发生变化,除非您再次对其进行反向工程,否则您将永远不会知道它。这是使用闭源SDK的危险。

另一种方法是使用Android提供的开源位置API。

LocationManager locationManager = (LocationManager)
          this.getSystemService(Context.LOCATION_SERVICE);
try {

        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 400l, (float) 1000.0, this); //You can also use LocationManager.GPS_PROVIDER and LocationManager.PASSIVE_PROVIDER
}
catch (SecurityException e) {
        Log.d(TAG, "Can't get location -- permission denied");
}

当然,您需要调整准确度和更新间隔以满足您的需求并节省电池电量。当您的手机进入Doze模式时,您肯定会在回调中找到辍学者。但是,您应该能够在问题中描述的Application类中使用上述内容,而不会在Google Play服务中添加令人烦恼的不透明行为。

© www.soinside.com 2019 - 2024. All rights reserved.