做一個測試工具時,需要將被測應用重新簽名。re-sign.jar用順手了,想在代碼中也調用它來進行重簽名工作,但轉念一想幹嘛不在代碼裏把它實現了呢?
re-sign.jar工具可以將一個apk文件重簽名,使用的是android自帶的debug簽名,也就是你在eclipse裏build後在bin目錄生成的apk文件的簽名。
下面是它的實現原理,非常簡單,就是下面兩個命令:
D:\java\jdk1.6.0_43/bin/jarsigner(jarsigner工具,在JDK的bin目錄下) -sigalg MD5withRSA -digestalg SHA1 -keystore C:\Users\zhuming/.android/debug.keystore(android的debug.keystore路徑) -storepass android -keypass android -signedjar C:/Users/zhuming/Desktop/temp.apk(重簽名後生成的臨時文件,不是最終文件)
C:/Users/zhuming/Desktop/source_debug.apk(要簽名的apk文件路徑) androiddebugkey
這個命令完成了重簽名的操作。
D:\android\sdk\build-tools\19.1.0/zipalign(zipalign工具,在android SDK的build-tools目錄下) -f 4 C:/Users/zhuming/Desktop/temp.apk(剛纔生成的臨時文件路徑) C:/Users/zhuming/Desktop/source_debug.apk(目標文件路徑)
這個命令對重簽名後的包進行了優化,即對資源文件做了“對齊”處理,詳參點擊打開鏈接。
瞭解了這些,再想在代碼中執行重簽名操作,就非常簡單了(下面是我的代碼,注意使用前需要配置JAVA_HOME和ANDROID_HOME)。
public static boolean debugSignApk(String sourcePath){
if (sourcePath == null) {
return false;
}
String temp[] = sourcePath.replaceAll("\\\\","/").split("/");
String name=sourcePath;
if (temp.length > 1) {
name = temp[temp.length - 1];
}
name=name.split("_unsigned")[0]+"_debug.apk";
JDK_JARSIGNER="jarsigner";
String sign_cmd = JDK_JARSIGNER+" -sigalg MD5withRSA -digestalg SHA1 -keystore "+
ANDROID_KEYSTORE+" -storepass android -keypass android -signedjar "+"./temp.apk "+"./"+sourcePath+" androiddebugkey";
String zip_cmd="zipalign -f 4 "+"./temp.apk "+name;
try {
Process process = Runtime.getRuntime().exec(sign_cmd);
if (process != null) {
InputStream inputStream = process.getErrorStream();
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(reader);
String line = null;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
reader.close();
inputStream.close();
process.destroy();
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
try {
Process process = Runtime.getRuntime().exec(zip_cmd);
if (process != null) {
InputStream inputStream = process.getErrorStream();
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(reader);
String line = null;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
reader.close();
inputStream.close();
process.destroy();
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
如果不想用debug簽名,而想使用自定義簽名怎麼辦呢?見下一篇文章吧。