以编程方式从同一应用程序本身安装更新的 Apk.[更新 apk] [英] Install the updated Apk from the same application itself programmatically.[Update apk]
问题描述
我正在使用以下代码从我的应用程序安装应用程序.
I am using following code to install an application from my app.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/InstallTest.apk")), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
让上面代码的包是com.xyz.one.现在,如果我使用上述代码安装任何其他软件包应用程序,则它可以正常工作.但是,如果我为同一应用程序(即 com.xyz.one)的更新后的 apk 版本尝试使用相同的代码,则会出现解析包时出现问题".
Let the package for above code is com.xyz.one. Now if I install any other package application with the mentioned code then it works fine. But if I try the same code for the updated apk version of the same application i.e. com.xyz.one then it gives "There is a problem parsing the package".
有人请帮助我如何从同一应用程序本身以编程方式安装 apk.
Someone please help how can I install the apk programmatically from the same application itself.
注意:我的更新 apk 存在于外部存储中.
Note: My update apk is present in external storage.
谢谢
推荐答案
关于通过文件下载更新 Android 应用程序有很多问题,而且发生了很多变化,我觉得此时更新会很好,所以就来了.
There is so many questions around updating Android Apps via file download and so much has changed that I felt an update would be good at this point so here it is.
代码已经在 Android O 及以上版本和 Android N 及以下版本测试,一切正常!
The code has been tested on Android O and above and Android N and below and all works!
在清单文件中,要支持 Android O 及更高版本,您需要
In the manifest file, to support Android O and above you will need
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
并且,要访问下载的文件,您需要:
and, for accessing the downloaded file you will need:
<application
...>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/app_installer_path"/>
</provider>
和引用的 XML 文件:
and the referenced XML file:
<?xml version="1.0" encoding="utf-8"?>
自从这些天以来,很多人都转向了 Kotlin,我将在下面展示该代码:
Since these days many have moved to Kotlin, I'll show that code below:
// Plain old filepath: E.g., "/storage/emulated/0/MyAppStorage/Temp/release-1.0.2039.apk"
private lateinit var appUpdateApk: String
以及真正起作用的代码:
And the code that does the real work:
private fun checkAndroidVersionAndInstallApk() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (MyApplication.context.packageManager.canRequestPackageInstalls()) {
installApk()
} else {
startActivityForResult(Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:${requireContext().packageName}")), INSTALL_PACKAGES_REQUESTCODE)
}
} else {
installApk()
}
}
private fun installApk() {
val intent = Intent(Intent.ACTION_VIEW)
intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val contentUri = FileProvider.getUriForFile(requireContext(), "${requireContext().packageName}.FileProvider", File(appUpdateApk))
intent.setDataAndType(contentUri, "application/vnd.android.package-archive")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
} else {
intent.setDataAndType(Uri.fromFile(File(appUpdateApk)), "application/vnd.android.package-archive")
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
requireContext().startActivity(intent)
requireActivity().finish()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
logInfo("VersionCheckFragment::onActivityResult: $requestCode")
when (requestCode) {
INSTALL_PACKAGES_REQUESTCODE -> checkAndroidVersionAndInstallApk()
else -> {
}
}
}
这篇关于以编程方式从同一应用程序本身安装更新的 Apk.[更新 apk]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!