打包工具类

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.OutputStreamWriter;

/**
 *
 * 最重要的要先将工程运行一次
 *
 * 工程中不能有空文件夹
 *
 *
 * APK打包类, 注意的地方, mainfest里要加 <meta-data android:name="UMENG_CHANNEL"
 * android:value="@string/channel_name" />
 *
 * string.xml 中要有: <string name="channel_name">app_channel</string>
 *
 * 代码中查看: String qudao = null; try { ApplicationInfo appInfo =
 * getPackageManager().getApplicationInfo( getPackageName(),
 * PackageManager.GET_META_DATA); qudao =
 * appInfo.metaData.getString("UMENG_CHANNEL"); } catch (NameNotFoundException
 * e) { Toast.makeText(this, "qudao 错误" , 1).show(); }
 *
 * Toast.makeText(this, "qudao:" + qudao, 1).show();
 *
 * 这里要替换签名,
 *
 * @description: android渠道打包工具类,确保路径填写无误,渠道名称填入channels中
 * @author */
public class CompiledApkUpdate {

 private static final String androidSDK_PATH = "E:\\workTools\\android-sdk-windows\\android-sdk-windows\\"; // android
 // SDK路径

 public static final String APK_NAME = "Wuyou-ver1.apk";
 public static final String PROJECT_LIBARY = "E:\\";
 public static final String PROJECT_PATH = "E:\\"; // 要打包的工程路径
 public static final String APK_PATH = "E:\\APK\\// 打包后存放apk的路径
                // duitang_是前缀

 private static final String apk_PATH_keystore = "E:\\APK_key\\.keystore"; // apk签名文件路径
 private static final String channelFlag = "app_channel";

 // public static String[] channels = {"duitang"};
 private static String currentChannelName = "";
 public static String[] channels = { "10000"};

 public static void main(String[] args) {
  replaceChannel();
 }

 /**
  * 替换渠道名称
  */
 public static void replaceChannel() {
  try {
   String outPath = PROJECT_PATH + "res\\values\\strings.xml"; // 输出文件位置
   String content = read(outPath);
   for (int channelid = 0; channelid < channels.length; channelid++) {
    String tmpContent = content;
    tmpContent = tmpContent.replaceFirst(channelFlag,
      channels[channelid]);
    currentChannelName = channels[channelid];
    write(tmpContent, outPath);
    System.out.println("replace channel name over..."
      + channels[channelid]);
    packageRes(); // 一次渠道号的更改完成。可以进行打包了。
    createUnsignedApk();
    signedApk(channelid);
   }
   write(content, outPath); // 完成后还原channel_name
   System.out.println("execute over!");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 /**
  * class文件打包成classes.dex
  */
 public static void packageDex() {
  try {
   System.out.println("dx.bat start...");
   Process process = Runtime.getRuntime().exec(
     androidSDK_PATH + "platform-tools\\dx.bat --dex --output="
       + PROJECT_PATH + "bin\\classes.dex " + PROJECT_PATH
       + "bin\\classes " + PROJECT_PATH + "libs\\*.jar");

   new MyThread(process.getErrorStream()).start();

   new MyThread(process.getInputStream()).start();

   process.waitFor();
   process.destroy();
   System.out.println("dx.bat over...");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 /**
  * res assets文件打包成res.zip
  */
 public static void packageRes() {
  try {
   System.out.println(currentChannelName + " create resources.ap");
   String library = "";
   if (PROJECT_LIBARY != null && !PROJECT_LIBARY.equals("")) {
    library = "-S " + PROJECT_LIBARY + "res ";
   }
   Process process = null;
   process = Runtime.getRuntime().exec(
     androidSDK_PATH + "platform-tools\\aapt.exe package -f "
       + "-M " + PROJECT_PATH
       + "AndroidManifest.xml "
       + // -M 指定配置文件
       "-S " + PROJECT_PATH
       + "res "
       + // -S 指定资源文件
       library + "-A " + PROJECT_PATH
       + "assets "
       + // -A 指定assets
       "-I " + androidSDK_PATH
       + "platforms\\android-7\\android.jar "
       + // -I 指定android类
       "-F " + PROJECT_PATH
       + "bin\\resources.ap_ --auto-add-overlay"); // 将资源文件打包resources.ap_
   new MyThread(process.getErrorStream()).start();
   new MyThread(process.getInputStream()).start();
   process.waitFor();
   process.destroy();
   System.out.println(currentChannelName + " resources.ap over...");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 /**
  * classes.dex res.zip AndroidManifest.xml组合成未签名的apk
  */
 public static void createUnsignedApk() {
  try {
   System.out.println(currentChannelName + " createUnsignedApk start");
   Process process = null;
   process = Runtime.getRuntime().exec(
     androidSDK_PATH + "tools\\apkbuilder.bat " + PROJECT_PATH
       + "bin\\" + APK_NAME + " -u -z " + PROJECT_PATH
       + "bin\\resources.ap_ -f " + PROJECT_PATH
       + "bin\\classes.dex"); // 生成未签名的apk
   new MyThread(process.getErrorStream()).start();
   new MyThread(process.getErrorStream()).start();
   process.waitFor();
   process.destroy();
   System.out.println(currentChannelName + " createUnsignedApk over");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 /**
  * 签名apk
  */
 public static void signedApk(int channelid) {
  try {
   System.out.println(currentChannelName + " signed apk start");
   Process process = null;
   String jarsigner;
   jarsigner = "jarsigner -keystore " + apk_PATH_keystore
     + " -storepass 密码 -keypass 密码 "
     + "-signedjar " + APK_PATH + channels[channelid] + ".apk "
     + PROJECT_PATH + "bin\\" + APK_NAME + " 签名名"; // 签名apk
   process = Runtime.getRuntime().exec(jarsigner); // 对apk进行签名
   new MyThread(process.getErrorStream()).start();

   new MyThread(process.getInputStream()).start();
   process.waitFor();
   process.destroy();
   System.out.println(currentChannelName + " signed apk over"); // 一条渠道的打包完成。文件会输出到指定目录
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 public static String read(String path) {
  StringBuffer res = new StringBuffer();
  String line = null;
  try {
   BufferedReader reader = new BufferedReader(new InputStreamReader(
     new FileInputStream(path), "UTF-8"));
   while ((line = reader.readLine()) != null) {
    res.append(line + "\n");
   }
   reader.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  return res.toString();
 }

 public static boolean write(String cont, String dist) {
  try {
   OutputStreamWriter writer = new OutputStreamWriter(
     new FileOutputStream(new File(dist)), "utf-8");
   writer.write(cont);
   writer.flush();
   writer.close();
   return true;
  } catch (IOException e) {
   e.printStackTrace();
   return false;
  }
 }

 public static class MyThread extends Thread {
  BufferedReader bf;

  public MyThread(InputStream input) {
   bf = new BufferedReader(new InputStreamReader(input));
  }

  public void run() {
   String line;
   try {
    line = bf.readLine();
    while (line != null) {
     System.out.println(line);
     line = bf.readLine();
    }
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值