- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在寻找一种简单的方法来查询和请求 .Net Maui 中的多个权限。我还需要请求蓝牙权限,但据我所知,毛伊岛没有内置的蓝牙权限。我在 2022 年最后一次听到的消息是,毛伊岛路线图中没有蓝牙,我觉得这是相当短视的。
我阅读了很多文章、问答、文档、观看了视频,并做了很多其他研究来解决这个问题。
到目前为止,我可以检查并请求个人权限,但我正在寻找比重复更干燥的东西:
PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.XXX>();
if (status != PermissionStatus.Granted){
status = await Permissions.RequestAsync<Permissions.XXX>();
}
对于每个权限。我需要多个权限,因此我的检查很快就会失控。
顺便说一句,根据 Google Play 要求,我的目标是 Android 13.0。
我知道这要求很高,但我迷失在所有建议中,其中许多建议不起作用,所以帮助解决所有这些问题就太好了!
最佳答案
我使用了许多不同的来源来将其组合在一起,但这些是最有用的。
毛伊岛可用权限:https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/appmodel/permissions
主线程权限:https://stackoverflow.com/a/75574570/1836461
蓝牙和自定义权限:https://www.youtube.com/watch?v=9GljgwfpiiE
定位服务检查:https://stackoverflow.com/a/69158717/1836461
为了使这更容易理解,我将把所有代码留到最后。
此外,我的项目面向 .Net 7.0、Android 13.0 (API 33)、iOS 11.0 和 Windows 10.0.19041.0 当前的 Google Play 要求。我还没有检查这是否适用于 iOS 或 Windows,但这至少让你/我在运行这些其他操作系统方面迈出了几步。更改 JIT 编译器的目标操作系统时,VS 2022 不会引发任何错误,因此它应该可以工作。如果没有,与 1-5 年前的建议或专为 Android 编写的 Java 建议相比,需要做的调整应该更少。
您需要设置 Manifest 和 .plist 文件以获得满足您需求的正确权限。我不打算在这里详细介绍它,因为它在我上面链接的第一个引用文献中已经很好地介绍了。
我建议将您的权限检查代码放入辅助方法中。由于这将是一个异步方法,因此您需要从“OnAppearing”方法调用它,您必须重写该方法并使其异步。
我让我的辅助方法返回一个 bool
,这样我就可以检查是否所有权限都被接受,因为我的应用程序需要我请求的所有权限。没有他们,它根本就不会做任何事。为了轻松检查权限是否被授予/限制,我为此添加了另一种方法,因为我要检查如此多的权限。
您可以将单独的 CheckStatusAsync
和 RequestAsync
移至通用方法并简单地调用该方法以帮助防止重复。
由于您/我需要蓝牙访问,因此您必须编写自定义权限检查器,但仅适用于 Android,不适用于 iOS 或 Windows。这并不难,但是没有太多资源可以向您展示如何操作,而且它们也不容易找到。
显然,如果手机上的定位服务未启用,那么这些对于蓝牙权限来说都无关紧要。如果您的应用程序可以扫描蓝牙设备,但没有找到任何设备,则很有可能手机的定位服务未启用。我必须添加一个 Toast,以便在扫描返回零结果时让用户知道这是必要的。
或者您可以使用操作系统特定方法直接检查定位服务状态。
MainPage.xaml.cs:
using CommunityToolkit.Maui.Alerts; // For the Toast
#if ANDROID
using Android.Content;
using Android.Locations;
#elif IOS || MACCATALYST
using CoreLocation;
#elif WINDOWS
using Windows.Devices.Geolocation;
#endif
protected override async void OnAppearing()
{
base.OnAppearing();
if (!await CheckPermissions())
{
await Toast.Make("Not all permissions were accepted. Application will close.").Show();
Application.Current.Quit();
}
}
private async Task<bool> CheckPermissions()
{
PermissionStatus bluetoothStatus = await CheckBluetoothPermissions();
PermissionStatus cameraStatus = await CheckPermissions<Permissions.Camera>();
PermissionStatus mediaStatus = await CheckPermissions<Permissions.Media>();
PermissionStatus storageWriteStatus = await CheckPermissions<Permissions.StorageWrite>();
//PermissionStatus photosStatus = await CheckPermissions<Permissions.Photos>();
...
bool locationServices = IsLocationServiceEnabled();
return IsGranted(cameraStatus) && IsGranted(mediaStatus) && IsGranted(storageWriteStatus) && IsGranted(bluetoothStatus);
}
private async Task<PermissionStatus> CheckBluetoothPermissions()
{
PermissionStatus bluetoothStatus = PermissionStatus.Granted;
if (DeviceInfo.Platform == DevicePlatform.Android)
{
if (DeviceInfo.Version.Major >= 12)
{
bluetoothStatus = await CheckPermissions<BluetoothPermissions>();
}
else
{
bluetoothStatus = await CheckPermissions<Permissions.LocationWhenInUse>();
}
}
return bluetoothStatus;
}
private async Task<PermissionStatus> CheckPermissions<TPermission>() where TPermission : Permissions.BasePermission, new()
{
PermissionStatus status = await Permissions.CheckStatusAsync<TPermission>();
if (status != PermissionStatus.Granted){
status = await Permissions.RequestAsync<TPermission>();
}
return status;
}
private static bool IsGranted(PermissionStatus status)
{
return status == PermissionStatus.Granted || status == PermissionStatus.Limited;
}
#if ANDROID
private bool IsLocationServiceEnabled()
{
LocationManager locationManager = (LocationManager)Android.App.Application.Context.GetSystemService(Context.LocationService);
return locationManager.IsProviderEnabled(LocationManager.GpsProvider);
}
#elif IOS || MACCATALYST
public bool IsLocationServiceEnabled()
{
return CLLocationManager.Status == CLAuthorizationStatus.Denied;
}
#elif WINDOWS
private bool IsLocationServiceEnabled()
{
Geolocator locationservice = new Geolocator();
return locationservice.LocationStatus == PositionStatus.Disabled;
}
#endif
在您的项目中创建一个名为“BluetoothPermissions.cs”的新文件:
using static Microsoft.Maui.ApplicationModel.Permissions;
namespace YourNamespace;
internal class BluetoothPermissions : BasePlatformPermission
{
#if ANDROID
public override (string androidPermission, bool isRuntime)[] RequiredPermissions =>
new List<(string permission, bool isRuntime)>
{
("android.permission.BLUETOOTH", true),
("android.permission.BLUETOOTH_ADMIN", true),
("android.permission.BLUETOOTH_SCAN", true),
("android.permission.BLUETOOTH_CONNECT", true),
("android.permission.ACCESS_COARSE_LOCATION", true),
("android.permission.ACCESS_FINE_LOCATION", true)
}.ToArray();
// This list includes Bluetooth LE permissions.
// You will need to include these permissions in your Android Manifest, too.
#endif
}
注释:当我继续开发此应用程序时,我正在寻找不需要所有权限(例如蓝牙)即可使用功能的方法。当我使这些功能能够打开和关闭时,我发现我越来越有可能必须在“主页”之外的设置页面上检查这些权限。我可能最终会将大多数(如果不是全部)这些权限转换为它自己的类,这样我就可以从我将打开和关闭功能的各个位置访问它。如果我这样做,我会保留这个答案,并做出一个新答案(如果它与这个答案有显着不同)。
关于c# - 检查和请求毛伊岛权限(包括蓝牙)的简单方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76275381/
我正在努力实现以下目标, 假设我有字符串: ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ) ) ) ) ) 我想编写一个正则
给定: 1 2 3 4 5 6
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
大家好,我卡颂。 Svelte问世很久了,一直想写一篇好懂的原理分析文章,拖了这么久终于写了。 本文会围绕一张流程图和两个Demo讲解,正确的食用方式是用电脑打开本文,跟着流程图、Demo一
身份证为15位或者18位,15位的全为数字,18位的前17位为数字,最后一位为数字或者大写字母”X“。 与之匹配的正则表达式: ?
我们先来最简单的,网页的登录窗口; 不过开始之前,大家先下载jquery的插件 本人习惯用了vs2008来做网页了,先添加一个空白页 这是最简单的的做法。。。先在body里面插入 <
1、MySQL自带的压力测试工具 Mysqlslap mysqlslap是mysql自带的基准测试工具,该工具查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出
前言 今天大姚给大家分享一款.NET开源(MIT License)、免费、简单、实用的数据库文档(字典)生成工具,该工具支持CHM、Word、Excel、PDF、Html、XML、Markdown等
Go语言语法类似于C语言,因此熟悉C语言及其派生语言( C++、 C#、Objective-C 等)的人都会迅速熟悉这门语言。 C语言的有些语法会让代码可读性降低甚至发生歧义。Go语言在C语言的
我正在使用快速将 mkv 转换为 mp4 ffmpeg 命令 ffmpeg -i test.mkv -vcodec copy -acodec copy new.mp4 但不适用于任何 mkv 文件,当
我想计算我的工作簿中的工作表数量,然后从总数中减去特定的工作表。我错过了什么?这给了我一个对象错误: wsCount = ThisWorkbook.Sheets.Count - ThisWorkboo
我有一个 perl 文件,用于查看文件夹中是否存在 ini。如果是,它会从中读取,如果不是,它会根据我为它制作的模板创建一个。 我在 ini 部分使用 Config::Simple。 我的问题是,如果
尝试让一个 ViewController 通过标准 Cocoa 通知与另一个 ViewController 进行通信。 编写了一个简单的测试用例。在我最初的 VC 中,我将以下内容添加到 viewDi
我正在绘制高程剖面图,显示沿路径的高程增益/损失,类似于下面的: Sample Elevation Profile with hand-placed labels http://img38.image
嗨,所以我需要做的是最终让 regStart 和 regPage 根据点击事件交替可见性,我不太担心编写 JavaScript 函数,但我根本无法让我的 regPage 首先隐藏。这是我的代码。请简单
我有一个非常简单的程序来测量一个函数花费了多少时间。 #include #include #include struct Foo { void addSample(uint64_t s)
我需要为 JavaScript 制作简单的 C# BitConverter。我做了一个简单的BitConverter class BitConverter{ constructor(){} GetBy
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我是 Simple.Data 的新手。但我很难找到如何进行“分组依据”。 我想要的是非常基本的。 表格看起来像: +________+ | cards | +________+ | id |
我现在正在开发一个 JS UDF,它看起来遵循编码。 通常情况下,由于循环计数为 2,Alert Msg 会出现两次。我想要的是即使循环计数为 3,Alert Msg 也只会出现一次。任何想法都
我是一名优秀的程序员,十分优秀!