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);
これにより、常に例外が発生します。
「不完全な位置オブジェクト、タイムスタンプまたは精度がありませんか? Location[gps 51.209580,2.923720 acc=1 et=?!? alt=1.0 vel=0.0 bear=0.0]」
この件に関する情報をここで見つけました。
著者は、LocationManger が isComplete (メソッド)
をチェックして、Location が完全かどうかを判断すると述べています。
クラスの mono バージョンには IsComplete プロパティ
と MakeComplete メソッドがあると思っていましたが、存在しませんでした (または、少なくとも見つかりませんでした)。
Android SDK ソース コードを詳しく見てみましょう。
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を使用して偽の場所を設定する方法があることは承知していますが、場所のモックを自動化する方法を探しています
アップデート
この質問を投稿してからしばらくして、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 によって提案されたソリューションが登場する場所です。