以编程方式从同一应用程序本身安装更新的Apk。[更新apk]

时间:2015-11-04 11:51:26

标签: android apk android-install-apk

我正在使用以下代码从我的应用程序安装应用程序。

 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。 现在,如果我使用上述代码安装任何其他软件包应用程序,那么它工作正常。 但是,如果我为相同应用程序的更新apk版本(即com.xyz.one)尝试相同的代码,则会显示“解析包时出现问题”。

有人请帮助我如何从同一个应用程序本身以编程方式安装apk。

注意:我的更新apk存在于外部存储设备中。

由于

4 个答案:

答案 0 :(得分:0)

您是否尝试过使用ACTION_INSTALL_PACKAGE动作?

您可以使用它直接启动应用程序安装程序,并使用一些参数来控制apk文件和安装选项。

EXTRA_INSTALLER_PACKAGE_NAMEEXTRA_NOT_UNKNOWN_SOURCEEXTRA_ALLOW_REPLACEEXTRA_RETURN_RESULT

答案 1 :(得分:0)

下面的代码对我来说很好,我想你可能会错过 file:// 前缀

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);

答案 2 :(得分:0)

如果您在手机中有本地文件,或者您可以通过编程方式下载:

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);

答案 3 :(得分:0)

围绕通过文件下载来更新Android Apps的问题太多了,而且已经发生了很大的变化,以至于我认为目前更新是个好办法。

该代码已经在Android O及更高版本以及Android N及更低版本上进行了测试,并且可以正常工作!

在清单文件中,要支持Android O及更高版本,您将需要

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

,并且,要访问下载的文件,您将需要:

<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文件:

<?xml version="1.0" encoding="utf-8"?>

由于这几天有很多人搬到Kotlin,所以我将在下面显示该代码:

// Plain old filepath: E.g., "/storage/emulated/0/MyAppStorage/Temp/release-1.0.2039.apk"
private lateinit var appUpdateApk: String
    

执行实际工作的代码:

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 -> {
        }
    }
}