使用File Picker时遭遇“Input string was not in a correct format”异常求助
解决Android 10下Plugin.FilePicker的格式转换异常
你遇到的问题是Plugin.FilePicker在Android 10环境下解析文件Uri时,尝试将字符串转为Int64失败导致的格式异常。从异常栈能明确看到,问题出在插件的IOUtil.GetPath方法里——这是因为Android 10引入了**Scoped Storage(分区存储)**机制,旧版本的FilePicker插件没适配这种新的文件Uri格式,才会触发解析错误。
下面是几个可行的解决方案:
1. 优先升级Plugin.FilePicker到最新版本
旧版本插件对Android 10及以上的分区存储支持不完善,直接升级到最新稳定版通常能解决问题。你可以在项目的NuGet包管理器中搜索Plugin.FilePicker,选择最新版本更新,新版本已经修复了大量适配Android 10+的兼容性问题。
2. 绕过插件路径解析,直接处理文件流
如果升级后仍有问题,建议不要依赖插件返回的FileData.Path,而是通过Android原生的ContentResolver直接读取文件内容。示例代码如下:
FileData fileData = await CrossFilePicker.Current.PickFile(); if (fileData != null) { // 用ContentResolver直接获取文件流,避免路径解析 var contentResolver = Android.App.Application.Context.ContentResolver; using (var stream = contentResolver.OpenInputStream(fileData.FilePath)) { // 这里可以直接处理文件流,比如转成字节数组或复制到应用内部存储 byte[] fileBytes = new byte[stream.Length]; await stream.ReadAsync(fileBytes, 0, fileBytes.Length); // 后续业务逻辑处理... } }
3. 适配分区存储的自定义路径解析(可选)
如果确实需要获取文件的真实路径,可以使用兼容Android 10的路径解析工具类,替换插件的GetPath逻辑:
public static string GetRealPathFromUri(Context context, Uri uri) { string filePath = ""; if (DocumentsContract.IsDocumentUri(context, uri)) { string docId = DocumentsContract.GetDocumentId(uri); // 处理媒体文件Uri if ("com.android.providers.media.documents".Equals(uri.Authority)) { string id = docId.Split(':')[1]; string selection = MediaStore.Images.Media._ID + "=?"; string[] selectionArgs = new string[] { id }; filePath = GetDataColumn(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs); } // 处理下载文件Uri else if ("com.android.providers.downloads.documents".Equals(uri.Authority)) { Uri contentUri = ContentUris.WithAppendedId(Uri.Parse("content://downloads/public_downloads"), long.Parse(docId)); filePath = GetDataColumn(context, contentUri, null, null); } } else if ("content".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase)) { filePath = GetDataColumn(context, uri, null, null); } return filePath; } private static string GetDataColumn(Context context, Uri uri, string selection, string[] selectionArgs) { string column = MediaStore.Images.Media.DATA; string[] projection = { column }; using (Cursor cursor = context.ContentResolver.Query(uri, projection, selection, selectionArgs, null)) { if (cursor != null && cursor.MoveToFirst()) { int columnIndex = cursor.GetColumnIndexOrThrow(column); return cursor.GetString(columnIndex); } } return null; }
注意:这个方法在Android 11+下可能仍有访问限制,建议优先使用文件流的方式处理文件。
4. 检查权限配置
确保你的AndroidManifest.xml中添加了必要权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
如果是旧项目升级,可临时添加以下属性兼容旧存储模式(仅作为过渡方案):
<application android:requestLegacyExternalStorage="true" ...>
内容的提问来源于stack exchange,提问作者sahithi
相关产品推荐
相关产品推荐

