以下是一个使用Kotlin实现Android设备上应用程序自动更新功能的示例代码:
AutoUpdateManager.kt
的新文件:import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.AsyncTask
import android.os.Build
import android.os.Environment
import android.widget.Toast
import androidx.core.content.FileProvider
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.lang.ref.WeakReference
import java.net.HttpURLConnection
import java.net.URL
class AutoUpdateManager(private val context: Context, private val apkUrl: String) {
private var downloadTask: DownloadTask? = null
fun checkUpdate() {
val currentVersion = getCurrentVersion()
val latestVersion = getLatestVersion()
if (latestVersion > currentVersion) {
showUpdateDialog()
} else {
Toast.makeText(context, "已经是最新版本", Toast.LENGTH_SHORT).show()
}
}
private fun getCurrentVersion(): Int {
var currentVersion = 0
try {
val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
currentVersion = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
packageInfo.longVersionCode.toInt()
} else {
packageInfo.versionCode
}
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
}
return currentVersion
}
private fun getLatestVersion(): Int {
// 从服务器或其他渠道获取最新版本信息
// 这里只是示例,使用一个固定值来代表最新版本
return 2
}
private fun showUpdateDialog() {
// 显示更新对话框,提示用户进行更新操作
// 这里只是示例,使用一个简单的Toast来代替实际的对话框
Toast.makeText(context, "有新版本可用,请点击更新", Toast.LENGTH_SHORT).show()
startDownload()
}
private fun startDownload() {
downloadTask = DownloadTask(context)
downloadTask?.execute(apkUrl)
}
private class DownloadTask(context: Context) : AsyncTask() {
private val contextReference: WeakReference = WeakReference(context)
override fun doInBackground(vararg params: String): File? {
val context = contextReference.get() ?: return null
val apkUrl = params[0]
val url = URL(apkUrl)
val connection = url.openConnection() as HttpURLConnection
connection.connect()
val apkName = apkUrl.substring(apkUrl.lastIndexOf("/") + 1)
val apkFile = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), apkName)
val input = BufferedInputStream(url.openStream())
val output = FileOutputStream(apkFile)
val buffer = ByteArray(1024)
var length: Int
while (input.read(buffer).also { length = it } > 0) {
output.write(buffer, 0, length)
}
output.flush()
output.close()
input.close()
return apkFile
}
override fun onPostExecute(file: File?) {
val context = contextReference.get() ?: return
if (file != null) {
installApk(context, file)
} else {
Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show()
}
}
private fun installApk(context: Context, file: File) {
val intent = Intent(Intent.ACTION_VIEW)
val apkUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
FileProvider.getUriForFile(context, context.packageName + ".fileprovider", file)
} else {
Uri.fromFile(file)
}
intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
}
}
AndroidManifest.xml
文件中添加一个FileProvider来处理安装apk文件的权限问题: