问题
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);
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".
Someone please help how can I install the apk programmatically from the same application itself.
Note: My update apk is present in external storage.
Thanks
回答1:
Have you tried using the action ACTION_INSTALL_PACKAGE?
You can use it to launch the application installer directly and use a few arguments to control the apk file, and the install options.
(EXTRA_INSTALLER_PACKAGE_NAME
, EXTRA_NOT_UNKNOWN_SOURCE
, EXTRA_ALLOW_REPLACE
, and EXTRA_RETURN_RESULT
)
回答2:
Below code works fine for me, I think you may miss the file:// prefix
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://"+path ), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
回答3:
If you have file local in phone or you can download before programmatically :
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.fromFile(
new File(Environment.getExternalStorageDirectory() + "/download/" + "NameOfFille.apk")
), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
回答4:
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.
The code has been tested on Android O and above and Android N and below and all works!
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>
and the referenced XML file:
<?xml version="1.0" encoding="utf-8"?>
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 -> {
}
}
}
来源:https://stackoverflow.com/questions/33521154/install-the-updated-apk-from-the-same-application-itself-programmatically-updat