使用Android自带的DownloadManager下载文件
-
- 简介
- 基础用法
- 完整代码
先放Google官方文档:https://developer.android.google.cn/reference/android/app/DownloadManager
简介
使用
Context.getSystemService(Context.DOWNLOAD_SERVICE)
来获取DownloadManager的实例DownloadManager可以将指定文件下载到指定位置,并处理下载出错、网络变化、系统重启等情况
需要注册一个ACTION_NOTIFICATION_CLICKED的Receiver来监听处理用户点击下载通知的事件
基础用法
首先保证应用具有
android.permission.INTERNET
权限。注册一个BroadcastReceiver,并在intent-filter标签中添加名称为
android.intent.action.DOWNLOAD_COMPLETE
和android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED
的action。使用DownloadManager.Request类构建一个下载请求,并使用
DownloadManager.enqueue(request)
方法开始进行下载。这个方法会返回一个long类型的值,标记了本次下载的id。
val request = DownloadManager.Request(uri)mId = mDownloadManager.enqueue(request)
下载完成后或用户点击通知栏的下载信息时,之前注册的Receiver会收到消息,我们在onReceive中进行处理。
开始下载之后,我们可以构建一个DownloadManager.Query对象,通过
Query.setFilterById
设置第3步中获取到的id,并调用DownloadManager.query
方法进行查询。query方法返回一个Cursor,和ContentProvider使用方法相同。事实上,DownloadManager的查询就是使用CotentProvider实现的。
val query = DownloadManager.Query()query.setFilterById(mId)val c = mDownloadManager.query(query)c.moveToFirst()val soFar = c.getLong(c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR))val total = c.getLong(c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES))c.close()val currentSpeed = calSpeed()val speed = Util.byte2Human(currentSpeed)Log.d(TAG, "已下载大小: ${Util.byte2Human(soFar)} / ${Util.byte2Human(total)} \t 下载速度: $speed/s")
完整代码
为方便阅读,所有代码都放在了一个Activity中。功能很简单,就是下载一个网络文件,并打印出下载进度,并在下载结束之后进行处理。csdn编辑器对kotlin支持不是很好啊!
package top.littlefogcat.testdownloadimport android.app.Activityimport android.app.DownloadManagerimport android.app.DownloadManager.ACTION_DOWNLOAD_COMPLETEimport android.content.BroadcastReceiverimport android.content.Contextimport android.content.Intentimport android.content.IntentFilterimport android.net.Uriimport android.os.Bundleimport android.os.SystemClockimport android.util.Logimport kotlinx.android.synthetic.main.activity_test.*import java.util.*class TestActivity : Activity() { companion object { const val TAG = "TestActivity" } private lateinit var mDownloadManager: DownloadManager private lateinit var mDownloadReceiver: DownloadReceiver private var mId: Long = -1 private var mComplete = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_test) mDownloadManager = getSystemService(DOWNLOAD_SERVICE) as DownloadManager btnDownload.setOnClickListener { val url = Uri.parse(Constant.QQ_APK_URL) val request = DownloadManager.Request(url) mId = mDownloadManager.enqueue(request) mDownloadReceiver = DownloadReceiver() val filter = IntentFilter(ACTION_DOWNLOAD_COMPLETE) registerReceiver(mDownloadReceiver, filter) Thread(DownloadListener()).start() } } fun notifyDownloadComplete(id: Long) { mComplete = true if (mId == -1L) { Log.w(TAG, "notifyDownloadComplete: NO ID") return } val query = DownloadManager.Query() query.setFilterById(mId) val c = mDownloadManager.query(query) c.moveToFirst() val localUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)) val mediaType = c.getString(c.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE)) Log.d(TAG, "notifyDownloadComplete: localUri = $localUri") Log.d(TAG, "notifyDownloadComplete: mediaType = $mediaType") } override fun onDestroy() { super.onDestroy() unregisterReceiver(mDownloadReceiver) } private inner class DownloadListener : Runnable { private val DEFAULT_QUEUE_SIZE = 5 private val mSpeedQueue = LinkedList() override fun run() { while (true) { if (mComplete) { break } val query = DownloadManager.Query() query.setFilterById(mId) val c = mDownloadManager.query(query) c.moveToFirst() val soFar = c.getLong(c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)) val total = c.getLong(c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)) c.close() if (mSpeedQueue.size >= DEFAULT_QUEUE_SIZE) { mSpeedQueue.poll() mSpeedQueue.offer(soFar) } else { mSpeedQueue.offer(soFar) } val currentSpeed = calSpeed() val speed = Util.byte2Human(currentSpeed) Log.d(TAG, "已下载大小: ${Util.byte2Human(soFar)} / ${Util.byte2Human(total)} \t 下载速度: $speed/s") SystemClock.sleep(500) } } private fun calSpeed(): Long { val size = mSpeedQueue.size if (size < 2) { return 0 } return ((mSpeedQueue.last - mSpeedQueue.first) / (size - 1)) } } private inner class DownloadReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { Log.d(TAG, "onReceive: ${intent?.action}") val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) id?.let { notifyDownloadComplete(it) } } }}
更多相关文章
- Android(安卓)近百个项目的源代码,覆盖Android开发的每个领域
- android 环境变量搭建
- android tab上显示数字
- apk安装法之二----一段Android实现应用下载并自动安装apk包的代
- Android获取WIFI状态下的IP地址以及MAC地址
- Android——NDK下载提示缺少toolchains问题解决
- Android获取手机方向
- Android(安卓)在非UI线程直接更新UI信息
- Android之Input子系统事件分发流程