码迷,mamicode.com
首页 > 编程语言 > 详细

写一个jar来批量处理签名apk

时间:2015-04-15 17:09:14      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:signapk   批处理apk签名   

众所周知,给apk进行签名,使用

jarsigner -verbose -keystore android.keystore -signedjar 签名后.apk 待签名.apk 

命令
这是有android.keystore文件时,给apk签名,签名时,要输入密码
还有一种情况,就是有platform.pk8和platform.x509.pem这两个文件时,给apk签名(让apk有系统签名),这个时候用

java -jar signapk.jar  platform.x509.pem  platform.pk8 待签名.apk 签名后.apk

这个需要signapk.jar包,这个jar包可以从android源码编译得到,

网上进行自动批量签名,都是采用第二种方式,但前提是得有 pem 和 pk8文件

所以第一步就是把keystore文件转换成 pem 和 pk8 文件

转换过程见        keystore文件转换格式为pk8+x509.pem    日记

接下来,就是要做批量处理代码,我看网上的,大都是采用脚本来处理,基本思路是先得到所有待签名的apk,再循环对每个apk进行签名,本人对脚本不是很在行,于是就用java来写了个批处理文件
批量签名采用的是都是signapk.jar,但是如果用java来写的话,那么就会有一个问题:如何在java文件中,调用jar文件?
不好意思,这个问题我也没解决,如果有哪位高人知道,请指教。
我的处理方式是绕过了这个问题,因为signapk.jar文件是由android源码文件生成的,我找到了SignApk.java源码
SignApk.java路径:

    android\jb_4.2\build\tools\signapk

有了源码,那什么都好办了,但还有个问题,SignApk.java引用到了两个jar包:
LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle-host bouncycastle-bcpkix-host
(在 Android.mk文件中有指出)
那么我就在源码中,全局搜这两个包,
./external/bouncycastle/Android.mk:81:    LOCAL_MODULE := bouncycastle-hostdex
./external/bouncycastle/Android.mk:102:    LOCAL_MODULE := bouncycastle-bcpkix-host
其实,这两个包不用找源码,只要找一生成的    bouncycastle-host.jar    bouncycastle-bcpkix-host.jar    就可以了
这两个包在android\jb_4.2\out\host\linux-x86\framework 目录下

源文件都准备好了,开干:
先建立一个java工程

里面有一个Main.java文件,

public class Main {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  // 当前目录用"./"
  File dist = new File("./签名后的apk");
  // 创建目录
  if (!dist.exists()) {
   dist.mkdirs();
   System.out.print("创建目录:  签名后的apk");
  }
  ArrayList<File> list = FileTools.getAllApks("./");
  System.out.print(list.size());
  String pem = FileTools.getPem("./");
  String pk8 = FileTools.getPk8("./");
  if (pem == null || pk8 == null) {
   System.out.print("没找到密钥和公钥文件!!!");
   return;
  }
  for (File file : list) {
   // 签名参数
   System.out.print("创建签名参数");
   String[] tem = new String[] { pem, pk8, file.getName(),
     dist.getAbsolutePath() + "/" + file.getName() };
   System.out.print("签名参数=" + Arrays.toString(tem));
   // 对每个apk文件进行签名
   SignApk.signApkMain(tem);
   System.out.print("签名完成");
  }
 }
}

这里引用到了一个工具类:FileToos.java

package com.ytmfdw.sign;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;

public class FileTools {

 public static ArrayList<File> getAllApks(String path) {
  ArrayList<File> files = new ArrayList<>();

  File file = new File(path);
  if (file.exists() && file.isDirectory()) {
   File[] list = file.listFiles(new FileFilter() {

    @Override
    public boolean accept(File pathname) {
     // TODO Auto-generated method stub
     if (pathname.getName().toLowerCase().endsWith(".apk")) {
      return true;
     }
     return false;
    }
   });

   for (File f : list) {
    files.add(f);

   }
  }

  return files;
 }

 /**
  * 获取cert.x509.pem 如果有两个后缀为pem,则以第一个为准
  * */
 public static String getPem(String path) {

  File file = new File(path);
  if (file.exists()) {
   if (file.isDirectory()) {
    File[] files = file.listFiles(new FileFilter() {

     @Override
     public boolean accept(File pathname) {
      // TODO Auto-generated method stub
      if (pathname.getName().toLowerCase().endsWith(".pem")) {
       return true;
      }
      return false;
     }
    });

    if (files.length > 0) {
     return files[0].getName();
    }
   }
  }

  return null;
 }

 /**
  * 获取private.pk8 如果有两个后缀为pk8,则以第一个为准
  * */
 public static String getPk8(String path) {

  File file = new File(path);
  if (file.exists()) {
   if (file.isDirectory()) {
    File[] files = file.listFiles(new FileFilter() {

     @Override
     public boolean accept(File pathname) {
      // TODO Auto-generated method stub
      if (pathname.getName().toLowerCase().endsWith(".pk8")) {
       return true;
      }
      return false;
     }
    });

    if (files.length > 0) {
     return files[0].getName();
    }
   }
  }

  return null;
 }
}


按以上方式写的,肯定会报错的,首先         SignApk.signApkMain这个方法是没有的,其实这个方法就是SignApk中的main()函数
java文件中,只要有一个main()函数,所以这个名字我改了下
除了这个地方报错外,SignApk的引用,也报错,源码中,定义是这样写的:class SignApk {
所以其他包中,没有权限引用这个类,所以要改成        
        public class SignApk{

然后,SignApk.java中,也会报错,因为没导包,把上面找到的   bouncycastle-host.jar    bouncycastle-bcpkix-host.jar  引用进来就可以了,基本上大功告成

总结下:关键是找到SignApk.java,bouncycastle-host.jar ,bouncycastle-bcpkix-host.jar这三个文件,然后是修改SignApk.java文件:
改两处:
类权限:       class SignApk {     ===改成==>      public class SignApk{
                       
主方法:    public static void main(String[] args) {       =改成==>        public static void signApkMain(String[] args) {


其他基本上没什么问题

写一个jar来批量处理签名apk

标签:signapk   批处理apk签名   

原文地址:http://blog.csdn.net/ytmfdw/article/details/45060471

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!