Xamarin Android通过Intent调用图库无法正常显示图片求助
解决Xamarin Android调用系统图库显示扭曲图片的问题
先看你遇到的问题:
我帮你排查了代码里的核心问题,主要是Android 7.0(API 24)及以上版本的Uri生成逻辑错误,加上可能的文件写入不完整问题,导致系统图库无法正确解析图片文件。下面是具体的修复步骤:
1. 修复FileProvider的Uri生成逻辑
Android N开始,系统禁止直接通过content://拼接文件路径的方式生成Uri,必须使用FileProvider来生成合法的Content Uri,否则其他应用(比如系统图库)无法安全读取文件,进而导致图像显示扭曲。
步骤1:在AndroidManifest.xml中注册FileProvider
打开你的Android项目的AndroidManifest.xml,在<application>标签内添加FileProvider的注册:
<application ...> <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application>
步骤2:创建FileProvider路径配置文件
在项目的Resources/xml目录下(如果没有xml目录,右键Resources新建一个)创建file_paths.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 配置你存放图片的公共目录路径 --> <external-public-path name="geo_mobiz_images" path="Pictures/Geo Mobiz" /> </paths>
步骤3:修改FileHelper的GetFileUri方法
把原来错误的Uri生成逻辑替换为FileProvider的正确用法:
public class FileHelper { public static FileHelper Instance { get; } = new FileHelper(); public async Task<Android.Net.Uri> GetFileUri(byte[] file, string fileName) { var filePath = GetFullFilePath(fileName); if (!FileExists(filePath)) { await SaveFileInDevice(file, filePath); } Android.Net.Uri uri; if (Build.VERSION.SdkInt >= BuildVersionCodes.N) { // 使用FileProvider生成合法的Content Uri uri = FileProvider.GetUriForFile( Android.App.Application.Context, $"{Android.App.Application.Context.PackageName}.fileprovider", new Java.IO.File(filePath)); } else { uri = Android.Net.Uri.Parse("file://" + filePath); } return uri; } // 其他方法保持不变,下面修复SaveFileInDevice方法 }
2. 确保图片文件完整写入
原代码中的SaveFileInDevice方法没有确保所有数据写入文件,可能导致文件损坏,加上FlushAsync确保数据全部写入:
private async Task SaveFileInDevice(byte[] file, string filePath) { using (var fileOutputStream = new FileOutputStream(filePath)) { await fileOutputStream.WriteAsync(file); await fileOutputStream.FlushAsync(); // 强制将缓存数据写入磁盘 } }
3. 权限适配(可选但重要)
如果你的应用目标是Android 10(API 29)及以上版本,需要注意:
- 对于公共目录的读写,需要在
AndroidManifest.xml中添加android:requestLegacyExternalStorage="true"(针对Android 10),或者申请MANAGE_EXTERNAL_STORAGE权限(Android 11+); - 也可以考虑将图片保存到应用私有目录,这样不需要额外的存储权限。
验证修复
修改完成后,重新编译运行应用,调用图库打开图片时,系统就能正确读取完整的图片文件,不会再显示扭曲的图像了。
内容的提问来源于stack exchange,提问作者Mohsin Ali Ayub
相关产品推荐
相关产品推荐

