在FusedLocationProviderApi中设置模拟位置

7

我试图从FusedLocationProviderApi获取模拟位置更新,但似乎无法使其工作。以下是我的安卓测试设置方法:

locationProvider = new LocationProvider(InstrumentationRegistry.getTargetContext().getApplicationContext(), settings);

// Connect first, so that we don't receive 'true' location
locationProvider.googleApiClient.blockingConnect();
// Set mock mode, to receive only mock locations
LocationServices.FusedLocationApi.setMockMode(locationProvider.googleApiClient, true);

InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
    @Override
    public void run() {
        // Start receiving locations; this call will connect api client, and if it's already connected (or after it connects) it will register for location updates
        locationProvider.start();
    }
});
// wait until we can request location updates
while (!locationProvider.isReceivingLocationUpdates) {
    Thread.sleep(10);
}

在此之后,我期望任何对LocationServices.fusedLocationApi.setMockLocation(apiClient, location)的调用都会设置模拟位置,并且我的监听器将接收到这些位置。不幸的是,情况并非如此,监听器保持沉默。
我设想的(或者我认为是)设置模拟位置的绝佳方法如下:
private void setMockLocation(final Location location) throws Exception {
    assertTrue(locationProvider.googleApiClient.isConnected());
    assertTrue(locationProvider.isReceivingLocationUpdates);

    final CountDownLatch countDownLatch = new CountDownLatch(1);
    LocationServices.FusedLocationApi.setMockMode(locationProvider.googleApiClient, true)
            .setResultCallback(new ResultCallback<Status>() {
                @Override
                public void onResult(Status status) {
                    assertTrue(status.isSuccess());
                    LocationServices.FusedLocationApi.setMockLocation(locationProvider.googleApiClient, location)
                            .setResultCallback(new ResultCallback<Status>() {
                                @Override
                                public void onResult(Status status) {
                                    assertTrue(status.isSuccess());
                                    countDownLatch.countDown();
                                }
                            });
                }
            });
    assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS));
}

方法成功返回,但是监听器没有接收到位置信息。我真的很困惑。最糟糕的是,有时测试会通过,但极其随机(即使相同的代码执行多次,在随后的调用中也会通过和失败)。为了完整起见,我的调试清单具有以下权限:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />

我已经在设置中允许模拟位置。


这个教程提供了如何在Android中使用模拟位置数据进行测试的很好的信息。此外,locationProvider已经被弃用,你应该使用GoogleApiClient代替它。你可以查看这个github页面获取示例GoogleApiClient的实现。 - ztan
我可能没有表达清楚 - locationProvider 是我的自定义类。我使用 GoogleApiClientFusedLocationProviderApi 来获取位置。 - wasyl
@wasyl 我没有尝试过这个。但是你是否检查了开发者选项下的允许模拟位置选项是否已启用? - manjusg
@Anuj 我也遇到了同样的问题,看起来我已经按照需要的一切做了(在我的Android中设置模拟器,添加了清单中的权限,设置了模拟位置),但是当位置改变时就从未被调用过。我已经试了几个小时了,想找出问题所在...你有没有成功理解是什么问题呢? - idish
很抱歉,不行。请在我发布的问题中直接联系Google团队的GitHub,也许他们会进一步调查此问题。 - wasyl
显示剩余3条评论
1个回答

2

这是更新后的Kotlin版本。请注意,在开发选项中,您需要将该应用程序选择为模拟位置提供程序,并在调试清单文件中设置权限。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
    tools:ignore="ProtectedPermissions" />
</manifest>

在onCreate中,一个活动将具有带有初始化程序的val。
  private lateinit var fusedLocationClient: FusedLocationProviderClient

在onCreate()中

  fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)


  fusedLocationClient.setMockMode(BuildConfig.DEBUG)

  fusedLocationClient.lastLocation
        .addOnSuccessListener { location : android.location.Location? ->
            // Got last known location. In some rare situations this can be null.
            Toast.makeText(this, location.toString(), Toast.LENGTH_SHORT).show()

        }
        .addOnFailureListener {  Toast.makeText(this, "failed", Toast.LENGTH_SHORT).show() }

最后,一种模拟位置的方法

 private fun setMockLocation(location: android.location.Location) {
    fusedLocationClient.setMockLocation(location)
        .addOnSuccessListener { Log.d(TAG, "location mocked") }
        .addOnFailureListener { Log.d(TAG, "mock failed") }
}

它在位置上发送了0.0。https://stackoverflow.com/questions/72633629/unit-test-for-fusedlocationclient-lastlocation-in-android - Bhoomika Brahmbhatt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接