前言:因項目需要,需要對已有的app進行一部分修改,所以花費了一天時間來研究這個東西,在網上查了很多資料,發現大多數都是簡單的說明或雷同,所以特此把成果分享下,希望對大家有用。
環境要求 jdk.17 (哪裏去下載就不用說了吧)
需要工具 apktool
2.1 這個是Google推出的工具,就只爲了針對這種情況,因爲apk相當於一個壓縮包,可以用壓縮工具就可以打開,可能很多人都試過直接用壓縮軟件打開apk並修改保存,但是最後卻不能安裝
2.2 下載地址:http://www.softpedia.com/get/Programming/Debuggers-Decompilers-Dissasemblers/ApkTool.shtml
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();
}
}
}
以上功能希望對大家有用,謝謝