【问题标题】:Install APK programmatically以编程方式安装 APK
【发布时间】:2011-11-03 21:12:23
【问题描述】:

我正在尝试在我的 android 应用中实现 AUTOUPDATE 功能,因为它是一个未通过 android 市场发布的自定义应用。到目前为止,我一切正常,但是 android 尝试安装应用程序并说“应用程序未安装”。不知道是不是很重要,但是App已经在设备上,所以是更新了。

应用程序从互联网下载 APK 文件并将其存储在 SD 卡上。比我这样做:

    Uri packageURI = Uri.parse("package:my_package");
    Intent intent = new Intent(Intent.ACTION_VIEW, packageURI);
    intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + ApkName)), 
            "application/vnd.android.package-archive");
    startActivity(intent);  

【问题讨论】:

  • 您在第一行中创建并放入第二行中的IntentUri 被您在第三行中提供的Uri 覆盖。您可以简单地删除第一行并使用带有操作字符串的单参数Intent 构造函数。另外,不要使用串联来创建路径——使用File 构造函数,它以FileString 作为参数。

标签: android installation package auto-update


【解决方案1】:

这是我使用的sn-p,它看起来和你的基本相同,我能看到的唯一区别是使用了packageURI。我不知道使用 packageURI 是否会导致它不起作用,但如果我是你,我会尝试不使用。

File appFile = new File(ScreenSaverActivity.this.getFilesDir() + File.separator + APPLICATION_FILE_NAME);
Intent installIntent = new Intent(Intent.ACTION_VIEW);
installIntent.setDataAndType(Uri.fromFile(appFile),"application/vnd.android.package-archive");
startActivity(installIntent);

但是,通常当您在尝试安装时看到“未安装应用程序”消息时,这意味着用于签署 2 个 apk 的签名不同,即一个是发布密钥签名,一个是调试密钥签名。或者,如果这 2 个 apk 是在不同的计算机上编译的,那么您已经使用 2 个不同的调试密钥对它们进行了签名。

请注意,即使您不是通过市场进行分发,您仍然需要生成并签署您的应用程序。调试密钥在 1 年后过期,一旦密钥过期,您的应用将停止工作。

【讨论】:

  • 请注意,您的代码只有在文件为 MODE_WORLD_READABLE 时才有效,因为它位于内部存储 (getFilesDir()) 上的应用程序本地位置。
  • 好点。我忘了提到这一点,当我实施它时,它确实让我很适应。
  • 是的,我想你知道。 :-) 但我希望其他任何遇到此答案的人都可以记录下来。
  • 你是对的,签名是问题所在。我没有意识到,我正在运行使用调试密钥签名的应用程序,并希望将其替换为使用普通密钥签名的应用程序。感谢您指出这一点。
【解决方案2】:

1) 检查manifest文件中指定的Application名称是否与之前相同。

2) 我猜你可能需要获取更多的包信息才能匹配。特别是如果应用程序是从不同的机器构建的,签名可能会有所不同(我对此不是 100% 确定)。 此外,如果您使用的是 Eclipse。检查运行配置下,检查指定的包名称是否与初始发布时使用的相同。

【讨论】: