友盟渠道号的问题

需求:需要给个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]
    }
 productFlavors {
        baidu{}}
这个要加在android{}内
在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的名字
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  点击打开链接包含工具

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
友盟渠道打包工具主要是提供基本的通过工程源码打包的功能。 常见错误见这里目前不支持的Apk特性见这里(可能会导致发布的SDK产生严重bug)。 Google 现在已经发布了最新的构建系统(New Building System) , 在 Android Studio 中已经支持了最新的 构建系统,如果开发者已经迁移,可以使用新的系统方面的生成渠道包,这是取代渠道打包工具的最佳方式。 1. 工程结构 工程结构图 : - CommonTools 共用的工具类,包括对 `Apktool` , `Jarsigner` , `zipalign` 的封装 - UIControls_35   共用的UI类,对大部分控件的样式都是在这里设置的 - UmengMarket  Marekt 组件,现在还没有实现 - UmengPackage 打包组件 - UmengTools 工程主要UI,管理 UmengMarket, UmengPackage, UmengTools 三个组件 - UmengWidget 小工具组件,目前仅有解包分析的功能 打包工具组件: - Source - Builder - ApkBuilder.cs     通过 APK 打包的 Builder 实现                    - Builder.cs            抽象 Builder 类,提供打包的主要逻辑                    - SourceBuilder.cs通过源码打包的 Builder 实现 (目前代码还没有实现)          - Worker.cs 打包过程对外接口 3. 打包流程 V2.0 版本仅实现了通过 .apk 打包的方式,本质上对  apk 文件进行反编译,修改 AndroidManifest.xml 文件后,再重新打包,我们使用的工具是开源的拆包工具 Apktool 将  apktool  添加到当前 process 的环境变量 执行 apktool d --no-src -f xxxx.apk temp 拆解apk 替换或者添加 AndroidManifest.xml 中的 友盟channel 执行apktool b temp  unsigned.apk 重新打包apk 执行 SignApk.jar 生成签名后的 apk 文件 执行 zipAlign 生成对齐优化后的 apk 文件 回到 3 替换新的渠道 完成打包 使用  JarSigner.jar 给 Apk 签名, SignApk.jar  文件是我们修改过的 apk 签名工具,实现了和 ADT 中一样的签名方式,使用如下: Usage: signapk file.{keystore} keystore_password key_entry key_password input.apk output.apk
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值