React Native中Android DownloadManager下载任务卡在queued状态无法下载
Android 11+ DownloadManager排队失败修复方案
1. 补充必要权限
在AndroidManifest.xml中添加以下权限配置:
<!-- 网络访问基础权限 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 读取网络状态,辅助DownloadManager调度任务 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- Android 12及以上通知权限,否则下载通知无法展示会阻塞队列 --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- 如需隐藏下载通知需添加此权限 --> <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
如果下载链接为HTTP明文协议,还需要在application标签添加明文流量允许配置:
<application ... android:usesCleartextTraffic="true">
2. 规避文件名冲突
Android 11对公共目录的文件写入限制更严格,若下载目录已存在同名文件,会导致任务卡队列,建议给文件名添加时间戳后缀避免冲突。
3. 适配通知权限校验
Android 11以上如果应用未获取通知权限,设置VISIBILITY_VISIBLE_NOTIFY_COMPLETED的下载任务会一直卡在排队状态,需要增加权限判断逻辑,调整后的下载代码如下:
public void download(String name, String fileName, String description, String mimeType, String url) { Uri downloadUri = Uri.parse(url); DownloadManager.Request request = new DownloadManager.Request(downloadUri); request.setTitle(name); request.setMimeType(mimeType); request.setDescription(description); request.allowScanningByMediaScanner(); request.setAllowedOverRoaming(true); request.setAllowedOverMetered(true); request.setVisibleInDownloadsUi(true); request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI); // 适配通知权限逻辑 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) { request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); } else { request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN); } } else { request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); } // 生成不重复的安全文件名 int dotIndex = fileName.lastIndexOf("."); String nameNoSuffix = dotIndex > 0 ? fileName.substring(0, dotIndex) : fileName; String suffix = dotIndex > 0 ? fileName.substring(dotIndex) : ""; String safeFileName = nameNoSuffix + "_" + System.currentTimeMillis() + suffix; request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, safeFileName); DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); downloadManager.enqueue(request); }
4. 模拟器异常排查
如果修改后仍有问题,可进入模拟器系统设置,找到「下载管理器」系统应用,清除存储数据后重试,部分版本Android模拟器的下载管理器缓存异常会导致任务卡队列。
内容的提问来源于stack exchange,提问作者Jan Kaifer
相关产品推荐
相关产品推荐

