Android WebView文件选择器触发onActivityResult后,文件内容无法处理问题
解决方案
1. 完善Android端WebView权限与回调
拿到文件Uri后,首先要确保WebView有权限访问该文件,同时开启WebView的必要设置:
- 在
onActivityResult中添加临时权限授权:
if (result != null) { // 授予WebView读取该Uri的临时权限 getContentResolver().takePersistableUriPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION); mUploadMessageForAndroid5.onReceiveValue(new Uri[]{result}); }
- 配置WebView支持文件操作:
WebSettings settings = webView.getSettings(); settings.setAllowFileAccess(true); settings.setAllowContentAccess(true); settings.setJavaScriptEnabled(true); // 必须开启JS,用于和前端交互 settings.setDomStorageEnabled(true);
2. ASPX前端添加文件接收与上传逻辑
RadGrid仅负责展示文件,需要先添加前端逻辑接收WebView传递的文件并提交到后端:
- 在ASPX页面添加必要的JS交互逻辑:
<script type="text/javascript"> function handleSelectedFile(fileUri) { // 通过XHR读取Uri对应的文件Blob let xhr = new XMLHttpRequest(); xhr.open('GET', fileUri, true); xhr.responseType = 'blob'; xhr.onload = function() { if (this.status === 200) { let blob = this.response; let fileName = fileUri.split('/').pop() || 'unknown-file'; // 构造FormData准备上传 let formData = new FormData(); formData.append('uploadFile', blob, fileName); // 提交到后端处理页面 let uploadXhr = new XMLHttpRequest(); uploadXhr.open('POST', '<%= ResolveUrl("~/UploadHandler.aspx") %>', true); uploadXhr.onload = function() { if (this.status === 200) { // 上传成功后刷新RadGrid $find('<%= RadGridDI.ClientID %>').rebind(); } }; uploadXhr.send(formData); } }; xhr.send(); } </script>
- Android端通过
evaluateJavascript调用该JS函数:
// 在onActivityResult拿到有效Uri后执行 String jsCommand = String.format("handleSelectedFile('%s');", result.toString()); webView.evaluateJavascript(jsCommand, null);
3. ASPX后端实现文件接收与RadGrid更新
创建UploadHandler.aspx处理文件上传,并更新RadGrid的数据源:
// UploadHandler.aspx.cs protected void Page_Load(object sender, EventArgs e) { if (Request.Files.Count > 0) { HttpPostedFile uploadedFile = Request.Files[0]; // 定义服务器保存路径,确保该目录有写入权限 string savePath = Server.MapPath("~/Uploads/"); if (!Directory.Exists(savePath)) { Directory.CreateDirectory(savePath); } string fullPath = Path.Combine(savePath, uploadedFile.FileName); uploadedFile.SaveAs(fullPath); // 更新数据源(示例用Session存储,实际可替换为数据库操作) List<Document> docList = Session["DocumentList"] as List<Document> ?? new List<Document>(); docList.Add(new Document { Id = docList.Count + 1, DocuId = Guid.NewGuid().ToString(), Filename = uploadedFile.FileName }); Session["DocumentList"] = docList; Response.StatusCode = 200; Response.Write("Upload success"); } else { Response.StatusCode = 400; Response.Write("No file received"); } } // 定义Document实体类(可放在App_Code或单独类库中) public class Document { public int Id { get; set; } public string DocuId { get; set; } public string Filename { get; set; } }
同时,在RadGrid所在页面的后台绑定数据源:
// 页面加载时绑定RadGrid protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { BindRadGrid(); } } private void BindRadGrid() { List<Document> docList = Session["DocumentList"] as List<Document> ?? new List<Document>(); RadGridDI.DataSource = docList; RadGridDI.DataBind(); } // RadGrid的查看按钮逻辑 protected void RadGridDI_SelectedIndexChanged(object sender, EventArgs e) { if (RadGridDI.SelectedItems.Count > 0) { GridDataItem selectedItem = (GridDataItem)RadGridDI.SelectedItems[0]; string fileName = selectedItem["Filename"].Text; string filePath = Server.MapPath("~/Uploads/") + fileName; // 输出文件供在线查看 Response.ContentType = MimeMapping.GetMimeMapping(fileName); Response.AppendHeader("Content-Disposition", "inline; filename=\"" + fileName + "\""); Response.TransmitFile(filePath); Response.End(); } }
4. 关键注意事项
- Android 10+需适配Scoped Storage,避免直接访问文件路径,坚持使用Content Uri。
- 确保ASPX服务器的
~/Uploads/目录有读写权限,否则文件保存会失败。 - WebView中访问
content://Uri时,必须通过XHR读取Blob,不能直接用File API访问。
内容的提问来源于stack exchange,提问作者Manu
相关产品推荐
相关产品推荐

