feat: OTA校验通过后调用PackageInstaller真正安装APK
- SHA256通过→installApk()→PackageInstaller Session API - 安装完成后通知栏提示重启 - 权限检查: canRequestPackageInstalls()
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,8 @@
|
||||
package dev.yuzu.gca
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.widget.Button
|
||||
@@ -161,6 +164,14 @@ class MainActivity : AppCompatActivity() {
|
||||
val actualSha256 = computeSha256(apkFile)
|
||||
if (actualSha256 == manifestSha256) {
|
||||
appendLog(" ✅ SHA256 校验通过!")
|
||||
// 5. 安装 APK
|
||||
appendLog("[5/5] 提交安装...")
|
||||
try {
|
||||
installApk(apkFile)
|
||||
appendLog(" ✅ 安装已提交,稍后通知栏点击重启")
|
||||
} catch (e: Exception) {
|
||||
appendLog(" ❌ 安装失败: ${e.message}")
|
||||
}
|
||||
} else {
|
||||
appendLog(" ❌ SHA256 校验失败!")
|
||||
appendLog(" expected: ${manifestSha256.take(32)}")
|
||||
@@ -192,6 +203,33 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun installApk(apkFile: File) {
|
||||
if (!packageManager.canRequestPackageInstalls()) {
|
||||
throw SecurityException("需要允许安装未知应用权限")
|
||||
}
|
||||
val packageInstaller = packageManager.packageInstaller
|
||||
val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
|
||||
val sessionId = packageInstaller.createSession(params)
|
||||
val session = packageInstaller.openSession(sessionId)
|
||||
try {
|
||||
apkFile.inputStream().use { input ->
|
||||
session.openWrite("package", 0, apkFile.length()).use { output ->
|
||||
input.copyTo(output)
|
||||
session.fsync(output)
|
||||
}
|
||||
}
|
||||
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
|
||||
?: throw Exception("无法获取启动Intent")
|
||||
val pendingIntent = PendingIntent.getActivity(
|
||||
this, 0, launchIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
session.commit(pendingIntent.intentSender)
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeSha256(file: File): String {
|
||||
val digest = MessageDigest.getInstance("SHA-256")
|
||||
file.inputStream().use { input ->
|
||||
|
||||
Reference in New Issue
Block a user