无需下载,通过程序重新安装应用程序apk

12
由于这个令人烦恼的Android限制,我需要用户重新安装我的应用程序,以便其他应用程序可以检测到清单权限。
这对用户来说已经很烦人了,而且我无法找到一种方法从存储在/data/app中的apk中重新安装我的应用程序,因此我必须在触发通常的安装意图之前将相同版本下载到存储卡中。
我迫切希望有人告诉我我漏了什么显而易见的东西!我一片空白...
提前感谢。
如果您希望看到该问题得到解决,请为此问题加星!谢谢。
编辑:请使用以下代码启动安装对话框,考虑@hackbod的评论。
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(this.getApplicationInfo().sourceDir)),
"application/vnd.android.package-archive");
startActivity(intent);
在我的Jelly Bean设备上,这会呈现两个选项:软件包安装器验证并安装。我不知道后者是否能够解决以下问题:
  • 通过这种方式安装应用程序可能会从Play商店中删除其所有权

我的应用程序是免费的,因此我无法测试以下付费问题:

  • 请注意,如果您的应用程序被前向锁定(这对所有JB或更高版本的付费应用程序都是无法避免的,因为应用程序已加密),则此方法将无法工作,因为其他人无法读取您的应用程序可执行文件

尽管hackbod最后使用了“可以被其他人读取”的话语,这表明如果您通过自己的代码执行此操作,对于您自己的应用程序而言,它是可读取的。如果您能够测试并且我错了,请纠正我。


1
您可以将其从/data/app复制到存储卡中。虽然您无法浏览该目录,但它包含的文件通常是可读的——尽管这并不保证(而且那也不总是安装位置)。另一种选择可能是不使用权限系统,而是尝试对请求软件包进行自己的身份验证。 - Chris Stratton
谢谢Chris - 我的应用程序需要安装在设备上,否则它将无法正常运行,所以我对用户安装位置几乎没有什么担心。我猜这是你提到的唯一考虑因素吧?另外,由于/data/app是可读的,我可以在任何其他操作之前检查apk是否位于那个位置。根据我的搜索,除非使用root功能,否则我找不到从那个位置传输apk的方法...如果有办法的话,我很想知道...我不确定你所说的“自己的身份验证”是什么意思。谢谢。 - brandall
如果它是可读的(通常情况下是这样),您无需root即可将其复制到允许写入的位置(例如sdcard,具有适当的清单权限)。但是,/data/app并不总是安装的位置。有时在安装过程中apk文件名会更改。您可以从/data/system/packages.xml确定位置和安装名称,但此时您已经深入私有内部功能,这可能不是未来的保障。实际上,重新下载可能是最好的选择-至少将其作为备选项。 - Chris Stratton
1
实际上,应用程序本身可以从/proc/self/maps确定其自己的apk文件/位置,因为它已经打开并映射到内存中作为运行的结果。请注意,我说的是应用程序本身 - 另一个进程(例如adb shell)将看到映射到其自己进程中的内容,而不是您的应用程序的内容。 - Chris Stratton
再次感谢,我会研究你的建议 - 我之前不知道/proc/self/maps。如果我相信Google会在几天内修复它,我就不会在这段时间里那么困扰了 - 但我有一种感觉,我正在寻找一个长期解决方案! - brandall
做好长期解决方案的准备 :) 即使 Google 在几天内修复了这个问题:在您开发的每个 Android 设备上依赖该修复程序之前,可能需要花费约 2 年的时间。我怀疑 Google 不会很快解决您的问题,也许它甚至是按预期工作的(如果他们以不同的方式处理,可能存在安全问题)。 - zapl
1个回答

3
您可以通过Context.getApplicationInfo().sourceDir获取.apk文件路径,并使用该路径启动应用程序安装程序。但是,如果您的应用程序已被锁定(从JB开始所有付费应用程序都无法避免应用程序加密),则这种方法将不起作用,因为其他人无法读取您的应用程序可执行文件。在这种情况下,您需要将.apk文件复制到某个全局可读位置(例如外部存储器),然后从那里安装。
无论您在此处做什么,都会产生一些不可避免的非常负面的后果:
- 从您的应用程序进行任何类型的安装都只能通过侧载UI完成,这对用户来说可能是非常可怕的体验,而且需要用户打开侧载才能继续。 - 以这种方式安装应用程序可能会使其所有权从Play商店中移除(因为它不再是安装它的商店)。这可能意味着用户无法通过商店向您报告崩溃或ANR,或者出现其他负面后果。我不确定实际会发生什么问题,但我真的不会认为这样做会没事。
最终,我强烈建议不要这样做。您需要哪些权限才需要强制执行此操作?出于很多原因,在大多数情况下,我不建议第三方应用程序声明自己的权限,因为在需要这些权限之后才知道这些权限会带来很多不良用户体验。

感谢您的回答。这个问题的一个很好的例子是应用程序Tasker,它需要net.dinglisch.android.tasker.PERMISSION_RUN_TASKS权限。正如您所知,Tasker可以进行一些重要的设备更改,因此开发人员希望将其带给安装我的应用程序的用户的注意。如果我建议我的用户安装Tasker以获得兼容功能,那么我就会遇到这种情况,在我的清单中的权限不被检测到。我不确定是否可以将您的答案标记为“正确”,因为似乎没有解决方案? - brandall

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接