在早期的 ARCore sdk 中,设备检查是在 arcore_client.aar 中的 SupportedDevices.class,方法可以参考这里
我使用的是 1.1.0 版本,发现里面的变化很大,找不到 SupportedDevices 这个类了,于是看了半天里面的代码,发现设备校验是通过底层 so 库做的,并且 sdk 里的 so 又调用了 ARCore 里的 so,很复杂,致使上面的反射方法失效
但是还不甘心,在把 ARCore sdk 捋了一遍后,我又把 ARCore apk 解压反编译了,看了一下大致的代码,然后在 apk 的 assets 目录发现了一个叫 device_profile_database 的目录,赫然发现里面记录的是一个个设备信息,在里面发现了 device_profile_OnePlus5_slash_OnePlus5_colon_7.proto 和 device_profile_OnePlus5_slash_OnePlus5_colon_8.proto 两个文件,用对比工具看了一下,内容完全一样,我觉得 一加 5 和 5t 硬件差别应该不大,所以思路就有了,把这两个文件分别拷贝一份,把设备型号 改成 5T,然后重新打包安装
安装后 ARCore apk 后,运行官方 demo 提示的信息变了,之前提示的是 "设备不支持" ,修改过后,提示 "创建 session 失败" ,查看 logcat 发现一个错误信息:签名校验失败,到这里,我觉得有戏,可以再搞一搞,错误信息是 native 报出来的,但是我发现,检查签名其实是 java 层做的,在 SessionCreateJniHelper 的 checkApkSignature() 函数里
@UsedByNative("session_create.cc")
static boolean checkApkSignature(Context var0) throws NameNotFoundException {
PackageInfo var1;
try {
var1 = var0.getPackageManager().getPackageInfo("com.google.ar.core", 64);
} catch (NameNotFoundException var9) {
return true;
}
// xxx 是很长的 签名值,这里省略了
Signature var2 = new Signature("xxx");
Signature[] var3 = var1.signatures;
int var4 = var1.signatures.length;
for(int var5 = 0; var5 < var4; ++var5) {
Signature var6;
if ((var6 = var3[var5]).equals(var2)) {
return true;
}
String var7 = var2.toCharsString();
String var8 = var6.toCharsString();
Log.w("ARCore-SessionCreateJniHelper", (new StringBuilder(39 + String.valueOf(var7).length() + String.valueOf(var8).length())).append("Signature mismatch. Expected '").append(var7).append("' got '").append(var8).append("'").toString());
}
// 这里是重点
return var0.getPackageManager().getApplicationInfo(var0.getPackageName(), 128).metaData.getBoolean("com.google.ar.core.disable_security_check", false);
}
代码的最后一行是重点,即只要在 demo 工程的 AndroidManifest.xml 中的 application 节点内添加如下内容即可跳过签名检查
<!-- 跳过 SessionCreateJniHelper 签名检查 -->
<meta-data
android:name="com.google.ar.core.disable_security_check"
android:value="true" />
然后重新运行 demo 就顺利跑起来了
下面是运行图
白天刚搞完这个,晚上 Google I/O 大会就发布了 ARCore 1.2 ,然后第二天试了上面的方法依然有效,ARCore 1.2 增加了 一加 3T 和 6 但是就是没有 5T 很郁闷
ARCore 1.2 sdk 相对于 1.1 的变化:增加了 Augmented Image 相关 api,并且做了代码混淆
以上