.NET MAUI Android:无需文件选择器直接加载DCIM文件夹图片
可行方案
1. 配置并申请必要权限
首先确保Android项目的AndroidManifest.xml中添加存储读取权限:
<!-- Android 12及以下 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Android 13+ 推荐使用更细分的媒体权限 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
同时在运行时动态申请权限(Android 6.0+要求):
// 在共享项目或Android平台代码中请求权限 var status = await Permissions.CheckStatusAsync<Permissions.StorageRead>(); if (status != PermissionStatus.Granted) { status = await Permissions.RequestAsync<Permissions.StorageRead>(); if (status != PermissionStatus.Granted) { // 权限申请失败,提示用户 return; } }
2. 获取DCIM文件夹路径
通过Android平台API直接获取DCIM目录的绝对路径:
using Android.OS; // 获取系统DCIM根目录 var dcimRootPath = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDcim).AbsolutePath; // 如果截图保存在DCIM的子文件夹(比如Screenshots),拼接路径 var targetFolderPath = Path.Combine(dcimRootPath, "Screenshots");
3. 定位目标截图文件
根据已知的文件名或筛选规则找到目标文件:
- 已知文件名的情况:
var targetFileName = "screenshot_20240520.png"; var targetFilePath = Path.Combine(targetFolderPath, targetFileName); if (!File.Exists(targetFilePath)) { // 处理文件不存在的逻辑 return; }
- 未知文件名,按规则筛选(比如取最新的PNG截图):
var targetFile = new DirectoryInfo(targetFolderPath) .GetFiles("*.png") .OrderByDescending(f => f.CreationTime) .FirstOrDefault(); if (targetFile == null) { // 无匹配文件 return; } var targetFilePath = targetFile.FullName;
4. 转换为MAUI可用的Image
将本地文件转换为MAUI的ImageSource直接绑定到界面控件,或转为Maui.Graphics.Image:
// 方法1:直接绑定到Image控件的Source imageControl.Source = ImageSource.FromFile(targetFilePath); // 方法2:读取为Maui.Graphics.Image using var stream = new FileStream(targetFilePath, FileMode.Open, FileAccess.Read); var mauiImage = PlatformImage.FromStream(stream);
5. 跨平台封装(可选)
为了符合MAUI的跨平台设计,可将Android特定逻辑封装为依赖服务:
// 共享项目定义接口 public interface IDcimImageLoader { Task<Maui.Graphics.Image> LoadScreenshotAsync(string fileName); } // Android平台实现 [assembly: Dependency(typeof(AndroidDcimImageLoader))] namespace YourApp.Platforms.Android { public class AndroidDcimImageLoader : IDcimImageLoader { public async Task<Maui.Graphics.Image> LoadScreenshotAsync(string fileName) { var dcimPath = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDcim).AbsolutePath; var filePath = Path.Combine(dcimPath, fileName); if (!File.Exists(filePath)) return null; using var stream = new FileStream(filePath, FileMode.Open); return await Task.FromResult(PlatformImage.FromStream(stream)); } } } // 共享项目中调用 var loader = DependencyService.Get<IDcimImageLoader>(); var screenshot = await loader.LoadScreenshotAsync("screenshot_20240520.png");
注意事项
- Android 10+的Scoped Storage机制下,直接访问DCIM目录需确保权限配置正确,避免访问受限;
- 若保存截图时已记录文件路径/Uri,直接使用该路径读取效率更高,无需遍历文件夹;
- 处理文件时需捕获
FileNotFoundException、UnauthorizedAccessException等异常,避免崩溃。
内容的提问来源于stack exchange,提问作者Haimo
相关产品推荐
相关产品推荐

