需求:需要给个apk模板,然后用操作工具,打包对应的友盟渠道包
1、友盟多渠道打包
1)、在maniest.xml加入
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
2)、在gradle文件中加入
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
productFlavors {
baidu{}}
这个要加在android{}内
baidu{}}
在buildTypes{}中的release中加入
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name
.endsWith('.apk')) {
// 输出apk名称为
def fileName = "输出名_${variant.productFlavors[0].name}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
控制apk输出目录以及apk的名字
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name
.endsWith('.apk')) {
// 输出apk名称为
def fileName = "输出名_${variant.productFlavors[0].name}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
2、最初的思路是用7zip把apk解压,然后通过工具来查找maniest.xml文件中的
android:name="UMENG_CHANNEL"并将其值替换,发现<meta-data/>节点不唯一,然后想着在string.xml引用渠道的值,打包以及反编译再次打包,获得的渠道号为null,这里这么操作为啥获取不到友盟的channel,我也不太清楚;此路不通,想着友盟最开始初始化的
UMConfigure.init(context,null, context.getString(),UMConfigure.DEVICE_TYPE_PHONE,null);用string.xml引用来解决,但是用apktool翻编译,再次打包之后仍然获取不到渠道,最后无意之间在网上看到美团打包,一分钟打900个包,
3、美团打包,用Python进行二次打包以及一个java工具类获取渠道号
1)、java工具类
public class ChannelUtil {
private static final String CHANNEL_KEY = "cztchannel";
private static final String CHANNEL_VERSION_KEY = "czt_channel_version";
private static String mChannel;
/**
* 返回市场。 如果获取失败返回""
* @param context 上下文
* @return 渠道号
*/
public static String getChannel(Context context){
return getChannel(context, "");
}
/**
* 返回市场。 如果获取失败返回defaultChannel
* @param context 上下文
* @param defaultChannel 默认的渠道号
* @return 渠道号
*/
public static String getChannel(Context context, String defaultChannel) {
//内存中获取
if(!TextUtils.isEmpty(mChannel)){
return mChannel;
}
//sp中获取
mChannel = getChannelBySharedPreferences(context);
if(!TextUtils.isEmpty(mChannel)){
return mChannel;
}
//从apk中获取
mChannel = getChannelFromApk(context, CHANNEL_KEY);
if(!TextUtils.isEmpty(mChannel)){
//保存sp中备用
saveChannelBySharedPreferences(context, mChannel);
return mChannel;
}
//全部获取失败
return defaultChannel;
}
/**
* 从apk中获取版本信息
* @param context 上下文
* @param channelKey 渠道关键字
* @return 对应的渠道号
*/
private static String getChannelFromApk(Context context, String channelKey) {
//从apk包中获取
ApplicationInfo appInfo = context.getApplicationInfo();
String sourceDir = appInfo.sourceDir; //获取apk安装路径
//默认放在meta-inf/里, 所以需要再拼接一下
String key = "META-INF/" + channelKey;
String ret = "";
ZipFile zipfile = null;
try {
zipfile = new ZipFile(sourceDir); //打开指定的zip文件(sourceDir的路径是安装包所在的路径)
Enumeration<?> entries = zipfile.entries(); //返回zip文件条目的枚举
while (entries.hasMoreElements()) { //判断枚举是否还有更多的元素
ZipEntry entry = ((ZipEntry) entries.nextElement()); //返回此枚举的下一个zip文件条目
String entryName = entry.getName(); //返回zip文件的路径名
if (entryName.startsWith(key)) {
ret = entryName;
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (zipfile != null) {
try {
zipfile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
String[] split = ret.split("_");
String channel = "";
//split != null && split.length >= 2默认ret=“”,截取ret.split("_")会有默认一个长度的数组
if (split.length >= 2) {
channel = ret.substring(split[0].length() + 1);
}
return channel;
}
/**
* 本地保存channel & 对应版本号
* @param context 上下文
* @param channel 渠道号
*/
private static void saveChannelBySharedPreferences(Context context, String channel){
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = sp.edit();
editor.putString(CHANNEL_KEY, channel);
editor.putString(CHANNEL_VERSION_KEY, getVersionCode(context));
editor.apply();
}
/**
* 从sp中获取channel
* @param context 上下文
* @return 为空表示获取异常、sp中的值已经失效、sp中没有此值
*/
private static String getChannelBySharedPreferences(Context context){
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
String currentVersionCode = getVersionCode(context);
if(TextUtils.isEmpty(currentVersionCode)){
//获取错误
return "";
}
String versionCodeSaved = sp.getString(CHANNEL_VERSION_KEY, "");
if(TextUtils.isEmpty(versionCodeSaved)){
//本地没有存储的channel对应的版本号
//第一次使用 或者 原先存储版本号异常
return "";
}
if(!currentVersionCode.equals(versionCodeSaved)){
return "";
}
return sp.getString(CHANNEL_KEY, "");
}
/**
* 从包信息中获取版本号
* @param context 上下文
* @return 返回当前的版本名
*/
private static String getVersionCode(Context context){
try{
return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
}catch(NameNotFoundException e) {
e.printStackTrace();
}
return "";
}
2)、python.exe文件可以去官网下载
https://www.python.org/downloads/或者http://download.csdn.net/download/hujiaxi222/10196673
打包工具下载http://download.csdn.net/download/hujiaxi222/10196658
3)、操作,将apk放入工具类中,双击文件后缀名是.py文件,就能看到对应的渠道apk,至于修改渠道号去
Info文件夹中的channel.txt文件操作,一个渠道号占一行
文章转载自这个链接http://blog.csdn.net/u012390044/article/details/50585792
点击打开链接包含工具