最近拿了同事的 OPPO A5 过来测试,发现直接用『Android Studio』的「Run 'app'」不能够把应用安装到手机上,系统的应用包安装程序会显示「安装失败」:

安装失败

『Android Studio』底部的「Run」选项卡会提示以下信息:

Installation did not succeed.
The application could not be installed: INSTALL_FAILED_TEST_ONLY
Installation failed due to: 'null'

翻阅官方文档后发现如下信息:

android:testOnly

Indicates whether this application is only for testing purposes. For example, it may expose functionality or data outside of itself that would cause a security hole, but is useful for testing. This kind of APK can be installed only through adb — you cannot publish it to Google Play.

Android Studio automatically adds this attribute when you click Run.

指示此应用是否仅用于测试目的。例如,它可能会在自身之外公开功能或数据,这样会导致安全漏洞,但对测试很有用。此类 APK 只能通过 adb 安装,您不能将其发布到 Google Play。

当您点击 Run 图标 时,Android Studio 会自动添加此属性。

可以看到,当 Run 程序后,『Android Studio』会自动在 Debug APK 的 AndroidManifest 中添加 android:testOnly="true" 属性,部分手机检测到该属性后会拒绝安装。

但是通过「Build」→「Build Bundles(s) / APK(s)」→「Build APK(s)」生成的 Debug APK 却不会有这种情况。

据网上大量文章讲述,这是『Android Studio』3.0 后的版本会出现的情况,关于这点我在官方文档没有找到具体说明,无从考证。

既然如此,那我强制把这个属性写成 false 不就可以了吗:

<application 
    ...
    android:testOnly="false">
    ...
</application>

结果却发现,依然无法正常安装。

网上提到,可以使用 ADB 命令来安装:

➜   adb install -t app-debug.apk

很多博主都说这个方法可以,但我测试发现不行,不知是否为个例。

最终方法,在「gradle.properties」文件中加入如下代码:

android.injected.testOnly=false

问题得以解决。

后来我换过不同的电脑和项目后发现,有时候该设置未必会生效,反编译 APK 文件看到 android:testOnly 属性仍未被移除,于是顺手写了个脚本来实现该操作并重新打包,流程可以参考之前的『Android 反编译入门指南』。

在调试应用这一块,以我目前测试过的手机来说,OPPO 和 vivo 可以称之为重灾区,vivo 的情况甚至比 OPPO 更加严重,据说还有联系客服开通调试权限等等的骚操作,实属无语。