您现在的位置是:首页 > 文章详情

Android--解包、添加文件、打包、签名

日期:2018-04-10点击:353
版权声明:本文为博主原创文章,转载请标明出处。 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("文件打包失败!!!"); } } 

原文链接:https://yq.aliyun.com/articles/631448
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章