注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

民主与科学

独立之人格,自由之思想

 
 
 

日志

 
 

Android快速批量打渠道包(AndroidManifestModifier)  

2013-11-29 17:52:43|  分类: Android其他 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
以下是对一个已经打包的Android应用程序的apk文件根据渠道号再进行批量打包的程序示例。
config.bat文件
set outDir=out
set rawDatadir=temp
set apk=SignatureChecker.apk
set channelName=A;B
set channelNo=1;2;3;4
set projectName=r
set versionCode=100
set stamp=%Date:~0,4%%Date:~5,2%%Date:~8,2%%Time:~0,2%%Time:~3,2%%Time:~6,2%
echo %stamp%_
build.bat文件
@echo off
call config.bat
Setlocal enabledelayedexpansion
set path=%path%;%cd%\lib

if exist %rawDatadir% (
 call deleteDir %rawDatadir%
)
if not exist %outDir% (
 md %outDir%
)
call apktool d -s %apk% %rawDatadir%
Setlocal enabledelayedexpansion
set /a cnt=0
for %%i in (%channelName%) do (
  set name=%%i
  set apkName=%projectName%_%versionCode%_!name!.apk
  call getSubStr "%channelNo%" !cnt!
  set no=!getSubStr~result!
  set /a cnt+=1
  java AndroidManifestModifier %rawDatadir%\AndroidManifest.xml %rawDatadir%\AndroidManifest.xml lenovo:channel !no!

  call apktool b %rawDatadir%  !apkName!
  jarsigner -keystore robin.keystore -storepass GL2009 -keypass gl2009  !apkName! robin
  move !apkName! %outDir%
)
endlocal
关于apktool请参考《Android反编译工具简介》,另外jarsigner就是JDK下载的一个工具。
AndroidManifestModifier主要用于在对Android应用程序进行打包发布是修改渠道号。
AndroidManifestModifier.java文件


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class AndroidManifestModifier {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String srcFilePath="AndroidManifest.xml";
        String outFilePath="AndroidManifest.xml";
        String metaDataName="youmi:channel";
        String metaDataNewValue="newValue"+System.currentTimeMillis()%1000;
        if(args!=null&&args.length>=4){
            srcFilePath=args[0];
            outFilePath=args[1];
            metaDataName=args[2];
            metaDataNewValue=args[3];
        }
        change(srcFilePath,outFilePath,metaDataName,metaDataNewValue);

    }
    public static void change(String srcfilePath,String outFilePath,String metaDataName,String metaDataNewValue) {
        File f = new File(srcfilePath);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = null;
        final String android_value="android:value";
        try {
            builder = factory.newDocumentBuilder();
            Document doc = builder.parse(f);
            NodeList nl = doc.getElementsByTagName("meta-data");
            int len = nl.getLength();
            org.w3c.dom.Node channelNode = null;
            for (int i = 0; i < len; i++) {
                org.w3c.dom.Node n = nl.item(i);
                System.out.println(n.getNodeName());
                NamedNodeMap nm = n.getAttributes();
                boolean c=false;
                for (int j = 0; j < nm.getLength(); j++) {
                    org.w3c.dom.Node n2 = nm.item(j);
                    System.out.println(n2.getNodeName() + "|" + n2.getNodeValue());
                    if (metaDataName.equals(n2.getNodeValue()))
                     {
                        c=true;
                        break;
                    }
                }
                if(c){
                    for (int j = 0; j < nm.getLength(); j++) {
                        org.w3c.dom.Node n2 = nm.item(j);
                        if (android_value.equals(n2.getNodeName())) {
                            channelNode=n2;
                            break;
                        }
                    }
                }
            }
            if (channelNode != null) {
                channelNode.setNodeValue(metaDataNewValue);
                writeXMLFile(doc, outFilePath);
            }
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    private static void writeXMLFile(Document doc, String outfile) {

        try {
            FileOutputStream fos = new FileOutputStream(outfile);
            OutputStreamWriter outwriter = new OutputStreamWriter(fos);
            writeXmlFile(doc, outwriter, "utf-8");
            outwriter.close();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 写入xml文件
    public static void writeXmlFile(Document doc, Writer w, String encoding) {
        try {
            Source source = new DOMSource(doc);
            Result result = new StreamResult(w);
            Transformer xformer = TransformerFactory.newInstance().newTransformer();
            xformer.setOutputProperty(OutputKeys.ENCODING, encoding);
            xformer.transform(source, result);
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }
}

getSubStr.bat文件
参考《getSubStr
deleteDir.bat文件
参考《deleteDir
apktool.bat文件
robin.keystore文件的制作
android应用程序的AndroidManifest.xml文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lenovo.robin"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
                <meta-data
            android:name="youmi:channel"
            android:value="88888" />
        <activity
            android:name=".SignatureCheckerActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".SignatureDetailActivity"
            android:label="@string/app_name" >
        </activity>
    </application>

</manifest>

结束!
  评论这张
 
阅读(1781)| 评论(3)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017