来源:http://hubingforever.blog.163.com/blog/static/1710405792013102954345842/

 

以下是对一个已经打包的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
 

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;
 
publicclassAndroidManifestModifier{
 
    /**
     * @param args
     */
    publicstaticvoid 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);
 
    }
    publicstaticvoid change(String srcfilePath,String outFilePath,String metaDataName,String metaDataNewValue){
        File f =newFile(srcfilePath);
        DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
        DocumentBuilder builder =null;
        finalString 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();
        }
 
    }
 
    privatestaticvoid writeXMLFile(Document doc,String outfile){
 
        try{
            FileOutputStream fos =newFileOutputStream(outfile);
            OutputStreamWriter outwriter =newOutputStreamWriter(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"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lenovo.robin"
    android:versionCode="1"
    android:versionName="1.0">
 
    <uses-sdkandroid: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>
                <actionandroid:name="android.intent.action.MAIN"/>
 
                <categoryandroid:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity
            android:name=".SignatureDetailActivity"
            android:label="@string/app_name">
        </activity>
    </application> 
</manifest>
posted on 2014-03-20 20:20  随我畅翔  阅读(269)  评论(0编辑  收藏  举报