###前言
之前写过一篇博客Android开发必备技能——修改debug签名,感觉对不习惯使用Linux命令的小伙伴而言,简直是噩梦。因此奉上简单实用的Java代码。
###关于命令
这里关于keystore主要使用四个命令:
- 显示签名文件信息
- 修改签名文件密码
- 修改别名
- 修改别名密码
在Java中表示如下:
private final String SHOW_COMMAND = "keytool -list -v -keystore %s -storepass %s";// 显示签名文件信息摘要
private final String STOREPASSWD_COMMAND = "keytool -storepasswd -keystore %s -storepass %s -new %s";// 修改签名文件密码
private final String CHANGEALIAS_COMMAND = "keytool -changealias -keystore %s -alias %s -destalias %s -storepass %s -keypass %s";// 修改别名
private final String KEYPASSWD_COMMAND = "keytool -keypasswd -keystore %s -storepass %s -alias %s -keypass %s -new %s";// 修改别名密码
%s是占位符,在后续的操作中,一次输入争取的信息,如:keystore 路径、keystore 密码、keystore 别名、keystore 别名密码。
###关于操作
提供alert方法,修改成默认的签名文件(eclipse能够识别),和修改成指定的签名文件
/**
* 修改生成默认签名文件
*
* @date 2016年5月8日 下午10:34:03
*/
public void alert() {
alert("android", "androiddebugkey", "android");
}
/**
* 修改生成指定签名文件
*
* @date 2016年5月15日 下午6:13:14
* @param newStorePass
* @param newAlias
* @param newKeypass
*/
public void alert(String newStorePass, String newAlias, String newKeypass) {
try {
createTempKeystore();
changeStorepass(storepass, newStorePass);
changeAlias(keyAlias, newAlias, newStorePass, keypasswd);
changeKeypass(newStorePass, newAlias, keypasswd, newKeypass);
restoreKeystore();
} catch (Exception e) {
System.out.println(e.toString());
// 修改失败,还原
removeTempKeystore();
}
}
###捕获执行时错误异常
Process提供错误输入流实例,通过判断错误输入流实例中有没有数据进而判断执行命令时,有没有发生错误。例如在这里,输入错误的keypass 就会导致第三步命令执行失败。
/**
* 判断Process执行时,是否发生异常
*
* @date 2016年5月15日 下午9:59:36
* @param process
* @return
*/
private boolean checkProcessError(Process process) {
try {
InputStream errorStream = process.getErrorStream();
if (errorStream != null) {//判断是否有错误输入流
BufferedReader br = new BufferedReader(new InputStreamReader(errorStream));
String buffer = br.readLine();
br.close();
errorStream.close();
if (buffer != null && !buffer.equals("")) {//判断错误输入流中是否有数据
return false;
}
return true;
}
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
###完整代码
package com.flueky.execute;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
public class Keystore {
private String keystorePath;// 签名文件路径
private final String tempPath = "temp.keystore";
private String storepass;// 签名文件密码
private String keyAlias;// 签名文件别名
private String keypasswd;// 别名对应的密码
private final String SHOW_COMMAND = "keytool -list -v -keystore %s -storepass %s";// 显示签名文件信息摘要
private final String STOREPASSWD_COMMAND = "keytool -storepasswd -keystore %s -storepass %s -new %s";// 修改签名文件密码
private final String CHANGEALIAS_COMMAND = "keytool -changealias -keystore %s -alias %s -destalias %s -storepass %s -keypass %s";// 修改别名
private final String KEYPASSWD_COMMAND = "keytool -keypasswd -keystore %s -storepass %s -alias %s -keypass %s -new %s";// 修改别名密码
public Keystore(String keystorePath, String storepass, String keyAlias, String keypasswd) {
super();
this.keystorePath = keystorePath;
this.storepass = storepass;
this.keyAlias = keyAlias;
this.keypasswd = keypasswd;
}
/**
* 修改生成默认签名文件
*
* @date 2016年5月8日 下午10:34:03
*/
public void alert() {
alert("android", "androiddebugkey", "android");
}
/**
* 修改生成指定签名文件
*
* @date 2016年5月15日 下午6:13:14
* @param newStorePass
* @param newAlias
* @param newKeypass
*/
public void alert(String newStorePass, String newAlias, String newKeypass) {
try {
createTempKeystore();
changeStorepass(storepass, newStorePass);
changeAlias(keyAlias, newAlias, newStorePass, keypasswd);
changeKeypass(newStorePass, newAlias, keypasswd, newKeypass);
restoreKeystore();
} catch (Exception e) {
System.out.println(e.toString());
// 修改失败,还原
removeTempKeystore();
}
}
/**
* 创建缓存keystore
*
* @date 2016年5月15日 下午9:13:27
*/
private void createTempKeystore() {
try {
File temp = new File(tempPath);
if (temp.exists())
temp.createNewFile();
File inKeystore = new File(keystorePath);
FileOutputStream tempOutput = new FileOutputStream(temp);
FileInputStream inputStream = new FileInputStream(inKeystore);
int length = 0;
byte[] buffer = new byte[1024];
while ((length = inputStream.read(buffer)) > 0) {
tempOutput.write(buffer, 0, length);
}
inputStream.close();
tempOutput.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 删除缓存keystore
*
* @date 2016年5月15日 下午9:14:24
*/
private void removeTempKeystore() {
File temp = new File(tempPath);
if (temp.exists())
temp.delete();
}
/**
* 重置keystore,在修改失败时创建
*
* @date 2016年5月15日 下午9:14:40
*/
private void restoreKeystore() {
try {
File temp = new File(tempPath);
File outKeystore = new File(keystorePath);
if (outKeystore.exists()) {
outKeystore.delete();
}
outKeystore.createNewFile();
FileInputStream tempInput = new FileInputStream(temp);
FileOutputStream outputStream = new FileOutputStream(outKeystore);
int length = 0;
byte[] buffer = new byte[1024];
while ((length = tempInput.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
outputStream.close();
tempInput.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 判断Process执行时,是否发生异常
*
* @date 2016年5月15日 下午9:59:36
* @param process
* @return
*/
private boolean checkProcessError(Process process) {
try {
InputStream errorStream = process.getErrorStream();
if (errorStream != null) {//判断是否有错误输入流
BufferedReader br = new BufferedReader(new InputStreamReader(errorStream));
String buffer = br.readLine();
br.close();
errorStream.close();
if (buffer != null && !buffer.equals("")) {//判断错误输入流中是否有数据
return false;
}
return true;
}
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* 显示证书信息
*
* @date 2016年5月15日 下午6:04:03
* @param storepass
*/
public void show(String storepass) {
try {
Process process = Runtime.getRuntime().exec(String.format(SHOW_COMMAND, keystorePath, storepass));
InputStream inStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inStream));
String line = "";
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 修改证书密码
*
* @date 2016年5月15日 下午5:50:28
* @param oldStorePass
* @param newStorePass
* @throws IOException
*/
public void changeStorepass(String oldStorePass, String newStorePass) throws Exception {
Process process = Runtime.getRuntime()
.exec(String.format(STOREPASSWD_COMMAND, tempPath, oldStorePass, newStorePass));
if (!checkProcessError(process))
throw new Exception("修改密码失败");
InputStream inStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inStream));
String line = "";
while ((line = reader.readLine()) != null) {
System.out.println(line);
// saveToFile(line, "runlog.log", false);
}
inStream.close();
}
/**
* 修改证书别名
*
* @date 2016年5月15日 下午5:50:51
* @param oldStorePass
* @param newStorePass
*/
public void changeAlias(String oldAlias, String newAlias, String storepass, String keypass) throws Exception {
Process process = Runtime.getRuntime()
.exec(String.format(CHANGEALIAS_COMMAND, tempPath, oldAlias, newAlias, storepass, keypass));
if (!checkProcessError(process))
throw new Exception("修改密码失败");
InputStream inStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inStream));
String line = "";
while ((line = reader.readLine()) != null) {
System.out.println(line);
// saveToFile(line, "runlog.log", false);
}
inStream.close();
}
/**
* 修改别名密码
*
* @date 2016年5月15日 下午5:59:41
* @param storepass
* @param alias
* @param oldKeypass
* @param newKeypass
*/
public void changeKeypass(String storepass, String alias, String oldKeypass, String newKeypass) throws Exception {
Process process = Runtime.getRuntime()
.exec(String.format(KEYPASSWD_COMMAND, tempPath, storepass, alias, oldKeypass, newKeypass));
if (!checkProcessError(process))
throw new Exception("修改密码失败");
InputStream inStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inStream));
String line = "";
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
inStream.close();
}
}