Xamarin.Forms Android 适配API 30分区存储(Scoped Storage)访问问题
Xamarin.Android 适配API30+直接跳转蓝牙文件夹授权方案
Android 8.0(API 26)及以上系统为ACTION_OPEN_DOCUMENT_TREE新增了EXTRA_INITIAL_URI参数,可以指定授权弹窗打开时默认定位的文件夹,不需要用户手动查找路径,即可直接弹出蓝牙文件夹的授权确认窗口。
实现代码
1. 发起授权请求
在需要获取蓝牙文件夹权限的位置调用以下代码:
// 蓝牙文件夹默认URI,对应内部存储根目录下的Bluetooth文件夹 const string BluetoothFolderUri = "content://com.android.externalstorage.documents/tree/primary%3ABluetooth"; var intent = new Intent(Intent.ActionOpenDocumentTree); // 设置默认打开的文件夹为蓝牙目录 intent.PutExtra(DocumentsContract.ExtraInitialUri, Android.Net.Uri.Parse(BluetoothFolderUri)); // 申请读写和持久化权限 intent.AddFlags( ActivityFlags.GrantReadUriPermission | ActivityFlags.GrantWriteUriPermission | ActivityFlags.GrantPersistableUriPermission | ActivityFlags.GrantPrefixUriPermission ); // 启动授权流程,请求码可自行定义 StartActivityForResult(intent, 1001);
2. 处理授权结果
重写OnActivityResult接收授权结果,持久化权限避免后续重复请求:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); if (requestCode != 1001 || resultCode != Result.Ok || data.Data == null) { // 授权失败处理逻辑 return; } // 持久化权限,重启应用后依然有效 ContentResolver.TakePersistableUriPermission( data.Data, ActivityFlags.GrantReadUriPermission | ActivityFlags.GrantWriteUriPermission ); // 后续可通过该URI直接操作蓝牙目录下的所有文件 }
兼容说明
- 极少数定制ROM修改了蓝牙文件默认存储路径,若出现定位失败的情况,可 fallback 到原有用户手动选择目录的逻辑即可
- 该方案完全符合Google Play隐私政策要求,可正常过审
内容的提问来源于stack exchange,提问作者James Murphy
相关产品推荐
相关产品推荐

