我正在为我的应用程序进行更新,其中有一节涉及下载和安装APK文件.
只要之前的版本是针对SDK30的,一切都运行得相当顺利.但是,当我增加目标并将SDK编译到32位时,它就开始出现奇怪的行为.
下面是处理包管理器和安装的代码:
private fun installOnClickListener() {
binding.termuxInstallCard.showProgress()
var session: PackageInstaller.Session? = null
try {
val packageInstaller: PackageInstaller =
requireContext().packageManager.packageInstaller
val params = PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL
)
val sessionId = packageInstaller.createSession(params)
session = packageInstaller.openSession(sessionId)
viewModel.addApkToSession(session)
var installBroadcast: PendingIntent? = null
val intent =
Intent(PACKAGE_INSTALLED_ACTION).putExtra(
"packageName",
"com.termux"
)
installBroadcast = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.getBroadcast(
context,
0,
intent,
FLAG_MUTABLE
)
} else {
PendingIntent.getBroadcast(context, 0, intent, FLAG_UPDATE_CURRENT)
}
session.commit(installBroadcast.intentSender)
session.close()
} catch (e: IOException) {
throw RuntimeException("Couldn't install package", e)
} catch (e: RuntimeException) {
session?.abandon()
throw e
} finally {
session?.close()
}
}
以下是正在发生的事情:
因为我的目标是SDK 32,所以我需要指定Mutability of PendingIntent
Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent
当我使用时:
- FLAG_MUTABLE-安装失败,并在EXTRA_STATUS_MESSAGE中说明错误代码-STATUS_FAILURE_INVALID,没有额外的调试消息.问题是,当我试图通过ADBshell 安装相同的下载APK时,它只是正常安装,没有任何问题.
- FLAG_IMMARTABLE-安装成功,而不用安装对话框提示用户but nothing is actually installed.
更多的代码,以防你需要-
fun addApkToInstallSession(
path: String,
session: PackageInstaller.Session
) {
val file = File("${context.filesDir.path}/$path")
val packageInSession: OutputStream = session.openWrite("com.termux", 0, -1)
val inputStream = FileInputStream(file)
val byteStream = inputStream.read()
try {
var c: Int
val buffer = ByteArray(16384)
while (inputStream.read(buffer).also { c = it } >= 0) {
packageInSession.write(buffer, 0, c)
}
} catch (e: IOException) {
println("IOEX")
} finally {
try {
packageInSession.close()
inputStream.close()
} catch (e: IOException) {
println("IOEX in closing the stream")
}
}
}
private val broadcastReceiverForInstallEvents = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
lifecycleScope.launch(Dispatchers.IO) {
val extras = intent.extras
val status = extras!!.getInt(PackageInstaller.EXTRA_STATUS)
val packageName = extras.getString("packageName")!!
if (PACKAGE_INSTALLED_ACTION == intent.action) {
println("STATUS $status")
when (status) {
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
try {
val confirmIntent = extras[Intent.EXTRA_INTENT] as Intent
confirmIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(confirmIntent)
} catch (e: Exception) {
lifecycleScope.launch(Dispatchers.Main) {
Toast.makeText(
requireContext(),
"We could not find an application to handle the installation of apps. Please download a package installer.",
Toast.LENGTH_SHORT
).show()
}
}
}
PackageInstaller.STATUS_SUCCESS -> {
lifecycleScope.launch(Dispatchers.Main) {
println("$packageName Install succeeded!")
// todo all done animation
binding.termuxInstallCard.markAsComplete()
Toast.makeText(requireContext(), "All Done!", Toast.LENGTH_SHORT)
.show()
lifecycleScope.launch {
// viewModel.setTermuxSetupDone()
}
/* redirecting... */
Handler(Looper.getMainLooper()).postDelayed({
redirect()
}, 2000)
}
}
PackageInstaller.STATUS_FAILURE, PackageInstaller.STATUS_FAILURE_ABORTED, PackageInstaller.STATUS_FAILURE_BLOCKED, PackageInstaller.STATUS_FAILURE_CONFLICT, PackageInstaller.STATUS_FAILURE_INCOMPATIBLE, PackageInstaller.STATUS_FAILURE_INVALID, PackageInstaller.STATUS_FAILURE_STORAGE -> {
lifecycleScope.launch(Dispatchers.Main) {
println("Extra Status Message${extras.getString("EXTRA_STATUS_MESSAGE")}")
"There was an error installing Termux. Please retry.".showSnackbar(
binding.root,
true
)
binding.termuxInstallCard.hideProgress()
}
}
else -> {
lifecycleScope.launch(Dispatchers.Main) {
println("$packageName Install failed else!")
// exitActivity("Package failed to install -> Unknown Error!")
binding.termuxInstallCard.hideProgress()
}
}
}
}
}
}
}
如果能帮上忙,我会非常感激!