AndroidでXamarin.Essentialsの「Location.Speed」プロパティがほとんど取得できません
実現したいこと
現在、Xamarin.EssentailsのLocation.Speedを用いて、時速が20km/hを超える場合には、アプリをロックするというテストアプリ「speedDetector」を作成しています。
しかし、Location.SpeedがAndroidでほとんど取得できないようです。iOSでは問題なく取得できます。
ターゲットフレームワークはAndroid12で、Xamarin.Essentialsのバージョンは1.7.3です。
アプリ自体はXamarinでの実装である必要がありますが、スピードを取得するロジックについてはXamarin.EssentailsのLocationにはこだわっておりません。
自作の速度計算ロジックを作らずに、Android端末でうまくSpeed値を取得できる良い方法はありますでしょうか?
以下はソースコードの説明となります。
1秒ごとにGeolocationRequestを受けとり、位置情報を「location」変数に格納しています。
「location」がnullでない場合には「JudgmentMessage」クラスのmessageとして「location」の情報と判定結果(20km/hを超えているか)を格納します。
それを「MainPageViewModel.cs」を経由して、フロント側の「MainPage.xaml」に渡します。
しかしAndroidの場合、上記の「Console.WriteLine(location.Speed);」の時点でほとんどの場合でnull値を返すようです。
稀に正常に値が取得できることもあるため、位置情報の権限の問題ではないようです。
また、「Speed」が取得できない場合でも、「Latitude」や「Longitude」は正常に取得できています。
ソースコード(抜粋)
judgmentTask.cs
public async Task Run(CancellationToken token)
{
await Task.Run(async () => {
while (true)
{
token.ThrowIfCancellationRequested();
await Task.Delay(TimeSpan.FromSeconds(1));
Location location = null;
try
{
var request = new GeolocationRequest(GeolocationAccuracy.Best, TimeSpan.FromSeconds(1));
location = await Geolocation.GetLocationAsync(request);
}
catch
{
continue;
}
if (location == null)
{
continue;
}
Console.WriteLine(location.Speed);
MainThread.BeginInvokeOnMainThread(() =>
{
var message = new JudgmentMessage
{
Location = location,
Locked = !this.Judge(),
};
this.SendData(message);
MessagingCenter.Send(message, nameof(JudgmentMessage));
});
}
}, token);
}
MainPageViewModel.cs
namespace SpeedDetector.ViewModels
{
internal class MainPageViewModel : INotifyPropertyChanged
{
private Location location;
public Location Location
{
get
{
return this.location ?? new Location
{
Latitude = 0,
Longitude = 0,
Accuracy = 0,
Speed = 0,
};
}
set
{
this.location = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Location)));
}
}
}
}
MainPage.xaml
<Label Grid.Row="3" Grid.Column="0"
VerticalOptions="Center"
Text="Speed" />
<Frame Grid.Row="3" Grid.Column="1"
VerticalOptions="Center"
Padding="4"
BorderColor="LightGray"
HasShadow="False">
<Label TextColor="Black" Text="{Binding Path=Location.Speed, StringFormat='{0:N} km/h', Converter={StaticResource speedConverter}}" />
</Frame>