• 简介
    • 基础用法
      • 完整代码

先放Google官方文档:https://developer.android.google.cn/reference/android/app/DownloadManager

简介

  • 使用Context.getSystemService(Context.DOWNLOAD_SERVICE)来获取DownloadManager的实例

  • DownloadManager可以将指定文件下载到指定位置,并处理下载出错、网络变化、系统重启等情况

  • 需要注册一个ACTION_NOTIFICATION_CLICKED的Receiver来监听处理用户点击下载通知的事件

基础用法

  1. 首先保证应用具有android.permission.INTERNET权限。

  2. 注册一个BroadcastReceiver,并在intent-filter标签中添加名称为android.intent.action.DOWNLOAD_COMPLETEandroid.intent.action.DOWNLOAD_NOTIFICATION_CLICKED的action。

  3. 使用DownloadManager.Request类构建一个下载请求,并使用DownloadManager.enqueue(request)方法开始进行下载。这个方法会返回一个long类型的值,标记了本次下载的id。

val request = DownloadManager.Request(uri)mId = mDownloadManager.enqueue(request)
  1. 下载完成后或用户点击通知栏的下载信息时,之前注册的Receiver会收到消息,我们在onReceive中进行处理。

  2. 开始下载之后,我们可以构建一个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) }        }    }}

更多相关文章

  1. Android(安卓)近百个项目的源代码,覆盖Android开发的每个领域
  2. android 环境变量搭建
  3. android tab上显示数字
  4. apk安装法之二----一段Android实现应用下载并自动安装apk包的代
  5. Android获取WIFI状态下的IP地址以及MAC地址
  6. Android——NDK下载提示缺少toolchains问题解决
  7. Android获取手机方向
  8. Android(安卓)在非UI线程直接更新UI信息
  9. Android之Input子系统事件分发流程

随机推荐

  1. android常用
  2. Android Studio Exception: Could not fi
  3. Android 官方文档:(二)应用清单 —— 2.26 <
  4. Android(安卓)常用命令
  5. Android手电筒案例
  6. minSdkVersion、targetSdkVersion、targe
  7. android监听软键盘enter按键
  8. Android事件分发机制——ViewGroup(二)
  9. 性能优化学习资源
  10. [android]android自动化测试十三之JavaMo