前言:因项目需要,需要对已有的app进行一部分修改,所以花费了一天时间来研究这个东西,在网上查了很多资料,发现大多数都是简单的说明或雷同,所以特此把成果分享下,希望对大家有用。
环境要求 jdk.17 (哪里去下载就不用说了吧)
需要工具 apktool
2.1 这个是Google推出的工具,就只为了针对这种情况,因为apk相当于一个压缩包,可以用压缩工具就可以打开,可能很多人都试过直接用压缩软件打开apk并修改保存,但是最后却不能安装
2.2 下载地址:
2.3 需要下载apktool2.0.2.jar 和apktool-install-windows-r05-ibot.tar.bz2
2.4下载下来之后会发现有三个文件aapt.exe你,apktool.bat,apktool.jar(将前面的apktool2.0.2.jar改名成apktool.jar),然后将这三个文件放到C:\Windows下面
2.5打开doc窗口 输入cmd 进入后输入apktool 就可以看见对应的命令
一个Android app 和对应的签名秘钥文件(可以找Android开发人员要)
3.1将其放入一个文件夹下E:\apkTest
3.2不放心的可以先把这两个文件备份下
Java 代码部分
import java.io.BufferedReader;
import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;/** * @author showlike * @version v1.0 * 2012-6-29 下午12:05:10 */public class Test { public static void main(String args[]) throws IOException{ BufferedReader br =null; OutputStreamWriter osw =null; Process process = null; try { //1----解压 //apktool路径 String newApppath ="E:\\apkTest\\"; //保存路径 String appPath ="E:\\apkTest\\"; // File file =new File(path); String cmd_d="cmd.exe /c apktool d "+appPath+"Taximeter_1.apk -o "+newApppath+"app"; System.out.println(cmd_d); process = Runtime.getRuntime().exec(cmd_d); if(process.waitFor()!=0)System.out.println("解压失败。。。"); //2----内容修改 String targetPath = newApppath+"app\\assets\\presenter.txt"; String content="15926322029"; System.out.println(targetPath); br = new BufferedReader(new InputStreamReader(new FileInputStream(targetPath))); osw = new OutputStreamWriter(new FileOutputStream(targetPath)); osw.write(content,0,content.length()); osw.flush(); //3----打包 process = Runtime.getRuntime().exec("cmd.exe /c apktool b "+newApppath+"app -o "+newApppath+"app.apk"); if(process.waitFor()!=0)System.out.println("打包失败。。。"); //4----签名 (文件名称中不能包含空格) String jdkBinPath="D:\\Program Files\\Java\\jdk1.7.0_79\\bin"; File bin =new File(jdkBinPath);/**
*E:\\apkTest\\taximeter.jks 表示签名的秘钥包
* 54546645 是签名包的密码
*E:\\apkTest\\app.apk 修改原有app并重新打包成app的文件
*E:\\apkTest\\appT.apk 签名后的apk名字和位置
**/
String cmd="cmd.exe /c jarsigner -verbose -keystore E:\\apkTest\\taximeter.jks -storepass 54546645 -keypass 54546645 -signedjar E:\\apkTest\\appT.apk -digestalg SHA1 -sigalg MD5withRSA E:\\apkTest\\app.apk taximeter"; process = Runtime.getRuntime().exec(cmd,null,bin); //Runtime.getRuntime().exec执行的时候有时候会阻塞了,就是你运行了但一直不结束,所以就增加下面的功能来处理 StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), "ERROR"); // kick off stderr errorGobbler.start(); StreamGobbler outGobbler = new StreamGobbler(process.getInputStream(), "STDOUT"); // kick off stdout outGobbler.start(); // process=Runtime.getRuntime().exec(cmdArray); if(process.waitFor()!=0)System.out.println("签名失败。。。"); }catch (Exception e) { e.printStackTrace(); }finally{ br.close(); osw.close(); System.out.println("结束。。。"); } }}
import java.io.BufferedReader;
import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; /** * 用于处理Runtime.getRuntime().exec产生的错误流及输出流 * @author ybqin * */ public class StreamGobbler extends Thread { InputStream is; String type; OutputStream os; StreamGobbler(InputStream is, String type) { this(is, type, null); } StreamGobbler(InputStream is, String type, OutputStream redirect) { this.is = is; this.type = type; this.os = redirect; } public void run() { try { InputStreamReader isr = null; BufferedReader br = null; PrintWriter pw = null; try { if (os != null) pw = new PrintWriter(os); isr = new InputStreamReader(is); br = new BufferedReader(isr); String line=null; while ( (line = br.readLine()) != null) { if (pw != null) pw.println(line); System.out.println(type + ">" + line); } if (pw != null) pw.flush(); } catch (IOException ioe) { ioe.printStackTrace(); } finally{ pw.close(); br.close(); isr.close(); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }以上功能希望对大家有用,谢谢