web-dev-qa-db-ja.com

Xamarin.Forms.Mapsを使用した6.0以上では、Androidの場所の許可

Xamarin.Forms.Mapsを使用してXamarin.Formsアプリケーションを実装しようとしていますが、常に例外に陥ります。

Java.Lang.SecurityException:私の場所には許可ACCESS_FINE_LOCATIONまたはACCESS_COARSE_LOCATIONが必要です

私はすでにこのチュートリアルの手順に従ってみました https://blog.xamarin.com/requesting-runtime-permissions-in-Android-Marshmallow/ ですが、結果が得られませんでした。

誰かが私を助けるためにもっと一貫性のあるものを持っていますか?

私が意図しているのは、Uberに非常に近いアプリケーションを使用することであり、場所のアクセス許可を取得できない場合は進行できません。

私のMainPageは私のPCLで次のようになります。

public partial class MainPage: ContentPage
    {
        public MainPage ()
        {
            InitializeComponent ();
            var map = new Map ()
            {
                MapType = MapType.Street,
                IsShowingUser = true
            };

            var stack = new StackLayout {Spacing = 0};
            stack.Children.Add (map);

            Content = stack;
        }
    }

Xamarin.Androidの私のMainActivityクラスは次のようになります。

[Activity (Label = "ExampleGeolocation", Icon = "@ drawable / icon",
              Theme = "@ style / MainTheme", MainLauncher = true,
              ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]

    public class MainActivity: global :: Xamarin.Forms.Platform.Android.FormsAppCompatActivity, ActivityCompat.IOnRequestPermissionsResultCallback
    {
        View layout;
        const int RequestLocationId = 0;
        readonly string [] PermissionsLocation = {Manifest.Permission.AccessCoarseLocation, Manifest.Permission.AccessFineLocation};

        protected override void OnCreate (Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate (bundle);

            global :: Xamarin.Forms.Forms.Init (this, bundle);
            global :: Xamarin.FormsMaps.Init (this, bundle);

            Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity = this;

            SetStatusBarColor (Android.Graphics.Color.Black);
            LoadApplication (new App ());
        }

        public override async void OnRequestPermissionsResult (int requestCode, string [] permissions, [GeneratedEnum] Permission [] grantResults)
        {
            switch (requestCode)
            {
                case RequestLocationId:
                    {
                        if (grantResults [0] == Permission.Granted)
                        {
                            var snack = Snackbar.Make (layout, "Location Permission is Available.", Snackbar.LengthShort);
                            snack.Show ();

                            await GetLocationAsync ();
                        }
                        else
                        {
                            var snack = Snackbar.Make (layout, "Location Permission Denied", Snackbar.LengthShort);
                            snack.Show ();
                        }
                    }

                    break;
            }
        }

        async Task TryGetLocationAsync ()
        {
            if ((int) Build.VERSION.SdkInt <23)
            {
                await GetLocationAsync ();
                return;
            }

            await GetLocationPermissionAsync ();
        }

        async Task GetLocationPermissionAsync ()
        {
            const string permission = Manifest.Permission.AccessFineLocation;

            if (CheckSelfPermission (permission) == Permission.Granted)
            {
                await GetLocationAsync ();
                return;
            }

            if (ShouldShowRequestPermissionRationale (permission))
            {
                Snackbar.Make (layout, "You must allow the application to access your location options.", Snackbar.LengthIndefinite)
                        .SetAction ("OK", v => RequestPermissions (PermissionsLocation, RequestLocationId))
                        .Show();

                return;
            }

            RequestPermissions (PermissionsLocation, RequestLocationId);
        }

        async Task GetLocationAsync ()
        {
            try
            {
                var locator = CrossGeolocator.Current;
            }
            catch (Exception e)
            {
                e.ToString ();
                throw new NotImplementedException ();
            }
        }
    };
8

Xamarin.Forms.Mapsを使用した6.0以上では、Androidの場所の許可

あなたは許可について多くのコードを書きましたが、許可を要求する場所が見つかりません。許可を使用する前に許可を要求する必要があります。

IsShowingUserプロパティをtrueに設定する場合、最初に許可をリクエストする必要があります。これは3つの解決策です。

解決策1:

コードで PermissionsPlugin を使用していることに気付きました。PCLでこの許可を要求する必要がある場合は、 PermissionsPlugin公式サンプル を参照してください。

このコードをMainActivityに追加します。

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
    PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

必要なときに許可をリクエストします。

try
{
    var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
    if (status != PermissionStatus.Granted)
    {
        if(await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Location))
        {
            await DisplayAlert("Need location", "Gunna need that location", "OK");
        }

        var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
        status = results[Permission.Location];
     }

     if (status == PermissionStatus.Granted)
     {
         //Permission granted, do what you want do.
     }
     else if(status != PermissionStatus.Unknown)
     {
         await DisplayAlert("Location Denied", "Can not continue, try again.", "OK");
     }
}
catch (Exception ex)
{
    //...
}

解決策2:

アプリケーションを開くとき、最初にMainActivityOnStartメソッドで許可をリクエストします。

protected override void OnStart()
{
    base.OnStart();

    if (ContextCompat.CheckSelfPermission(this, permission) != Permission.Granted)
    {
        ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.AccessCoarseLocation, Manifest.Permission.AccessFineLocation }, 0);
    }
    else
    {
        System.Diagnostics.Debug.WriteLine("Permission Granted!!!");
    }
}

解決策3:

DependencyService を使用して、必要なときに許可を要求します。これは sample に関連する tutorial を読んだものです。この例では、次の行を実行するときに許可を要求します。

buttonGetLocation.Click += async (sender, e) => await TryGetLocationAsync();
17
York Shen

これを内部に追加Android MainActiviy OnCreate()

Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity = this;

これをAndroid mainactivity:

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
    Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

このコードは機能し、ユーザーに場所の許可を求めます。

                var locator = CrossGeolocator.Current;
                locator.DesiredAccuracy = 1000;
                var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);

参照する:

https://jamesmontemagno.github.io/GeolocatorPlugin/

4
pollaris

必要なすべての権限を設定したことを確認してください。 AndroidでXamarin.Forms.Mapsを使用する場合は、プロジェクトのAndroidManifest.xmlファイルに次の権限が設定されていることを確認してください。

<uses-permission Android:name="Android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" />
<uses-permission Android:name="Android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE" />
<uses-permission Android:name="Android.permission.ACCESS_WIFI_STATE" />
<uses-permission Android:name="Android.permission.INTERNET" />

Android Project]を右マウスでクリックし、Propertiesを選択してアクセス許可を設定することもできます。タブ[Android Manifest]に移動し、必要なアクセス許可をすべてマークします。

また、applicationタグに次の2つのステートメントを追加したことを確認してください。

<meta-data Android:name="com.google.Android.geo.API_KEY" Android:value="ADD_YOUR_KEY_HERE" />
<meta-data Android:name="com.google.Android.gms.version" Android:value="@integer/google_play_services_version" />
1

このビデオは、xamarinフォームでの実行時の許可に役立ちます https://www.youtube.com/watch?v=IWdpzpFChUQ

1
Vidhya