You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 11+设备Espresso测试中模拟位置提供者启用异常排查

新版Android(11+)正确启用模拟位置的解决方案

在Android 11及以上版本中,系统对位置测试提供者的行为做了更严格的校验:如果测试提供者没有输出有效位置数据,系统会判定其不可用,进而触发onProviderDisabled回调。这就是你遇到的启用测试提供者后不久收到disabled回调的原因。

以下是修正后的实现步骤:

1. 确保测试应用具备模拟位置权限

在测试应用的AndroidManifest.xml中添加权限声明:

<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
    android:maxSdkVersion="30" />

对于Android 11+,该权限属于签名级权限,instrumented测试应用与目标应用签名一致时会自动授予。也可以通过adb命令预先授权:

adb shell appops set com.your.test.package android:mock_location allow

2. 修正测试提供者的初始化逻辑

初始化测试提供者时,除了设置启用状态,还要主动标记提供者为可用状态,避免系统误判:

locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
// 先移除已存在的同名测试提供者,避免重复添加报错
if (locationManager.getProvider(LOCATION_PROVIDER_NAME) != null) {
    locationManager.removeTestProvider(LOCATION_PROVIDER_NAME);
}
// 添加测试提供者
locationManager.addTestProvider(LOCATION_PROVIDER_NAME, false,
                                false, false, false,
                                true, true, true,
                                LocationManager.POWER_USAGE_HIGH, 
                                ProviderProperties.ACCURACY_FINE);
// 关键:设置提供者状态为可用
locationManager.setTestProviderStatus(LOCATION_PROVIDER_NAME,
                                      LocationProvider.AVAILABLE,
                                      null, System.currentTimeMillis());
// 初始设置为禁用
locationManager.setTestProviderEnabled(LOCATION_PROVIDER_NAME, false);

3. 启用测试提供者后发送有效位置数据

启用测试提供者后,必须立即发送至少一条模拟位置数据,让系统确认该提供者能正常输出位置:

locationManager.setTestProviderEnabled(LOCATION_PROVIDER_NAME, true);

// 构造并发送模拟位置
Location mockLocation = new Location(LOCATION_PROVIDER_NAME);
mockLocation.setLatitude(39.9042); // 示例纬度(北京)
mockLocation.setLongitude(116.4074); // 示例经度
mockLocation.setAccuracy(5.0f);
mockLocation.setTime(System.currentTimeMillis());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    mockLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
}
locationManager.setTestProviderLocation(LOCATION_PROVIDER_NAME, mockLocation);

// 避免使用SystemClock.sleep,推荐用Espresso的IdlingResource或await方法等待回调
// 例如:Espresso.onView(isRoot()).perform(waitFor(200));

额外注意事项

  • 不要依赖SystemClock.sleep,改用Espresso的等待机制更可靠,避免测试不稳定。
  • 测试完成后记得移除测试提供者,避免影响后续测试:
@After
public void tearDown() {
    if (locationManager != null && locationManager.getProvider(LOCATION_PROVIDER_NAME) != null) {
        locationManager.removeTestProvider(LOCATION_PROVIDER_NAME);
    }
}

内容的提问来源于stack exchange,提问作者Laurent D.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 05:48:24