从片段安装 apk
Install apk from fragment
我正在尝试从我的片段安装一个应用程序。我希望显示未知来源许可消息,然后进行安装过程。问题是在我第一次安装时,应用程序似乎崩溃了。
当然,下次(安装另一个 apk 时)这个问题就会消失。我做了以下步骤:
在我的视图模型中:
fun installApp(uri: Uri) {
viewModelScope.launch(context = exceptionHandler + DEFAULT) {
val promptInstall = Intent(Intent.ACTION_VIEW, uri)
promptInstall.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
promptInstall.setDataAndType(uri, "application/vnd.android" + ".package-archive")
promptInstall.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
promptInstall.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivityMutableLiveData.postValue(promptInstall.toOneTimeEvent())
}
}
然后在我的片段中:
viewModel.startActivityLiveData.observe(viewLifecycleOwner, Observer { oneTimeEvent ->
(oneTimeEvent.getValue() as Intent).startActivityFromIntent(requireActivity())})
最后这是我的扩展功能:
fun Intent.startActivityFromIntent(context: Context) = (context as Activity).startActivity(this)
嗯,看来我上面说的过程在Android10及以上有问题(崩溃了!)。这是我找到的解决方案:
private fun Uri.installApp(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!context.packageManager.canRequestPackageInstalls()) {
startForResult.launch(Intent(ACTION_MANAGE_UNKNOWN_APP_SOURCES))
Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).setData(
} else {
viewModel.installApp(this)
}
} else {
viewModel.installApp(this)
}
我们必须按照以下步骤做:
private val startForResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
when (result.resultCode) {
RESULT_OK -> {
// your logic...
}
RESULT_CANCELED -> {
//do something
}
else -> {
}
}
}
我正在尝试从我的片段安装一个应用程序。我希望显示未知来源许可消息,然后进行安装过程。问题是在我第一次安装时,应用程序似乎崩溃了。 当然,下次(安装另一个 apk 时)这个问题就会消失。我做了以下步骤:
在我的视图模型中:
fun installApp(uri: Uri) {
viewModelScope.launch(context = exceptionHandler + DEFAULT) {
val promptInstall = Intent(Intent.ACTION_VIEW, uri)
promptInstall.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
promptInstall.setDataAndType(uri, "application/vnd.android" + ".package-archive")
promptInstall.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
promptInstall.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivityMutableLiveData.postValue(promptInstall.toOneTimeEvent())
}
}
然后在我的片段中:
viewModel.startActivityLiveData.observe(viewLifecycleOwner, Observer { oneTimeEvent ->
(oneTimeEvent.getValue() as Intent).startActivityFromIntent(requireActivity())})
最后这是我的扩展功能:
fun Intent.startActivityFromIntent(context: Context) = (context as Activity).startActivity(this)
嗯,看来我上面说的过程在Android10及以上有问题(崩溃了!)。这是我找到的解决方案:
private fun Uri.installApp(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!context.packageManager.canRequestPackageInstalls()) {
startForResult.launch(Intent(ACTION_MANAGE_UNKNOWN_APP_SOURCES))
Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).setData(
} else {
viewModel.installApp(this)
}
} else {
viewModel.installApp(this)
}
我们必须按照以下步骤做:
private val startForResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
when (result.resultCode) {
RESULT_OK -> {
// your logic...
}
RESULT_CANCELED -> {
//do something
}
else -> {
}
}
}