在android模拟位置提供程序应用程序中调用setElapsedRealtimeNanos()

时间:2014-10-19 10:02:50

标签: android google-maps-android-api-2

我正在开发一个Android应用程序,它将接收当前位置并使用标记将其显示在地图上,然后将定期更新。我按照以下教程:

Google Maps Android API v2

Retrieving the Current Location

Receiving Location Updates

我想用模拟位置测试我的应用程序,所以我遵循了本教程:

Testing Using Mock Locations

然而,由于Google尽管我的最佳尝试仍然令人困惑,但第一种方法失败了。我遇到了这个问题:

Android LocationClient mock location not set

然后,我决定使用模拟位置提供程序应用程序并发现即使下载的应用程序的清单具有android:minSdkVersion="7",它也有一个SendMockLocationService.java文件,其中有两个函数调用{{1} }和elapsedRealtimeNanos()在API级别17中添加。我需要在API级别为8的设备中运行此模拟位置提供程序应用程序。因此,我更改了该行:

setElapsedRealtimeNanos()

elapsedTimeNanos = SystemClock.elapsedRealtimeNanos();

我不清楚如何改变这一行:

elapsedTimeNanos = SystemClock.elapsedRealtime()*1000000;

如何更改上述行,以便模拟位置提供程序应用程序与API级别8兼容?

1 个答案:

答案 0 :(得分:2)

我今晚更新了the sample project you referenced以使用gradle构建,并注意到在API级别17中引入的使用setElapsedRealtimeNanos的相同问题。该应用程序在我的4.4设备上工作正常,但会崩溃我的4.1设备上有NoSuchMethodError。

我开始深入研究位置类的源代码,以确切了解API 17的变化。这里有相应的差异:

https://android.googlesource.com/platform/frameworks/base/+/2eeeec248a38ff33999c83f4b8d5bab7d50e79d2%5E%21/

如果您搜索新引入的字段mElapsedRealtimeNano的用法,您将看到它的值仅在一个位置查询(+保留以指示新插入的行) :

+    public boolean isComplete() {
+        if (mProvider == null) return false;
+        if (!mHasAccuracy) return false;
+        if (mTime == 0) return false;
+        if (mElapsedRealtimeNano == 0) return false;
+        return true;
+    }

新推出的地理位置概念已经完成'也只在一个地方使用:

     public void setTestProviderLocation(String provider, Location loc) {
+        if (!loc.isComplete()) {
+            if (mContext.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN) {
+                // for backwards compatibility, allow mock locations that are incomplete
+                Log.w(TAG, "Incomplete Location object", new Throwable());
+                loc.makeComplete();
+            } else {
+                throw new IllegalArgumentException(
+                        "Location object not complete. Missing timestamps or accuracy?");
+            }
+        }
+
         // original setTestProviderLocation code is then executed here
     }

由于在API 17之前的Location类中缺少此验证,因此如果在版本检查中将两个调用都包装到SystemClock.elapsedRealtimeNanos(),那么应用程序在所有API级别上都可以正常工作&gt; = 7。

elapsedTimeNanos = SystemClock.elapsedRealtimeNanos();

应替换为

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    elapsedTimeNanos = SystemClock.elapsedRealtimeNanos();
}

mockLocation.setElapsedRealtimeNanos(elapsedTimeNanos);

应替换为

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    mockLocation.setElapsedRealtimeNanos(elapsedTimeNanos);
}

在SendMockLocationService类中。 Android Studio会抱怨elapsedTimeNanos可能尚未初始化 - 您可以使用值0安全地初始化它以解决此问题。

通过这些更改,应用程序在我的4.1设备上正常运行。如果您在旧版Android上遇到任何问题,请与我们联系。

修改:repository for my updated version of the Google sample app