安卓端Agora SDK在onFileMessageReceived中按指定路径下载文件问题求助
安卓Agora RTM文件消息下载与文件打开问题解决方案
核心排查与修复步骤
- 第一步:校验MediaId有效性
Agora RTM生成的mediaId默认有效期为7天,超出有效期后无法正常下载文件。你可以在onFileMessageReceivedFromPeer回调中打印rtmFileMessage.getMediaId()的值,和发送端上传文件成功后拿到的mediaId做对比,确认两者完全一致,没有出现截断、传值错误的问题。 - 第二步:确认存储写入权限
你当前使用的是应用私有缓存目录,不需要申请外部存储权限,但需要先确认缓存目录可写:// 在getCacheFile方法中增加可写校验 public static String getCacheFile(Context context, String id) { File parent = new File(context.getCacheDir(), CACHE_DIR); if (!parent.exists()) { boolean mkdirSuccess = parent.mkdirs(); if (!mkdirSuccess) { Log.e("CacheError", "缓存目录创建失败"); return null; } } File targetFile = new File(parent, id); if (!targetFile.canWrite()) { Log.e("CacheError", "目标文件无写入权限"); } return targetFile.getAbsolutePath(); } - 第三步:校验下载文件完整性
你遇到的PDF可提示打开但无法正常加载的问题,大概率是文件下载不完整导致的,可以在下载成功回调中增加文件大小校验逻辑,和发送端原始文件大小做比对:
如果你使用的是Agora RTM 1.4.x及以下版本,建议升级到1.5.0及以上稳定版,旧版本存在小概率下载成功回调触发但文件未完全写入磁盘的问题,会导致文件损坏无法打开。@Override public void onSuccess(Void aVoid) { File downloadFile = new File(cacheFile); long downloadSize = downloadFile.length(); long originSize = rtmFileMessage.getSize(); if (downloadSize != originSize) { Log.e("DownloadError", "文件下载不完整,下载大小:" + downloadSize + " 原始大小:" + originSize); // 此处可增加重试下载逻辑 return; } // 原有列表更新逻辑 massageList.add(0,new ChatItem(ChatItem.LayoutSix, "", rtmFileMessage.getFileName(), cacheFile, Time(), false)); chatAdapter.notifyDataSetChanged(); recyclerView_list.scrollToPosition(0); } - 第四步:修复第三方应用打开文件逻辑
如果文件大小校验一致还是无法打开PDF,是安卓7.0及以上系统的文件访问权限限制导致的,需要配置FileProvider来完成文件共享:- 先在AndroidManifest.xml中配置FileProvider声明:
<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>- 在res/xml目录下创建file_paths.xml文件,配置缓存目录的访问权限:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <cache-path name="cache" path="./" /> </paths>- 打开PDF时使用FileProvider获取Uri:
public void openPdfFile(Context context, String filePath) { File pdfFile = new File(filePath); if (!pdfFile.exists()) { Toast.makeText(context, "文件不存在", Toast.LENGTH_SHORT).show(); return; } Intent intent = new Intent(Intent.ACTION_VIEW); Uri uri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", pdfFile); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } else { uri = Uri.fromFile(pdfFile); } intent.setDataAndType(uri, "application/pdf"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { context.startActivity(intent); } catch (ActivityNotFoundException e) { Toast.makeText(context, "请先安装PDF阅读器", Toast.LENGTH_SHORT).show(); } } - 第五步:错误码定位下载失败原因
如果下载直接触发onFailure回调,可以打印errorInfo.getErrorCode()的值定位问题:- 1001:mediaId无效或已过期
- 1003:下载超时,可切换网络重试
- 1004:文件写入失败,检查磁盘剩余空间和目录权限
- 其他错误码可排查当前RTM连接状态,确认下载过程中没有主动断开RTM连接或者销毁RtmClient实例。
内容的提问来源于stack exchange,提问作者komal Jadhav
相关产品推荐
相关产品推荐

