版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/chaoyu168/article/details/79900485
package zip;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
public class ziptest {
private static File apktool = null;
private static File signapk = null;
private static File testkey_pk8 = null;
private static File testkey_x509_pem = null;
private static File dirFile;// 根目录
public static void main(String args[]) throws IOException{
Process process = null;
apktool = new File(dirFile.getAbsolutePath(), "apktool.bat");
dirFile = new File(System.getProperty("user.dir"));
signapk = new File(dirFile.getAbsolutePath(), "signapk.jar");
testkey_pk8 = new File(dirFile.getAbsolutePath(), "testkey.pk8");
testkey_x509_pem = new File(dirFile.getAbsolutePath(), "testkey.x509.pem");
try {
//1----解压
//apktool路径
//String path = "E:\\apktool\\apktool.bat";
//保存路径
String appPath = "E:\\newapk\\";
//process = Runtime.getRuntime().exec("cmd.exe /c"+path+" apktool d "+appPath+"lvping.apk -o"+appPath+"apk");
process = Runtime.getRuntime().exec("cmd.exe /c"+apktool.getPath() + " d –f "+appPath+"lvping.apk -o"+appPath+"apk");
if(process.waitFor()!=0)System.out.println("解压失败!");
//2----添加json文件
String filePath ="E:\\newapk\\apk";
File f = new File(filePath);
File[] fis = f.listFiles();
for(File ff:fis) {
String paths = ff.getAbsolutePath();
if(paths.contains("assets")) {
String fPath = "E:\\newapk\\apk\\assets";
CreateJson(fPath);
}else {
String fPath =filePath+"\\assets";
File fs = new File(fPath);
CreateJson(fPath);
fs.mkdirs();
}
}
//3----打包
// process = Runtime.getRuntime().exec("cmd.exe /c"+path+" b "+appPath+"apk -o"+appPath+"app.apk");
process = Runtime.getRuntime().exec("cmd.exe /c"+apktool.getPath() +" b "+appPath+"apk -o"+appPath+"app.apk");
if(process.waitFor()!=0)System.out.println("打包失败!");
//4----签名 (文件名称中不能包含空格)
//String cmd = "cmd.exe /c E:\\apktool\\signapk.jar E:\\apktool\\testkey.x509.pem E:\\apktool\\testkey.pk8 "+appPath+"app.apk"+ appPath;
String cmd = "cmd.exe /c java -jar" + signapk.getPath() + " " + testkey_x509_pem.getPath() + " "
+ testkey_pk8.getPath() + " " +appPath+"app.apk " + appPath+ "appt.apk";
process = Runtime.getRuntime().exec(cmd);
System.out.println("111213");
if(process.waitFor()!=0) {
System.out.println("签名失败。。。");
}
}catch (Exception e)
{
e.printStackTrace();
}finally{
/* br.close();
osw.close();*/
}
}
public static void CreateJson(String fPath/*,String json*/) {
// 标记文件生成是否成功
boolean flag = true;
// 拼接文件完整路径
String fullPath =fPath+ File.separator + "config.json";
// 生成json格式文件
try {
// 保证创建一个新文件
File file = new File(fullPath);
if (!file.getParentFile().exists()) { // 如果父目录不存在,创建父目录
file.getParentFile().mkdirs();
}
if (file.exists()) { // 如果已存在,删除旧文件
file.delete();
}
file.createNewFile();
// 格式化json字符串
// 将格式化后的字符串写入文件
Writer write = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
write.write("{\"user\":\"test1\",\"direction\":\"3.24\"}");
write.flush();
write.close();
} catch (Exception e) {
flag = false;
e.printStackTrace();
}
}
}
上面是借助apktool,下面试纯代码:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Enumeration;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipOutputStream;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
/**
* @author showlike
* @version v1.0
* 2012-9-28 上午11:03:36
* explain : 文件解压/打包工具
*/
public class ZipUtil {
private static final int BUFFER = 1024;
private static final String BASE_DIR = "";
/**符号"/"用来作为目录标识判断符*/
private static final String PATH = "/";
/**签名目录*/
private static final String SIGN_PATH_NAME = "META-INF";
/**修改文件目录*/
private static final String UPDATE_PATH_NAME = "\\res\\raw\\channel";
/**解压源文件目录*/
private static final String SOURCE_PATH_NAME = "\\source\\";
/**打包目录*/
private static final String TARGET_PATH_NAME = "\\target\\";
/**签名目录*/
private static final String RESULT_PATH_NAME = "\\result\\";
/**JDK BIN 目录*/
private static final String JDK_BIN_PATH = "C:\\Program Files\\Java\\jdk1.6.0_26\\bin";
/**密钥 目录*/
private static final String SECRET_KEY_PATH = "F:\\document\\APK\\";
/**密钥 名称*/
private static final String SECRET_KEY_NAME = "sdk.keystore";
/**
* 解压缩zip文件
* @param fileName 要解压的文件名 包含路径 如:"c:\\test.zip"
* @param filePath 解压后存放文件的路径 如:"c:\\temp"
* @throws Exception
*/
@SuppressWarnings("rawtypes")
public static void unZip(String fileName, String filePath) throws Exception{
ZipFile zipFile = new ZipFile(fileName);
Enumeration emu = zipFile.getEntries();
while(emu.hasMoreElements()){
ZipEntry entry = (ZipEntry) emu.nextElement();
if (entry.isDirectory()){
new File(filePath+entry.getName()).mkdirs();
continue;
}
BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
File file = new File(filePath + entry.getName());
File parent = file.getParentFile();
if(parent != null && (!parent.exists())){
parent.mkdirs();
}
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos,BUFFER);
byte [] buf = new byte[BUFFER];
int len = 0;
while((len=bis.read(buf,0,BUFFER))!=-1){
fos.write(buf,0,len);
}
bos.flush();
bos.close();
bis.close();
}
zipFile.close();
}
/**
* 压缩文件
*
* @param srcFile
* @param destPath
* @throws Exception
*/
public static void compress(String srcFile, String destPath) throws Exception {
compress(new File(srcFile), new File(destPath));
}
/**
* 压缩
*
* @param srcFile
* 源路径
* @param destPath
* 目标路径
* @throws Exception
*/
public static void compress(File srcFile, File destFile) throws Exception {
// 对输出文件做CRC32校验
CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(
destFile), new CRC32());
ZipOutputStream zos = new ZipOutputStream(cos);
compress(srcFile, zos, BASE_DIR);
zos.flush();
zos.close();
}
/**
* 压缩
*
* @param srcFile
* 源路径
* @param zos
* ZipOutputStream
* @param basePath
* 压缩包内相对路径
* @throws Exception
*/
private static void compress(File srcFile, ZipOutputStream zos,
String basePath) throws Exception {
if (srcFile.isDirectory()) {
compressDir(srcFile, zos, basePath);
} else {
compressFile(srcFile, zos, basePath);
}
}
/**
* 压缩目录
*
* @param dir
* @param zos
* @param basePath
* @throws Exception
*/
private static void compressDir(File dir, ZipOutputStream zos,
String basePath) throws Exception {
File[] files = dir.listFiles();
// 构建空目录
if (files.length < 1) {
ZipEntry entry = new ZipEntry(basePath + dir.getName() + PATH);
zos.putNextEntry(entry);
zos.closeEntry();
}
String dirName = "";
String path = "";
for (File file : files) {
//当父文件包名为空时,则不把包名添加至路径中(主要是解决压缩时会把父目录文件也打包进去)
if(basePath!=null && !"".equals(basePath)){
dirName=dir.getName();
}
path = basePath + dirName + PATH;
// 递归压缩
compress(file, zos, path);
}
}
/**
* 文件压缩
*
* @param file
* 待压缩文件
* @param zos
* ZipOutputStream
* @param dir
* 压缩文件中的当前路径
* @throws Exception
*/
private static void compressFile(File file, ZipOutputStream zos, String dir)
throws Exception {
/**
* 压缩包内文件名定义
*
* <pre>
* 如果有多级目录,那么这里就需要给出包含目录的文件名
* 如果用WinRAR打开压缩包,中文名将显示为乱码
* </pre>
*/
if("/".equals(dir))dir="";
else if(dir.startsWith("/"))dir=dir.substring(1,dir.length());
ZipEntry entry = new ZipEntry(dir + file.getName());
zos.putNextEntry(entry);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
int count;
byte data[] = new byte[BUFFER];
while ((count = bis.read(data, 0, BUFFER)) != -1) {
zos.write(data, 0, count);
}
bis.close();
zos.closeEntry();
}
public static void main(String[] args)throws Exception{
StringBuffer buffer = new StringBuffer();
BufferedReader br =null;
OutputStreamWriter osw =null;
String srcPath = "F:\\document\\APK\\new\\iGouShop.apk";
String content= "channel_id=LD20120926";
File srcFile = new File(srcPath);
String parentPath = srcFile.getParent(); //源文件目录
String fileName = srcFile.getName(); //源文件名称
String prefixName = fileName.substring(0, fileName.lastIndexOf("."));
//解压源文件保存路径
String sourcePath = buffer.append(parentPath).append(SOURCE_PATH_NAME).
append(prefixName).append("\\").toString();
//------解压
unZip(srcPath, sourcePath);
//------删除解压后的签名文件
String signPathName = sourcePath+SIGN_PATH_NAME;
File signFile = new File(signPathName);
if(signFile.exists()){
File sonFiles[] = signFile.listFiles();
if(sonFiles!=null && sonFiles.length>0){
//循环删除签名目录下的文件
for(File f : sonFiles){
f.delete();
}
}
signFile.delete();
}
//------修改内容
buffer.setLength(0);
String path = buffer.append(parentPath).append(SOURCE_PATH_NAME)
.append(prefixName).append(UPDATE_PATH_NAME).toString();
br = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
while((br.readLine())!=null)
{
osw = new OutputStreamWriter(new FileOutputStream(path));
osw.write(content,0,content.length());
osw.flush();
}
//------打包
String targetPath = parentPath+TARGET_PATH_NAME;
//判断创建文件夹
File targetFile = new File(targetPath);
if(!targetFile.exists()){
targetFile.mkdir();
}
compress(parentPath+SOURCE_PATH_NAME+prefixName,targetPath+fileName);
//------签名
File ff =new File(JDK_BIN_PATH);
String resultPath = parentPath+RESULT_PATH_NAME;
//判断创建文件夹
File resultFile = new File(resultPath);
if(!resultFile.exists()){
resultFile.mkdir();
}
//组合签名命令
buffer.setLength(0);
buffer.append("cmd.exe /c jarsigner -keystore ")
.append(SECRET_KEY_PATH).append(SECRET_KEY_NAME)
.append(" -storepass winadsdk -signedjar ")
.append(resultPath).append(fileName).append(" ") //签名保存路径应用名称
.append(targetPath).append(fileName).append(" ") //打包保存路径应用名称
.append(SECRET_KEY_NAME);
//利用命令调用JDK工具命令进行签名
Process process = Runtime.getRuntime().exec(buffer.toString(),null,ff);
if(process.waitFor()!=0)System.out.println("文件打包失败!!!");
}
}