LoginSignup
YA32
@YA32

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

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>
0

No Answers yet.

Your answer might help someone💌