在Xamarin/Maui C#库中找不到RegisterForActivityResult怎么办?
MAUI中蓝牙权限请求的正确实现方案
1. 优先使用MAUI内置权限API(推荐)
MAUI已经封装了跨平台的权限请求逻辑,无需直接操作Android原生的ActivityResult系统,代码更简洁且不依赖特定Activity。
步骤1:配置Android权限声明
在Platforms/Android/AndroidManifest.xml中添加对应权限:
<!-- Android 11及以下基础蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> <!-- Android 12+ 细分蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- Android 10+ 扫描蓝牙需定位权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
步骤2:共享代码中实现权限请求
using Microsoft.Maui.ApplicationModel; using Microsoft.Maui.ApplicationModel.Permissions; public async Task<bool> GetBluetoothAccessAsync() { PermissionStatus overallStatus = PermissionStatus.Denied; if (DeviceInfo.Platform == DevicePlatform.Android) { if (DeviceInfo.Version.Major >= 12) { // Android 12+ 需分别请求扫描和连接权限 var scanPerm = await Permissions.RequestAsync<Permissions.BluetoothScan>(); var connectPerm = await Permissions.RequestAsync<Permissions.BluetoothConnect>(); overallStatus = (scanPerm == PermissionStatus.Granted && connectPerm == PermissionStatus.Granted) ? PermissionStatus.Granted : PermissionStatus.Denied; } else if (DeviceInfo.Version.Major >= 10) { // Android 10-11 需定位+传统蓝牙权限 var locationPerm = await Permissions.RequestAsync<Permissions.LocationWhenInUse>(); var bluetoothPerm = await Permissions.RequestAsync<Permissions.Bluetooth>(); overallStatus = (locationPerm == PermissionStatus.Granted && bluetoothPerm == PermissionStatus.Granted) ? PermissionStatus.Granted : PermissionStatus.Denied; } else { // Android 9及以下仅需传统蓝牙权限 overallStatus = await Permissions.RequestAsync<Permissions.Bluetooth>(); } } else { // 其他平台通用处理 overallStatus = await Permissions.RequestAsync<Permissions.Bluetooth>(); } // 权限通过后,请求打开蓝牙开关 if (overallStatus == PermissionStatus.Granted) { var bluetooth = Bluetooth.Default; if (!bluetooth.IsOn) { return await bluetooth.RequestEnableAsync(); } return true; } return false; }
2. 若需使用Android原生ActivityResultLauncher
如果必须依赖原生实现,MAUI中可通过Platform.CurrentActivity获取当前Activity,注册ActivityResultLauncher,同时通过TaskCompletionSource将回调转为异步方法,避免直接耦合Activity:
#if ANDROID using Android.App; using Android.Content; using AndroidX.Activity.Result; using AndroidX.Activity.Result.Contracts; public class BluetoothEnableHelper : IDisposable { private readonly Activity _currentActivity; private ActivityResultLauncher<Intent> _btLauncher; private TaskCompletionSource<bool> _resultTcs; public BluetoothEnableHelper() { _currentActivity = Platform.CurrentActivity; // 注册Launcher _btLauncher = _currentActivity.RegisterForActivityResult( new StartActivityForResultContract(), result => { _resultTcs?.SetResult(result.ResultCode == Result.Ok); _resultTcs = null; }); } public Task<bool> RequestBluetoothEnableAsync() { _resultTcs = new TaskCompletionSource<bool>(); var enableIntent = new Intent(BluetoothAdapter.ActionRequestEnable); _btLauncher.Launch(enableIntent); return _resultTcs.Task; } // 释放资源避免内存泄漏 public void Dispose() { _btLauncher?.Unregister(); } } #endif
在共享代码中调用:
#if ANDROID using (var helper = new BluetoothEnableHelper()) { bool isBtEnabled = await helper.RequestBluetoothEnableAsync(); // 处理结果 } #endif
关于是否必须使用OnActivityResult
完全不需要,上述两种方案都能替代传统的OnActivityResult回调。MAUI内置API是最优解,原生ActivityResultLauncher方案也符合现代Android开发规范,且通过Platform.CurrentActivity和异步封装,能实现蓝牙处理类与Activity的解耦。
内容的提问来源于stack exchange,提问作者SoItBegins
相关产品推荐
相关产品推荐

