如何使用xamarin表单提示用户进行地理定位

本文关键字:定位 用户 何使用 xamarin 表单 提示 | 更新日期: 2023-09-27 18:04:29

我正在制作一个xamarin表单应用程序,需要请求地理位置许可,如果授予它需要从设备获得地理位置数据,然后将地理位置坐标放入预测。我使用的地理定位器插件由James Montemagno以及permissionplugin由James Montemagno当我打开雷达页面屏幕只是保持白色它从来没有问我的许可这是我的xamarin表单代码:

using AppName.Data;
using Xamarin.Forms;
using Plugin.Geolocator;
using System.Diagnostics;
using System.Threading.Tasks;
using Plugin.Permissions;
using Plugin.Permissions.Abstractions;
using System;
namespace AppName.Radar
{
    public partial class RadarHome : ContentPage
    {
        public RadarHome()
        {
            InitializeComponent();
        }
         async void locator()
        {
            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)
                {
                    var browser = new WebView();
                    var results = await CrossGeolocator.Current.GetPositionAsync(10000);
                    browser.Source  = "https://forecast.io/?mobile=1#/f/" + "Lat: " + results.Latitude + " Long: " + results.Longitude;
                }
                else if (status != PermissionStatus.Unknown)
                {
                    await DisplayAlert("Location Denied", "Can not continue, try again.", "OK");
                }
            }
            catch (Exception ex)
            {
                await DisplayAlert("Location Denied", "Can not continue, try again.", "OK");
            }
        }
    }
}
这是我的Android MainActivity代码:
using Android.App;
using Android.Content.PM;
using Android.OS;
using Xamarin.Forms.Platform.Android;
using Android;
using Plugin.Permissions;
namespace AppName.Droid
{
    [Activity(MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, Theme = "@style/CustomTheme")]
    public class MainActivity : FormsApplicationActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
        {
            PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

我漏掉什么了吗?两个插件都安装在form项目中android项目和iOS项目

如何使用xamarin表单提示用户进行地理定位

需要添加所需的权限。

Android中,为了允许我们的应用程序访问位置服务,我们需要启用两个Android权限:ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION

iOS,取决于你是否总是使用地理定位(如地图应用程序),或者只是在用户的工作流程中的某些点,你要么需要在你的Info.plist中添加关键NSLocationWhenInUsageDescriptionNSLocationAlwaysUsageDescription,以及一个新的字符串条目,用于描述你将与用户的位置做什么。当在运行时提示用户权限时,将显示这里列出的描述。

在Windows环境下,必须启用ID_CAP_LOCATION权限

在这里阅读完整的博客- iOS, Android和Windows的地理定位变得容易

Xamarin的界面

    public interface MyLocationTracker
   {
            void ObtainMyLocation();
         event EventHandler<MyLocationEventArgs> locationObtained;
      }
public interface MyLocationEventArgs
  {
    double lat { get; set; }
    double lng { get; set; }
   }

2。Android依赖代码

[assembly: Xamarin.Forms.Dependency(typeof(GetMyLocationStatus))]
namespace BarberApp.Droid
{
public class GetMyLocationStatus: Java.Lang.Object,MyLocationTracker,ILocationListener
{

    private LocationManager _locationManager;
    private string _locationProvider;
    private Location _currentLocation { get; set; }
    public GetMyLocationStatus() {
    this.InitializeLocationManager();
    }
    public event EventHandler<MyLocationEventArgs> locationObtained;
    event EventHandler<MyLocationEventArgs> MyLocationTracker.locationObtained
    {
        add
        {
            locationObtained += value;
        }
        remove
        {
            locationObtained -= value;
        }
    }


    void InitializeLocationManager()
    {
        _locationManager = (LocationManager)Forms.Context.GetSystemService(Context.LocationService);
    }

    public void OnLocationChanged(Location location)
    {
        _currentLocation = location;
        if (location != null)
        {
            LocationEventArgs args = new LocationEventArgs();
            args.lat = location.Latitude;
            args.lng = location.Longitude;
            locationObtained(this, args);

        }

    }

    void MyLocationTracker.ObtainMyLocation()
    {
        _locationManager = (LocationManager)Forms.Context.GetSystemService(Context.LocationService);
        if (!_locationManager.IsProviderEnabled(LocationManager.GpsProvider) || !_locationManager.IsProviderEnabled(LocationManager.NetworkProvider))
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(Forms.Context);
            builder.SetTitle("Location service not active");
            builder.SetMessage("Please Enable Location Service and GPS");
            builder.SetPositiveButton("Activate", (object sender, DialogClickEventArgs e) =>
            {

                    Intent intent = new Intent(Android.Provider.Settings.ActionLocationSourceSettings);
                    Forms.Context.StartActivity(intent);


            });
            Dialog alertDailog = builder.Create();
            alertDailog.SetCanceledOnTouchOutside(false);
            alertDailog.Show();
        }
        else {
            _locationManager.RequestLocationUpdates(
                LocationManager.NetworkProvider,
                    0,   //---time in ms---
                    0,   //---distance in metres---
                    this);
        }

    }

    ~GetMyLocationStatus(){
        _locationManager.RemoveUpdates(this);
    }
}

public class LocationEventArgs : EventArgs, MyLocationEventArgs
{
    public double lat { get; set; }
    public double lng { get; set; }
}
}

3。IOS依赖代码

[assembly: Xamarin.Forms.Dependency(typeof(GetILocationStatus))]
namespace BarberApp.iOS
{

public class GetILocationStatus : MyLocationTracker
{

    public GetILocationStatus() { }
    CLLocationManager lm;
    public event EventHandler<MyLocationEventArgs> locationObtained;
     event EventHandler<MyLocationEventArgs> MyLocationTracker.locationObtained
    {
        add
        {
            locationObtained += value;
        }
        remove
        {
            locationObtained -= value;
        }
    }
void MyLocationTracker.ObtainMyLocation()
    {
        lm = new CLLocationManager();
        lm.DesiredAccuracy = CLLocation.AccuracyBest;
        lm.DistanceFilter = CLLocationDistance.FilterNone;
        lm.LocationsUpdated +=
            (object sender, CLLocationsUpdatedEventArgs e) =>
            {
                var locations = e.Locations;
                var strLocation =
                    locations[locations.Length - 1].
                        Coordinate.Latitude.ToString();
                strLocation = strLocation + "," +
                    locations[locations.Length - 1].
                        Coordinate.Longitude.ToString();
                LocationEventArgs args = new LocationEventArgs();
                args.lat = locations[locations.Length - 1].
                    Coordinate.Latitude;
                args.lng = locations[locations.Length - 1].
                    Coordinate.Longitude;
                locationObtained(this, args);
            };
        lm.AuthorizationChanged += (object sender,
            CLAuthorizationChangedEventArgs e) =>
        {
            if (e.Status ==
                CLAuthorizationStatus.AuthorizedWhenInUse)
            {
                lm.StartUpdatingLocation();
            }
        };
        lm.RequestWhenInUseAuthorization();
    }
    ~GetILocationStatus()
    {
        lm.StopUpdatingLocation();
    }

}

public class LocationEventArgs : EventArgs, MyLocationEventArgs
{
    public double lat { get; set; }
    public double lng { get; set; }
}
}

4。Xamarin表单代码

MyLocationTracker msi;

    double BetaLat;
    double BetaLog;
            var locator = CrossGeolocator.Current;
            if (locator.IsGeolocationEnabled == false)
            {
                if (Device.OS == TargetPlatform.Android)
                {

                    msi = DependencyService.Get<MyLocationTracker>();
                    msi.locationObtained += (object Esender, MyLocationEventArgs ew) => {
                        Console.WriteLine(ew.lat);
                    };
                    msi.ObtainMyLocation();

                }
                else if (Device.OS == TargetPlatform.iOS)
                {
                    msi = DependencyService.Get<MyLocationTracker>();
                    msi.locationObtained += (object Jsender, MyLocationEventArgs je) =>
                    {
                        Console.WriteLine(je.lat);
                    };
                    msi.ObtainMyLocation();
                }
            }
                locator.DesiredAccuracy = 50;
                var position =  locator.GetPositionAsync(timeoutMilliseconds: 100000);

                BetaLat = position.Latitude;
                BetaLog = position.Longitude;
string str = string.Format("https://forecast.io/?mobile=1#/f/Lat:{0} , Long: {1}", BetaLat, BetaLog);

  var client = new System.Net.Http.HttpClient();
 client.BaseAddress = new Uri(str);

我有同样的问题,这个插件不请求权限在运行时,即使它显示在Droid属性页。修复方法是手动将这一行复制并粘贴到manifest.xml文件中。

<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="23" />

由于某些原因,Xamarin在设置属性页时没有更新这一行以包含targetSdkVersion。

希望这有助于有人,因为我花了几个小时试图弄清楚这一点!

JamesMontemagno创建的xam . plugin . geoocator插件有一个很好的例子。

下面是如何获得使用GPS的权限-权限实现示例

这里是一个如何实现它的示例(包括检查GPS是否打开)- GPS实现示例

阅读自述文件。