2013-10-14 57 views
3

我試圖通過創建一個Location實例,然後使用LocationManager.SetTestProviderLocation(string providerName,Locatin location)方法來模擬我的位置。使用LocationManager.SetProviderLocation嘲弄一個位置,我如何使位置完成

例如:

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); 

這總是導致一個例外:

「不完整的位置對象,缺少時間戳或精度 位置[全球定位系統51.209580 ,2.923720 acc = 1 et =?!alt = 1.0 vel = 0.0 bear = 0.0]「

我發現了一些關於here的信息。
作者提到LocationManger檢查isComplete(method)
以確定位置是否完整。

我的預期類的單聲道版本有一個IsComplete財產
和MakeComplete方法,但它們不存在(或至少我無法找到他們)

以在Android SDK source code仔細看看:

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字段
並且由於我不知道如何訪問該字段,所以我不能嘲笑工作。

我是否錯過了一些東西,這是一款缺失的Mono for Android功能或
有沒有可能使其工作的另一種方式。

注:我知道有使用DDMS, 設置假的位置的方式,但我正在尋找一種方法來自動化嘲諷

UPDATE

一段時間地點發布此問題後,我意識到我沒有針對API級別16.
因此,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) 
}; 

雖然這解決了果凍豆設備問題(4.1或更高版本)的代碼
將打破舊設備。這是@Cheesebaron提出的解決方案的作用。

回答

2

你可能會需要通過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上運行。

+0

嗨thnx的答案,同時我想清楚發生了什麼,將它張貼在這裏 – TimothyP

+0

其實不,你的解決方案是正確的。我會更新我的答案,以顯示我發現的內容,但將您的問題標記爲解決方案,顯然是您的選擇! – TimothyP

+0

'makeComplete'僅用於根據文檔向後兼容,並且僅存在於API 16及更高版本中。 – Cheesebaron

相關問題