/**
* 专用下载APK文件Service工具类,通知栏显示进度,下载完成自动安装
*/
class UpdateService : Service() {
/**
* 安卓系统下载类
*/
private var manager: DownloadManager by Delegates.notNull()
/**
* 接收下载完的广播
*/
private var mDownloadReceiver: DownloadCompleteReceiver by Delegates.notNull()
/**
* 初始化下载器
*/
private fun initDownManager(url: String) {
Log.i("tt", "initDownManager")
manager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
mDownloadReceiver = DownloadCompleteReceiver()
//设置下载地址
val down = DownloadManager.Request(
//下载链接
Uri.parse(url))
// 设置允许使用的网络类型,这里是移动网络和wifi都可以
down.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE or DownloadManager.Request.NETWORK_WIFI)
// 下载时,通知栏显示途中
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
down.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
}
// 显示下载界面
down.setVisibleInDownloadsUi(true)
// 设置下载后文件存放的位置
down.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, "my_app.apk")
// 将下载请求放入队列
manager.enqueue(down)
//注册下载广播
registerReceiver(mDownloadReceiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
val url = intent.getStringExtra("url")
// 调用下载
initDownManager(url)
return super.onStartCommand(intent, flags, startId)
}
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onDestroy() {
// 注销下载广播
unregisterReceiver(mDownloadReceiver)
super.onDestroy()
}
// 接受下载完成后的intent
internal open inner class DownloadCompleteReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
//判断是否下载完成的广播
if (intent.action == DownloadManager.ACTION_DOWNLOAD_COMPLETE) {
Log.i("tt", "DownloadManager.ACTION_DOWNLOAD_COMPLETE")
//获取下载的文件id
val downId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1L)
//自动安装apk
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
val uriForDownloadedFile = manager.getUriForDownloadedFile(downId)
Log.i("tt", "uri=$uriForDownloadedFile")
installApkNew(uriForDownloadedFile)
}
//停止服务并关闭广播
this@UpdateService.stopSelf()
}
}
//安装apk
private fun installApkNew(uri: Uri) {
val intent = Intent()
//执行动作
intent.action = Intent.ACTION_VIEW
//执行的数据类型
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.setDataAndType(uri, "application/vnd.android.package-archive")
//不加下面这句话是可以的,查考的里面说如果不加上这句的话在apk安装完成之后点击单开会崩溃
// android.os.Process.killProcess(android.os.Process.myPid());
startActivity(intent)
}
}
}
//启动服务
val intent = Intent(this, UpdateService::class.java)
intent.putExtra("url", url)
startService(intent)