本人博客原文:http://hubingforever.blog.163.com/blog/static/1710405792013102954345842/

以下是对一个已经打包的Android应用程序的apk文件根据渠道号再进行批量打包的程序示例。 config.bat文件 set outDir=out set rawDatadir=temp set apk=S ignatureChecker.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文件 请参考《 Android反编译工具简介》 robin.keystore文件的制作 请参考《 Android应用程序签名简介 》 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>

结束!

更多相关文章

  1. Python3原生编写月份计算工具
  2. 一款常用的 Squid 日志分析工具
  3. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  4. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  5. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  6. Spring For Android初体验
  7. 还在用递归删除文件夹及里面的文件吗?android下一行命令搞定!
  8. Android(安卓)SDK无法更新问题解决
  9. 一些资料,binder,content provider

随机推荐

  1. JavaScript 高阶函数快速入门 [每日前端
  2. 分享十张表的数据!大家一起玩!
  3. 2019年 Vue.js 报告中的亮点 [每日前端夜
  4. 用python重新定义【2019十大网络流行语】
  5. 用 Node.js 写一个多人游戏服务器引擎 [
  6. 三十天写三十个网站后,我学到的东西[每日
  7. 14个最好的 JavaScript 数据可视化库[每
  8. deno如何偿还Node.js的十大技术债 [每日
  9. 11个最好的JavaScript动态效果库[每日前
  10. React教程:组件,Hooks和性能 [每日前端夜话