web-dev-qa-db-ja.com

Xamarin Essentialsの地理位置情報が機能せず、GetLocationAsyncが失敗する

したがって、ユーザーの場所を取得し、それを逆ジオコーディングして、住所と番地を取得します。

そのため、プレリリース版のXamarin.Essentialsパッケージをインストールしました。ジオロケーションとジオコーディングAPIを使用したかったので、コードをいくつか記述しましたが、GetCurrentLocationの試行でコードがif (location != null)に到達しませんでした。

Xamarin.EssentialsがXam.Plugin.Geolocatorの作者であるJames Montemagnoの発言に基づいてプレリリースにあることは重要ではないと思います。

私は引き続きプラグインの作業とメンテナンスを行いますが、Xamarin.Essentialsをチェックアウトして、自分のアプリと同じようにアプリに最適かどうかを確認することをお勧めします!

ソース: https://github.com/jamesmontemagno/GeolocatorPlugin

私が何をした?

私が抱えている問題についてStackOverflowの質問を検索しましたが、私の知る限り、私に役立つ質問を見つけることができません。

私が調べた質問:

タイムアウトを追加するとうまくいくかどうかも試しました:var request = new GeolocationRequest(GeolocationAccuracy.Medium, timeout: TimeSpan.MaxValue );

しかし、同じ問題が同じ場所で同じくらい早く発生しました。 ifステートメントには到達しませんでした。

私のコード:

FillInLocationInForm();は、私のPageコンストラクターで設定されています。

_public Location location;_および_public Placemark placemark;_は、Pageクラスで設定されます。

これらは、Pageクラスの関連する関数です。

_public async void FillInLocationInForm()
    {
        if (await GetCurrentLocation())
        {
            if (await ReverseGeocodeLocation())
            {
                await this.DisplayAlert("Location", placemark.AdminArea + " " + placemark.FeatureName + " " + placemark.Locality + " " + placemark.SubLocality + " " + placemark.SubAdminArea + " " + placemark.SubThoroughfare + " " + placemark.Thoroughfare, "Okay", "Okay");
            }
        }           
    }

public async Task<bool> GetCurrentLocation ()
    {
        try
        {
            var request = new GeolocationRequest(GeolocationAccuracy.Medium);
            var location = await Geolocation.GetLocationAsync(request);

            if (location != null)
            {                    
                this.location = location;
                return await Task.FromResult(true);
            }
        }
        catch (FeatureNotSupportedException fnsEx)
        {
            // Handle not supported on device exception               
        }
        catch (PermissionException pEx)
        {
            // Handle permission exception                
        }
        catch (Exception ex)
        {
            // Unable to get location              
        }
        return await Task.FromResult(false);
    }

public async Task<bool> ReverseGeocodeLocation()
    {
        try
        {
            var lat = location.Latitude;
            var lon = location.Longitude;

            var placemarks = await Geocoding.GetPlacemarksAsync(lat, lon);

            var placemark = placemarks?.FirstOrDefault();
            if (placemark != null)
            {
                //var geocodeAddress =
                //    $"AdminArea:       {placemark.AdminArea}\n" +
                //    $"CountryCode:     {placemark.CountryCode}\n" +
                //    $"CountryName:     {placemark.CountryName}\n" +
                //    $"FeatureName:     {placemark.FeatureName}\n" +
                //    $"Locality:        {placemark.Locality}\n" +
                //    $"PostalCode:      {placemark.PostalCode}\n" +
                //    $"SubAdminArea:    {placemark.SubAdminArea}\n" +
                //    $"SubLocality:     {placemark.SubLocality}\n" +
                //    $"SubThoroughfare: {placemark.SubThoroughfare}\n" +
                //    $"Thoroughfare:    {placemark.Thoroughfare}\n";

                //Console.WriteLine(geocodeAddress);
                this.placemark = placemark;
                return await Task.FromResult(true);
            }
        }
        catch (FeatureNotSupportedException fnsEx)
        {
            // Feature not supported on device
        }
        catch (Exception ex)
        {
            // Handle exception that may have occurred in geocoding
        }
        return await Task.FromResult(false);
    }
_

また、これらの権限をアプリのAndroidManifestに追加し、実行時にリクエストしました。アプリの設定で場所とストレージの両方が選択されているのを見ました。

_<uses-permission Android:name="Android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" />
<uses-feature Android:name="Android.hardware.location" Android:required="false" />
<uses-feature Android:name="Android.hardware.location.gps" Android:required="false" />
<uses-feature Android:name="Android.hardware.location.network" Android:required="false" />
_

私がフォローしているドキュメント:

どんな助けでもありがたいです。

編集:

キャンセルトークンをGetLocationAsyncに追加する必要がありますが、その方法はまだわかりません。 GeolocationRequestの横に表示されません。

enter image description here

編集2:

CancellationTokenを追加しましたが、ifステートメントにまだ到達していません。多分私はまだそれを使っていません。

_using System.Threading; // add above

CancellationTokenSource source = new CancellationTokenSource();
CancellationToken cancelToken = source.Token;
var location = await Geolocation.GetLocationAsync(request, cancelToken);
_

編集3:

下の画像のブレークポイントは発生しません。つまり、ifステートメントに到達することはありません。どういうわけか、コードは試行錯誤から抜け出しますが、catchステートメントの1つには行きません。現在、catchステートメントでConsole.WriteLine()を使用しています。デバイスログに何も表示されません。デバイスログで確認したキャッチからConsole.WriteLine()をテストしました。 enter image description here

6
Sjoerd Pottuit

どうやら、私は十分に長く待たなかった。ジェイソンが言ったように。

タイムアウトを追加する最初の試みは次のとおりです。

new GeolocationRequest(GeolocationAccuracy.Medium, timeout: TimeSpan.MaxValue);

どういうわけか、上の行は機能しませんでした。

とにかく、10秒のタイムスパンを追加すると、場所がわかります。

var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));       
1
SPottuit