Android(Kotlin)中使用DownloadManager下载文件后如何访问文件
解决DownloadManager下载文件后通过Uri访问的问题
DownloadManager返回的Uri是content://类型的内容URI,不是直接的文件路径,不能通过uri.path直接访问文件,必须通过ContentResolver来读取文件内容。以下是针对不同场景的具体实现:
1. 显示下载的图片
方法一:使用Glide(推荐,自动处理URI和线程)
直接将Uri传入Glide加载到ImageView:
// 确保已添加Glide依赖到build.gradle Glide.with(applicationContext) .load(uri) .into(yourImageView)
方法二:原生方式读取Bitmap
如果不想用第三方库,通过ContentResolver获取输入流解码Bitmap:
val contentResolver = applicationContext.contentResolver contentResolver.openInputStream(uri)?.use { inputStream -> val bitmap = BitmapFactory.decodeStream(inputStream) yourImageView.post { yourImageView.setImageBitmap(bitmap) } }
2. 播放下载的音频
方法一:使用MediaPlayer
val mediaPlayer = MediaPlayer().apply { setDataSource(applicationContext, uri) prepareAsync() setOnPreparedListener { start() } setOnErrorListener { _, _, _ -> // 处理播放错误 true } } // 记得在合适的时机释放MediaPlayer,比如页面销毁时 // mediaPlayer.release()
方法二:使用ExoPlayer(更稳定,支持更多格式)
// 确保已添加ExoPlayer依赖 val exoPlayer = SimpleExoPlayer.Builder(applicationContext).build() yourPlayerView.player = exoPlayer val mediaItem = MediaItem.fromUri(uri) exoPlayer.setMediaItem(mediaItem) exoPlayer.prepare() exoPlayer.playWhenReady = true // 页面销毁时释放资源 // exoPlayer.release()
3. 关键注意事项
- 权限问题:Android 10及以上采用分区存储,DownloadManager返回的Content Uri已具备访问权限,无需额外申请
READ_EXTERNAL_STORAGE;Android 9及以下若下载到公共目录(如Downloads),需在Manifest中声明权限并动态申请。 - 上下文安全:优先使用
onReceive传入的context参数,避免直接依赖全局applicationContext,可通过context ?: applicationContext做空安全处理。 - 文件存在性校验:可以先查询确认文件存在,避免空指针:
val contentResolver = applicationContext.contentResolver val cursor = contentResolver.query(uri, null, null, null, null) cursor?.use { if (it.moveToFirst()) { // 文件存在,执行后续操作 } else { // 文件不存在,处理异常 } }
修改后的BroadcastReceiver示例:
var brdCstRcvr = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) val appContext = context ?: applicationContext if (id == downloadID) { Toast.makeText(appContext, "Download Completed !!!", Toast.LENGTH_LONG).show() val mgr = appContext.getSystemService(DOWNLOAD_SERVICE) as DownloadManager val uri: Uri = mgr.getUriForDownloadedFile(downloadID) // 示例:显示图片 Glide.with(appContext) .load(uri) .into(yourImageView) // 示例:播放音频 val mediaPlayer = MediaPlayer().apply { setDataSource(appContext, uri) prepareAsync() setOnPreparedListener { start() } } } } }
内容的提问来源于stack exchange,提问作者Michel
相关产品推荐
相关产品推荐

