You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 17:54:33