Apk安裝
Android11之前可通過 Intent.ACTION_INSTALL_PACKAGE 進(jìn)行傳遞Apk的URI進(jìn)行安裝
但是在Android11版本 Intent.ACTION_INSTALL_PACKAGE 已標(biāo)注棄用
同時(shí)推薦在Android5版本提供的PackageInstaller類進(jìn)行安裝
兼容到Android5.0
PackageInstaller
先看看該類的使用流程
Android Apk 安裝.jpg
額外提示
通過該方式,不需要主動(dòng)去申請(qǐng)App內(nèi)安裝Apk權(quán)限,PackageInstaller內(nèi)置了該申請(qǐng)
代碼實(shí)現(xiàn)
注意 該類啟動(dòng)模式為 棧頂單例
同時(shí)需配備一個(gè) intent-filter
<activity android:name=".InstallActivity" android:launchMode="singleTop">
<intent-filter>
<action android:name="cc.xiaobaicz.work.INSTALL_APK" android:exported="true"/>
</intent-filter>
</activity>
//注意 該類啟動(dòng)模式為 棧頂單例
class InstallActivity : AppCompatActivity() {
//intent-filter 的 action
private val ACTION_INSTALL = "cc.xiaobaicz.work.INSTALL_APK"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
install()
}
/**
* 安裝
*/
private fun install() {
packageManager.packageInstaller.apply {
//生成參數(shù)
val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
//創(chuàng)建ID
val id = createSession(params)
//打開Session
val session = openSession(id)
//寫入文件
writeAssetsApk2Session(session, "pbox.apk")
//新建IntentSender
val intent = createIntentSender()
//提交漾狼,進(jìn)行安裝
session.commit(intent)
}
}
/**
* 新建一個(gè)IntentSender用于接收結(jié)果
* 該例子通過當(dāng)前頁面接收
*/
private fun createIntentSender(): IntentSender {
val intent = Intent(this, MainActivity::class.java).apply {
action = ACTION_INSTALL
}
val pending = PendingIntent.getActivity(this, 0, intent, 0)
return pending.intentSender
}
//寫入Apk到Session輸出流,該例子 獲取Assets內(nèi)文件泣栈,可通過其他方式獲取Apk流
private fun writeAssetsApk2Session(session: PackageInstaller.Session, s: String) {
assets.open(s).use { input ->
session.openWrite("apk", 0, -1).use { output ->
output.write(input.readBytes())
}
}
}
/**
* 接收安裝結(jié)果
*/
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
intent ?: return
if (intent.action != ACTION_INSTALL) {
return
}
intent.extras?.apply {
when (this.getInt(PackageInstaller.EXTRA_STATUS)) {
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
//提示用戶進(jìn)行安裝
startActivity(this.get(Intent.EXTRA_INTENT) as Intent)
}
PackageInstaller.STATUS_SUCCESS -> {
//安裝成功
}
else -> {
//失敗信息
val msg = this.getString(PackageInstaller.EXTRA_STATUS_MESSAGE)
}
}
}
}
}