Android:下载文件后检查存在性却提示不存在的问题求助
嘿,我之前也踩过这个坑!用DownloadManager下载完成后立刻检查文件找不到,多半是这几个原因,咱们一步步来搞定:
1. 别在回调里立刻检查,等系统真正处理完
DownloadManager的完成通知只是告诉你下载任务结束了,但系统可能还在把文件从临时目录移到目标位置,或者MediaScanner还在扫描文件。这时候直接去查文件,大概率是找不到的。
正确的姿势是注册一个BroadcastReceiver监听DownloadManager.ACTION_DOWNLOAD_COMPLETE广播,等收到这个广播再去检查文件——这时候系统才真正把文件准备好了。
2. 用DownloadManager查询接口获取真实路径,别自己瞎拼
你可能是自己拼接文件名去查找,但DownloadManager有自己的存储逻辑(尤其是Android 10+的分区存储),自己拼的路径很可能不对。一定要通过查询DownloadManager的Cursor来获取文件的真实Uri:
// 先定义广播接收器(可以在Activity里动态注册) private BroadcastReceiver downloadCompleteReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); DownloadManager.Query query = new DownloadManager.Query(); query.setFilterById(downloadId); Cursor cursor = dm.query(query); if (cursor.moveToFirst()) { int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); if (status == DownloadManager.STATUS_SUCCESSFUL) { // 获取下载文件的本地Uri String localUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); File downloadedFile = new File(Uri.parse(localUri).getPath()); // 现在检查文件是否存在 if (downloadedFile.exists()) { // 搞定!文件存在,执行你的逻辑 } else { // Android 10+可能出现File路径访问不到的情况,试试通过ContentResolver验证 try (InputStream is = getContentResolver().openInputStream(Uri.parse(localUri))) { if (is != null) { // 其实文件是存在的,只是不能通过File直接访问,改用ContentResolver操作即可 } } catch (IOException e) { e.printStackTrace(); } } } cursor.close(); } } }; // 在onCreate里注册广播 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ...其他初始化代码 registerReceiver(downloadCompleteReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); } // 别忘了在onDestroy里注销广播,避免内存泄漏 @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(downloadCompleteReceiver); }
3. 权限要到位
如果你的App targetSdkVersion >=23,记得动态申请WRITE_EXTERNAL_STORAGE权限(Android 10+下载到公共目录依然需要这个权限)。如果是Android 11+,尽量避免申请MANAGE_EXTERNAL_STORAGE,优先用DownloadManager默认的存储路径或者setDestinationInExternalFilesDir指定App私有目录(私有目录不需要额外权限)。
4. 确认下载请求的目标路径设置正确
如果是你自己指定了下载路径,比如用request.setDestinationUri()或者request.setDestinationInExternalPublicDir(),一定要确保路径是合法的,并且App有访问权限。如果没设置,DownloadManager会默认存在系统的下载目录,这时候绝对不要自己拼接路径,必须通过Cursor查询获取。
内容的提问来源于stack exchange,提问作者Aerandir Games

