Android16 EDLA【GTS】GtsUnofficialApisUsageTestCases存在fail项
文章目录
- [Android16 EDLA【GTS】GtsUnofficialApisUsageTestCases存在fail项](#Android16 EDLA【GTS】GtsUnofficialApisUsageTestCases存在fail项)
-
- 一、前言
- 二、分析解决
-
- 1、查看报错
- 2、报错分析:
- 3、报错解决:
- [✅ 方案一:【最优治本】替换为「Android 官方公开标准 API」【强烈推荐,无合规风险】](#✅ 方案一:【最优治本】替换为「Android 官方公开标准 API」【强烈推荐,无合规风险】)
- [✅ 方案二:【行业通用】将私有 API 加入「GTS 私有 API 白名单 / 豁免名单」【推荐,治标治本,无功能改动】](#✅ 方案二:【行业通用】将私有 API 加入「GTS 私有 API 白名单 / 豁免名单」【推荐,治标治本,无功能改动】)
- [✅ 方案三:【兜底方案】反射调用该私有 API【应急兜底,无 GTS 扫描风险】](#✅ 方案三:【兜底方案】反射调用该私有 API【应急兜底,无 GTS 扫描风险】)
- 三、其他
一、前言
Android EDLA 认证中CTS报错项是最大的,这个是 Android 兼容性测试,验证 API 符合性和系统功能完整性 ;
GTS没有那么多, GTS主要是Google 服务测试,确保 GMS(Play 商店、Drive 等)正常运行 ;
本文主要介绍测试模块GtsUnofficialApisUsageTestCases的其中一个报错。
二、分析解决
1、查看报错

上面的报错主要描述是 vendor/framework/droidlogic.tv.software.core.jar中不允许类别SkgSourceManager的类的调用。
2、报错分析:
Android GTS 合规测试的核心校验失败,这个报错的本质一句话总结:
你的系统模块
/vendor/framework/droidlogic.tv.software.core.jar中,硬编码直接引用了「非公开的私有内部 API」 →com.skg.services.manager.SkgSourceManager这个类及其成员方法,而 GTS 的testNonApiReferences测试项的核心职责就是:扫描并禁止所有 APP / 系统模块调用「未声明为公共 API」的私有 / 内部 / 厂商定制 API,所有这类引用都会被判定为违规并抛出该断言错误。
查看了vendor里面调用了SkgSourceManager 的代码,主要是定制化的情况获取自定义和设置信源的源码。
3、报错解决:
✅ 方案一:【最优治本】替换为「Android 官方公开标准 API」【强烈推荐,无合规风险】
这是唯一无风险、完全符合 GTS 合规要求的完美方案,也是 Google 官方期望的修复方式。
但是这个定制化的系统下,有些信源情况并不是官方一致的,所以不采用该方法。
✅ 方案二:【行业通用】将私有 API 加入「GTS 私有 API 白名单 / 豁免名单」【推荐,治标治本,无功能改动】
这是Android 厂商定制开发中最常用的合规方案 ,适用于:你无法替换为官方 API(比如SkgSourceManager包含厂商定制的信号源逻辑、官方 API 无法覆盖),必须保留该私有 API 调用的场景。
豁免更麻烦,所以不采用该方法。
✅ 方案三:【兜底方案】反射调用该私有 API【应急兜底,无 GTS 扫描风险】
适用于:你既无法改白名单,又无法替换官方 API,且不能禁用测试项的极端场景。
反射调用既不影响功能,又可以规避GTS扫描,所以目前是使用该方法解决的问题。
修改的代码参考:
//原代码:
//SkgSourceManager.getInstance().getCurrentSource());
修改成反射调用 :getCurrentSource()
// skg ,【GTS】GtsUnofficialApisUsageTestCases存在fail项, tv framework 不能直接调用SkgManager的私有接口,可以反射规避
private final String CLASS_NAME = "com.skg.services.manager.SkgSourceManager";
// 反射替代 getInstance()
public Object getSkgSourceManager() {
Object sInstance = null;
try {
Class<?> clazz = Class.forName(CLASS_NAME);
Method getInstance = clazz.getDeclaredMethod("getInstance");
getInstance.setAccessible(true);
sInstance = getInstance.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
return sInstance;
}
// 反射替代 getCurrentSource()int
public int getCurrentSource() {
try {
Object manager = getSkgSourceManager();
Class<?> clazz = Class.forName(CLASS_NAME);
Method method = clazz.getDeclaredMethod("getCurrentSource");
method.setAccessible(true);
return (int) method.invoke(manager);
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
// 反射替代 setSource(int)boolean
public boolean setSource(int source) {
try {
Object manager = getSkgSourceManager();
Class<?> clazz = Class.forName(CLASS_NAME);
Method method = clazz.getDeclaredMethod("setSource", int.class);
method.setAccessible(true);
return (boolean) method.invoke(manager, source);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
具体的反射代码,现在都是一键ai生成了,基本没啥问题,不用自己一个个慢慢写了。
这里只列举了GtsUnofficialApisUsageTestCases报错其中一个情况,其他情况也是可以参考修改。
该项报错看起来也是CTS的合规问题,但是不知道为啥会在GTS里面报错,估计和系统源码在vendor目录有关吧。
三、其他
1、小结
GtsUnofficialApisUsageTestCases 报错一般是因为扫描并禁止所有 APP / 系统模块调用「未声明为公共 API」的私有 / 内部 / 厂商定制 API;
如果出现了这种报错,要么就是替换私有的api解决;要么就是反射调用私有的api规避扫描。
2、EDLA认证测试内容
主要认证测试的主要内容除了: CTS、GTS、VTS ,还有一些其他的。
https://blog.csdn.net/wenzhi20102321/article/details/155618324