我正在尝试通过创建Location实例然后使用LocationManager.SetTestProviderLocation(string providerName,Locatin location)方法来模拟我的位置。
例如:
Location location = new Location(providerName)
{
Latitude = 51.20958,
Longitude = 2.92372,
Accuracy = 100.0f,
Time = DateTime.Now.Ticks,
Altitude = 1.0,
Speed = 0.0f,
Bearing = 0.0f,
Provider = providerName,
};
locationManager.SetTestProviderLocation(providerName, location);
这总是会导致异常:
“位置对象不完整,缺少时间戳或准确性? 位置[gps 51.209580,2.923720 acc = 1 et =?!? alt = 1.0 vel = 0.0 承担= 0.0]“
我找到了有关该主题here的一些信息
作者提到LocationManger检查isComplete(方法)
以确定位置是否完整。
我希望该类的单声道版本具有IsComplete属性
和MakeComplete方法,但它们不存在(或者至少我找不到它们)
public void makeComplete()
{
if (mProvider == null) mProvider = "?";
if (!mHasAccuracy) {
mHasAccuracy = true;
mAccuracy = 100.0f;
}
if (mTime == 0) mTime = System.currentTimeMillis();
if (mElapsedRealtimeNanos == 0) mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();
}
我猜是“et =?!?”异常中的值是指 mElapsedRealtimeNanos 字段,因为我无法知道访问该字段,所以我无法嘲笑工作。
我错过了什么,这是Android或者Mono的缺失功能 是否有另一种方法可以使它发挥作用。
注意:我知道有很多方法可以使用DDMS设置虚假位置, 但我正在寻找一种自动化位置模拟的方法
更新
发布此问题一段时间后,我意识到我没有针对API级别16 因此,Mono for Android没有公开 ElapsedRealtimeNanos 属性。
切换到API级别16后,该属性变为可用。但是,它没有 提供 MakeComplete 方法。 (也许这是一个错误/缺失的功能)。
所以我做了一个快速的解决方案来验证行为:
Location location = new Location(providerName)
{
Longitude = locations[position, 0],
Latitude = locations[position, 1],
Accuracy = 100.0f,
Time = DateTime.Now.Ticks,
Altitude = 1.0,
Speed = 0.0f,
Bearing = 0.0f,
Provider = providerName,
ElapsedRealtimeNanos = (long)(TimeSpan.FromTicks(DateTime.Now.Ticks)
.TotalMilliseconds * 1000000)
};
虽然这解决了Jelly Bean设备(4.1或更高版本)代码的问题 将破坏旧设备。这就是@Cheesebaron提出的解决方案发挥作用的地方。
答案 0 :(得分:3)
您可能需要通过JNI访问makeComplete
,代码如下:
public class MyLocation : Location
{
protected MyLocation(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public MyLocation(Location l) : base(l)
{
}
public MyLocation(string provider) : base(provider)
{
}
public void MakeComplete()
{
if ((int)Build.VERSION.SdkInt >= 16)
{
var locationClass = JNIEnv.FindClass("android/location/Location");
var makeComplete = JNIEnv.GetMethodID(locationClass, "makeComplete", "()V");
JNIEnv.CallVoidMethod(Handle, makeComplete);
}
}
}
然后只需使用MyLocation
的实例,即调用MakeComplete
。但是它只能在API 16上运行。