【问题标题】:setElapsedRealtimeNanos() call in android mock location provider appandroid 模拟位置提供程序应用程序中的 setElapsedRealtimeNanos() 调用
【发布时间】:2014-10-19 10:02:50
【问题描述】:

我正在开发一个 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 文件,其中有两个函数调用elapsedRealtimeNanos()setElapsedRealtimeNanos()在 API 级别 17 中添加。我需要在 API 级别 8 的设备中运行这个模拟位置提供程序应用程序。所以,我改变了这一行:

elapsedTimeNanos = SystemClock.elapsedRealtimeNanos();

elapsedTimeNanos = SystemClock.elapsedRealtime()*1000000;

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

mockLocation.setElapsedRealtimeNanos(elapsedTimeNanos);

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

【问题讨论】:

  • 您不会更改该行,因为您已经更改了 elapsedTimeNanos 的值。

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


【解决方案1】:

我今天晚上更新了the sample project you referenced 以使用 gradle 构建,并注意到使用 API 级别 17 中引入的setElapsedRealtimeNanos 存在相同的问题。该应用程序在我的 4.4 设备上运行良好,但会因 NoSuchMethodError 上而崩溃我的 4.1 设备。

我深入研究了位置类的源代码,以确切了解 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 级别 >= 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    • 2012-11-13
    • 1970-01-01
    • 2011-01-26
    • 2013-06-07
    相关资源
    最近更新 更多