升级打包工具packer-ng-plugin支持V3签名
该库github:https://github.com/mcxiaoke/packer-ng-plugin
升级后jar包下载地址: https://download.youkuaiyun.com/download/liuyu0915/11200365
前言:
打包工具packer-ng-plugin生成多渠道包的核心代码是集成美团多渠道打包工具。美团已经升级了打包工具,支持将V3签名后的包生成多渠道包,而packer-ng-plugin工具并没有更新集成美团打包工具的代码。
造成影响:使用v3签名的apk,再用该库创建渠道包,不能安装在安卓9.0及以上系统上。这是因为安卓9.0及以上系统首先校验V3签名,生成的渠道包带有V3签名,但该库并不支持将V3签名的apk包生成渠道包,所以不能安装在9.0及以上系统上。不过,由v3签名的apk生成的渠道包是可以安装在9.0以下系统上的。这是因为9.0以下系统不会校验V3签名。
解决办法
方法一:使用V2签名的apk创建渠道包。 这样生成的渠道包没有了V3签名,就不会影响该库写入和读取渠道信息,9.0及以上系统在未发现V3签名时自动去校验V2签名。
方法二:升级该库(packer-ng-plugin),使其支持v3签名。将美团读取和写入渠道的代码移值过来即可。
测试结果如下:
注:360加固未使用它默认勾选的“自动签名功能”和“签名校验”功能。下面测试的顺序是release包加固再签名,再生成渠道包。最后安装至8.0和9.0系统上。
源文件 | 360加固 | 签名工具 | 是否是渠道包 | 签名验证 | 安装状况 | 提示信息 | ||
build-tools25.0.0 | build-tools28.0.3 | 8.0系统 | 9.0系统 | |||||
release安装包 | 否 | 是 | 否 | 通过 | 正常安装 | 正常安装 | ||
release安装包 | 否 | 是 | 是 | 通过 | 正常安装 | 不能安装 | 1号信息 | |
release安装包 | 是 | 否 | 否 | 否 | 否 | 不能安装 | 不能安装 | 2号信息 |
release安装包 | 是 | 是 | 否 | 通过 | 正常安装 | 可以安装 | ||
release安装包 | 是 | 是 | 是 | 通过 | 正常安装 | 不能安装 | 1号信息 | |
release安装包 | 是 | 是 | 是 | 通过 | 正常安装 | 正常安装 | ||
1号信息:安卓9.0系统安装时提示签名不一致。这是因为apk使用了V3签名,在安卓9.0及以上系统校验V3签名时不通过。 | ||||||||
2号信息:只加固不能安装。验证签名失败,未发现签名文件 |
结论:
1.360加固会破坏签名文件,加固后需要重新签名(未使用360自带的自动签名功能,建议不用360签名)。
2.V3签名的包可以在任何手机上安装,但通过该库生成的渠道包不能安装在9.0及以上系统上。
备注:
1.V3签名就是使用buildTools28.0.0及以版本进行签名的。如果使用V2签名可以使用25 26 27等版本的buildtools进行签名。
2.无论是v3还是v2签名的release包,都可以安装在任何系统上。如上不能安装在9.0及以上系统的故障是因为使用v3签名的apk,再用该库创建渠道包,渠道包不能安装。
升级打包工具packer-ng-plugin
具体步骤:
步骤一:将packer-ng-plugin下库并导入工程
下载地址: https://github.com/mcxiaoke/packer-ng-plugin
步骤二:修改该库写入渠道信息的模块 ,并生成jar包。
2.1依赖payload_writer库,并在packer-ng-plugin库中的Bridege类中修改如下。
2.2生成新的jar包。
该库创建的task。执行cli>Tasks>other>distJar .执行后项目根目录下面tools文件夹下的packer-ng-2.0.1.jar已经得到更新。
打开jar包可以看到代码已经更新。
步骤三:修改该库读取渠道信息的模块,生成jar包导入安卓工程。
3.1 将安卓项目中依赖读取渠道信息的库导入到本地,再进行修改读取渠道信息的那部分。同上述一样。
也可以将美团payload_reader模块打成jar包,通过ChannelReader来读取渠道信息。代码如下。
在安卓项目中调用下面getChannel(Context context)方法即可。
public static String getChannel(final File file) {
try {
ChannelInfo channelInfo = ChannelReader.get(file);
if (channelInfo != null) {
String channel = channelInfo.getChannel();
return channel;
}
return EMPTY_STRING;
} catch (Exception e) {
return EMPTY_STRING;
}
}
public static String getChannel(final Context context) {
try {
return getChannelOrThrow(context);
} catch (Exception e) {
return EMPTY_STRING;
}
}
public static synchronized String getChannelOrThrow(final Context context)
throws IOException {
final ApplicationInfo info = context.getApplicationInfo();
File file = new File(info.sourceDir);
return getChannel(file);
}