├── .gitignore ├── README.md ├── libs └── packer-helper-1.0.5.jar ├── market_template.txt └── src ├── META-INF └── MANIFEST.MF └── com └── micro └── mcpt ├── ToolGui.form ├── ToolGui.java └── util ├── ConfigUtil.java └── FileUtil.java /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /.gradle 3 | /build 4 | /captures 5 | /opt 6 | /out 7 | /apks 8 | *.iml -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **version1.0** 2 | 3 | ### 功能:打开指定的apk文件和需要构建的渠道列表,输出多渠道包。 4 | ### 导入项目:本项目是java 的IntelliJ IDEA工程,导入运行main方法即可打开主界面 5 | 6 | ### 使用:运行MultiChannelPackerTools.jar,根据提示操作即可。 7 | 命令行下调用(需要jre): 8 | ```shell 9 | java -jar MultiChannelPackerTools.jar 10 | ``` 11 | 12 | ###注意: 13 | - 读写渠道名称需要配合此工具原理来实现 14 | - 渠道列表文件规则:一行代表一个,#表示注释 15 | 16 | #### 参考文章: 17 | - [https://github.com/seven456/MultiChannelPackageTool](https://github.com/seven456/MultiChannelPackageTool) 18 | - [https://github.com/mcxiaoke/packer-ng-plugin](https://github.com/mcxiaoke/packer-ng-plugin) 19 | -------------------------------------------------------------------------------- /libs/packer-helper-1.0.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/act262/MultiChannelPackerTool/f262c4e2baf19b7a53f90322230b152455083806/libs/packer-helper-1.0.5.jar -------------------------------------------------------------------------------- /market_template.txt: -------------------------------------------------------------------------------- 1 | #官网下载 2 | official 3 | #360手机助手 4 | qihu360 5 | #百度手机助手 6 | baidu 7 | #腾讯应用宝 8 | yingyongbao 9 | #豌豆荚 10 | wandoujia 11 | #淘宝手机助手 12 | taobao 13 | #小米应用商店 14 | xiaomi 15 | #华为应用商店 16 | huawei 17 | #魅族应用商店 18 | meizu 19 | #联想乐商店 20 | lianxiang 21 | #oppo 22 | oppo 23 | #vivo 24 | vivo 25 | #金立手机助手 26 | jinli 27 | #乐视应用开放平台 28 | leshi 29 | #机锋市场 30 | jifeng 31 | #安智市场 32 | anzhi 33 | #搜狗手机助手 34 | sougou 35 | #三星 36 | samsung 37 | -------------------------------------------------------------------------------- /src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: com.micro.mcpt.ToolGui 3 | 4 | -------------------------------------------------------------------------------- /src/com/micro/mcpt/ToolGui.form: -------------------------------------------------------------------------------- 1 | 2 |
95 | -------------------------------------------------------------------------------- /src/com/micro/mcpt/ToolGui.java: -------------------------------------------------------------------------------- 1 | package com.micro.mcpt; 2 | 3 | import com.mcxiaoke.packer.helper.PackerNg; 4 | import com.micro.mcpt.util.ConfigUtil; 5 | 6 | import javax.swing.*; 7 | import javax.swing.filechooser.FileNameExtensionFilter; 8 | import java.awt.*; 9 | import java.awt.event.ActionEvent; 10 | import java.awt.event.ActionListener; 11 | import java.io.File; 12 | import java.io.IOException; 13 | import java.util.List; 14 | import java.util.zip.ZipFile; 15 | 16 | /** 17 | * APK多渠道读写工具 18 | * 19 | * @author act262@gmail.com 20 | */ 21 | public class ToolGui { 22 | private JButton mApkFileButton; 23 | private JPanel mRootPannel; 24 | private JTextField mApkFilePath; 25 | private JTextArea mConsoleArea; 26 | private JButton mBeginButton; 27 | private JTextField mMarketFilePath; 28 | private JButton mMarketButton; 29 | private JProgressBar progressBar1; 30 | private JScrollPane mScrollText; 31 | 32 | public ToolGui() { 33 | // 初始化上次记录的文件位置 34 | mApkFilePath.setText(getLastApkFilePath()); 35 | mMarketFilePath.setText(getLastMarketFilePath()); 36 | 37 | mApkFileButton.addActionListener(new ActionListener() { 38 | @Override 39 | public void actionPerformed(ActionEvent actionEvent) { 40 | openApkFile(); 41 | } 42 | }); 43 | 44 | mMarketButton.addActionListener(new ActionListener() { 45 | @Override 46 | public void actionPerformed(ActionEvent actionEvent) { 47 | openMarketFile(); 48 | } 49 | }); 50 | 51 | mBeginButton.addActionListener(new ActionListener() { 52 | @Override 53 | public void actionPerformed(ActionEvent actionEvent) { 54 | begin(); 55 | } 56 | }); 57 | } 58 | 59 | // 开始处理 60 | private void begin() { 61 | String apkFilePath = mApkFilePath.getText(); 62 | // 未选择文件 63 | if (apkFilePath == null || apkFilePath.isEmpty()) { 64 | prompt("APK文件不存在"); 65 | return; 66 | } 67 | String marketFilePath = mMarketFilePath.getText(); 68 | if (marketFilePath == null || marketFilePath.isEmpty()) { 69 | prompt("Market文件不存在"); 70 | return; 71 | } 72 | 73 | try { 74 | boolean check = check(apkFilePath); 75 | if (!check) { 76 | return; 77 | } 78 | } catch (IOException e) { 79 | e.printStackTrace(); 80 | // 文件操作发生错误 81 | mConsoleArea.setText("文件不存在"); 82 | return; 83 | } 84 | 85 | // 保存上次有效目录 86 | save(apkFilePath, marketFilePath); 87 | 88 | try { 89 | build(apkFilePath, marketFilePath); 90 | } catch (Exception e) { 91 | e.printStackTrace(); 92 | prompt("构建失败"); 93 | } 94 | } 95 | 96 | // 打开市场文件 97 | private void openMarketFile() { 98 | JFileChooser chooser = new JFileChooser(); 99 | chooser.setFileFilter(new FileNameExtensionFilter("Market Text Files", "txt")); 100 | // 记录上次选择位置 101 | File file = new File(mMarketFilePath.getText()); 102 | if (file.exists()) { 103 | chooser.setCurrentDirectory(file); 104 | } 105 | int returnVal = chooser.showOpenDialog(mRootPannel); 106 | if (returnVal == JFileChooser.APPROVE_OPTION) { 107 | File selectedFile = chooser.getSelectedFile(); 108 | mMarketFilePath.setText(selectedFile.getAbsolutePath()); 109 | } 110 | } 111 | 112 | /** 113 | * 打开Apk文件 114 | */ 115 | private void openApkFile() { 116 | // 打开APK文件 117 | JFileChooser chooser = new JFileChooser(); 118 | chooser.setFileFilter(new FileNameExtensionFilter("Android Apk Files", "apk")); 119 | // 记录上次选择位置 120 | File file = new File(mApkFilePath.getText()); 121 | if (file.exists()) { 122 | chooser.setCurrentDirectory(file); 123 | } 124 | 125 | int returnVal = chooser.showOpenDialog(mRootPannel); 126 | if (returnVal == JFileChooser.APPROVE_OPTION) { 127 | File selectedFile = chooser.getSelectedFile(); 128 | mApkFilePath.setText(selectedFile.getAbsolutePath()); 129 | } 130 | } 131 | 132 | /** 133 | * 弹出提示框 134 | * 135 | * @param message 提示信息 136 | */ 137 | private void prompt(String message) { 138 | Toolkit.getDefaultToolkit().beep(); 139 | JOptionPane.showMessageDialog(null, message, "WARNING", JOptionPane.ERROR_MESSAGE); 140 | } 141 | 142 | // 检查APK文件是否已经写入过数据 143 | private boolean check(String filePath) throws IOException { 144 | ZipFile zipFile = null; 145 | try { 146 | zipFile = new ZipFile(filePath); 147 | String name = zipFile.getName(); 148 | String comment = zipFile.getComment(); 149 | int size = zipFile.size(); 150 | System.out.println("name = " + name); 151 | System.out.println("size = " + size); 152 | System.out.println("comment = " + comment); 153 | 154 | if (comment != null) { 155 | prompt("该APK文件已经写入过信息"); 156 | return false; 157 | } 158 | } catch (IOException e) { 159 | throw e; 160 | } finally { 161 | if (zipFile != null) { 162 | zipFile.close(); 163 | } 164 | } 165 | return true; 166 | } 167 | 168 | /** 169 | * 开始构建 170 | */ 171 | private void build(String apkFilePath, String marketFilePath) throws Exception { 172 | mConsoleArea.setText(""); 173 | mConsoleArea.setText("build start\n"); 174 | File apkFile = new File(apkFilePath); 175 | if (!apkFile.exists()) { 176 | prompt("APK 文件不存在"); 177 | return; 178 | } 179 | 180 | File marketFile = new File(marketFilePath); 181 | if (!marketFile.exists()) { 182 | prompt("Market 文件不存在"); 183 | return; 184 | } 185 | 186 | List