diff --git a/README.md b/README.md
index 7c65943..f69642b 100644
--- a/README.md
+++ b/README.md
@@ -1,37 +1,10 @@
# 安卓sdk工具
#### 介绍
-用于安卓sdk做热更新常用的一些工具
+用于工作上安卓sdk做热更新常用的一些工具
-#### 软件架构
-软件架构说明
-
-
-#### 安装教程
-
-1. xxxx
-2. xxxx
-3. xxxx
#### 使用说明
-1. xxxx
-2. xxxx
-3. xxxx
+1. 要用签名工具则必须配好jarsigner环境
-#### 参与贡献
-
-1. Fork 本仓库
-2. 新建 Feat_xxx 分支
-3. 提交代码
-4. 新建 Pull Request
-
-
-#### 码云特技
-
-1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
-2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com)
-3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
-4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
-5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
-6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
diff --git a/src/com/qy/Interfaces/DalogAbs.java b/src/com/qy/Interfaces/DalogAbs.java
deleted file mode 100755
index 0047e93..0000000
--- a/src/com/qy/Interfaces/DalogAbs.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.qy.Interfaces;
-
-public abstract class DalogAbs {
- public abstract void onSuccess();
-}
diff --git a/src/com/qy/Interfaces/DialogInterface.java b/src/com/qy/Interfaces/DialogInterface.java
new file mode 100644
index 0000000..b0b6c71
--- /dev/null
+++ b/src/com/qy/Interfaces/DialogInterface.java
@@ -0,0 +1,6 @@
+package com.qy.Interfaces;
+
+public abstract class DialogInterface {
+ public void onSuccess(){};
+ public void onOut(Object data){};
+}
diff --git a/src/com/qy/ui/AppMain.java b/src/com/qy/ui/AppMain.java
index 37982a5..d658f87 100755
--- a/src/com/qy/ui/AppMain.java
+++ b/src/com/qy/ui/AppMain.java
@@ -223,7 +223,7 @@ public class AppMain extends JFrame {
// TODO: handle exception
e.printStackTrace();
}
- setTitle("\u8F6C\u6362\u5668v2.10");
+ setTitle("\u8F6C\u6362\u5668v2.2");
// TODO Auto-generated constructor stub
setSize(900, 456);
getContentPane().setLayout(null);
@@ -653,6 +653,16 @@ public class AppMain extends JFrame {
});
menu.add(autoSDK);
+ JMenuItem autoOutApk = new JMenuItem("自动更新SDK");
+ autoOutApk.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ new AutoOutAPKUi();
+ }
+ });
+ menu.add(autoOutApk);
+
+
mnBasetools = new JMenu("Base64\u5DE5\u5177");
menuBar.add(mnBasetools);
diff --git a/src/com/qy/ui/AutoOutAPKAddChannelUi.form b/src/com/qy/ui/AutoOutAPKAddChannelUi.form
new file mode 100644
index 0000000..da1b04a
--- /dev/null
+++ b/src/com/qy/ui/AutoOutAPKAddChannelUi.form
@@ -0,0 +1,30 @@
+
+
diff --git a/src/com/qy/ui/AutoOutAPKAddChannelUi.java b/src/com/qy/ui/AutoOutAPKAddChannelUi.java
new file mode 100644
index 0000000..99e6254
--- /dev/null
+++ b/src/com/qy/ui/AutoOutAPKAddChannelUi.java
@@ -0,0 +1,99 @@
+package com.qy.ui;
+
+import com.qy.Interfaces.DialogInterface;
+import com.qy.utils.Tools;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.util.*;
+import java.util.List;
+
+public class AutoOutAPKAddChannelUi {
+ private JComboBox comboBox1;
+ private JPanel panel1;
+ private JButton submit;
+ private JPanel inputPanel;
+ private JSONObject json;
+ private List list=new ArrayList<>();
+ private DialogInterface inter;
+ private JFrame frame;
+
+ public AutoOutAPKAddChannelUi(DialogInterface inter, JFrame frame) {
+ this.inter=inter;
+ this.frame=frame;
+ json= Tools.loadConfig(new File("gameConfig.json"));
+ init();
+ }
+ private void init(){
+ Vector vector=new Vector<>(json.keySet());
+ comboBox1.setModel(new DefaultComboBoxModel<>(vector));
+ comboBox1.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ setData(comboBox1.getSelectedIndex());
+ }
+ });
+ submit.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Map map=new HashMap<>();
+ map.put("NAME",name);
+ for (JTextField textField : list) {
+ map.put(textField.getName(),textField.getText());
+ }
+ inter.onOut(map);
+ AutoOutAPKAddChannelUi.this.frame.dispose();
+ }
+ });
+ GridLayout layout=new GridLayout(-1,1);
+ inputPanel.setLayout(layout);
+ inputPanel.setBackground(Color.black);
+ setData(0);
+ }
+ private String name="";
+ private void setData(int index){
+ inputPanel.removeAll();
+ inputPanel.updateUI();
+ list.clear();
+ JSONArray item = null;
+ int i=0;
+ for (String key : json.keySet()) {
+ if(i==index){
+ item=json.getJSONArray(key);
+ name=key;
+ break;
+ }
+ i++;
+ }
+ if(item==null){
+ return;
+ }
+ for (int j = 0; j
+
diff --git a/src/com/qy/ui/AutoOutAPKUi.java b/src/com/qy/ui/AutoOutAPKUi.java
new file mode 100644
index 0000000..a1425ef
--- /dev/null
+++ b/src/com/qy/ui/AutoOutAPKUi.java
@@ -0,0 +1,177 @@
+package com.qy.ui;
+
+import com.qy.Interfaces.DialogInterface;
+import com.qy.Interfaces.SmaliApkToolsPath;
+import com.qy.utils.ApkSignTools;
+import com.qy.utils.AutoOutAPKTools;
+import com.qy.utils.Tools;
+import org.apache.commons.lang3.StringUtils;
+import org.json.JSONObject;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Vector;
+
+public class AutoOutAPKUi {
+ private JPanel panel1;
+ private JTextField packageName;
+ private JTextField gameId;
+ private JTextField jiguang;
+ private JList list1;
+ private JButton addChannel;
+ private JButton removeChannel;
+ private JButton start;
+ private JButton selectAppPath;
+ private JLabel appPath;
+
+ private LinkedHashMap map = new LinkedHashMap<>();
+ private LinkedHashMap channel = new LinkedHashMap<>();
+ private Vector vector = new Vector();
+
+
+ public AutoOutAPKUi() {
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception e) {
+ // TODO: handle exception
+ e.printStackTrace();
+ }
+ JFrame frame = new JFrame("马甲包出包工具1.0");
+ frame.setContentPane(panel1);
+ frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ frame.pack();
+ frame.setSize(420, 400);
+ frame.setVisible(true);
+ initView();
+ }
+
+ private void initView() {
+ list1.setListData(vector);
+ addChannel.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ AutoOutAPKAddChannelUi.newInstance(new DialogInterface() {
+ @Override
+ public void onOut(Object data) {
+ super.onOut(data);
+ Map, ?> channel = (Map, ?>) data;
+ AutoOutAPKUi.this.channel.put((String) channel.get("NAME"), channel);
+ vector.add((String) channel.get("NAME"));
+ list1.setListData(vector);
+ list1.updateUI();
+ }
+ });
+
+ }
+ });
+ removeChannel.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String name = vector.get(list1.getSelectedIndex());
+ vector.remove(list1.getSelectedIndex());
+ channel.remove(name);
+ list1.setListData(vector);
+ list1.updateUI();
+ }
+ });
+ start.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String gid = gameId.getText();
+ String jid = jiguang.getText();
+ String pid = packageName.getText();
+ String path = appPath.getText();
+ if (StringUtils.isEmpty(gid) || StringUtils.isEmpty(pid) || StringUtils.isEmpty(path)) {
+ new TextToDialog("警告", "有参数未填写");
+ return;
+ }
+ Map cmap = new HashMap<>();
+ for (String key : channel.keySet()) {
+ Map, ?> map = (Map, ?>) channel.get(key);
+ for (Object o : map.keySet()) {
+ if (!o.equals("NAME")) {
+ cmap.put((String) o, (String) map.get(o));
+ }
+ }
+ }
+ AutoOutAPKTools tools = new AutoOutAPKTools(gid, cmap);
+ JSONObject json=new JSONObject();
+ JSONObject pa=new JSONObject();
+ JSONObject ji=new JSONObject();
+ pa.put("key","${packagename}");
+ pa.put("value",pid);
+ ji.put("key","${JPUSH_KEY}");
+ ji.put("value",jid);
+ json.put("package=",pa);
+ json.put("JPUSH_APPKEY",ji);
+ tools.setAppPath(path);
+ tools.setManifestMap(json);
+ tools.start(new SmaliApkToolsPath() {
+ @Override
+ public void smaliPath(String path) {
+ LinkedHashMap keyMap=ApkSignUi.loadKeys();
+ Vector adbList = new Vector(keyMap.keySet());
+ JComboBox keysList=new JComboBox(adbList);
+ keysList.setBounds(157, 50, 200, 27);
+ new TextToDialog("选择签名", keysList, new DialogInterface() {
+ @Override
+ public void onSuccess() {
+ String key=adbList.get(keysList.getSelectedIndex());
+ String tmp=keyMap.get(key);
+ if(!StringUtils.isEmpty(tmp)){
+ JSONObject json=new JSONObject(tmp);
+ ApkSignTools signTools=new ApkSignTools();
+ signTools.setSignFile(new File(json.getString("file")));
+ signTools.setApkFile(new File(path));
+ signTools.setKeyStorePassword(json.getString("alias_password"));
+ signTools.setName(json.getString("alias"));
+ signTools.setSignKey(json.getString("password"));
+ if(signTools.sign()){
+ try {
+ String apkName="./apk_out/game_"+System.currentTimeMillis()+".apk";
+ Tools.copyFile(signTools.getApkFile().getAbsolutePath()+"_sign.apk",apkName,true);
+ Desktop.getDesktop().open(new File(apkName).getParentFile());
+ System.out.println("签名完成");
+ } catch (IOException ioException) {
+ ioException.printStackTrace();
+ }
+ tools.clear();
+ }else {
+ new TextToDialog("警告","签名失败");
+ }
+ }
+ }
+ });
+ }
+ });
+ }
+ });
+
+ selectAppPath.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JFileChooser jFile = new JFileChooser(new File(new File("").getAbsolutePath()));
+ jFile.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ jFile.showOpenDialog(null);
+ File path = jFile.getSelectedFile();
+ appPath.setText(path.getAbsolutePath());
+ }
+ });
+ }
+
+ private void createUIComponents() {
+ // TODO: place custom component creation code here
+ }
+
+
+ public static void main(String[] args) {
+ new AutoOutAPKUi();
+ }
+}
diff --git a/src/com/qy/ui/SMSToolsUi.java b/src/com/qy/ui/SMSToolsUi.java
index ec3f81d..0594531 100755
--- a/src/com/qy/ui/SMSToolsUi.java
+++ b/src/com/qy/ui/SMSToolsUi.java
@@ -11,7 +11,7 @@ import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.UIManager;
-import com.qy.Interfaces.DalogAbs;
+import com.qy.Interfaces.DialogInterface;
import com.qy.sms.SDKTools;
import java.awt.Desktop;
@@ -71,7 +71,7 @@ public class SMSToolsUi extends JFrame {
SDKTools.start(new File("").getAbsolutePath());
btnNewButton.setText(path);
btnNewButton.setEnabled(true);
- new TextToDialog("提示", "计费SDK生成成功,请选择保存位置", new DalogAbs() {
+ new TextToDialog("提示", "计费SDK生成成功,请选择保存位置", new DialogInterface() {
File sdk;
@Override
@@ -85,7 +85,7 @@ public class SMSToolsUi extends JFrame {
File sdk_ = new File(
sdk.getAbsolutePath() + "/" + "计费sdk" + SDKTools.version + ".zip");
SDKTools.buildSDK(sdk_);
- new TextToDialog("完成", "任务已完成", new DalogAbs() {
+ new TextToDialog("完成", "任务已完成", new DialogInterface() {
@Override
public void onSuccess() {
diff --git a/src/com/qy/ui/SmaliUi.java b/src/com/qy/ui/SmaliUi.java
index 2cd2b6c..041e929 100755
--- a/src/com/qy/ui/SmaliUi.java
+++ b/src/com/qy/ui/SmaliUi.java
@@ -16,7 +16,7 @@ import javax.swing.border.LineBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
-import com.qy.Interfaces.DalogAbs;
+import com.qy.Interfaces.DialogInterface;
import com.qy.Interfaces.SmaliApkToolsPath;
import com.qy.utils.ApkSignTools;
import com.qy.utils.SmaliUtils;
@@ -361,7 +361,7 @@ public class SmaliUi extends JFrame {
Vector adbList = new Vector(keyMap.keySet());
JComboBox keysList=new JComboBox(adbList);
keysList.setBounds(157, 50, 200, 27);
- new TextToDialog("选择签名", keysList, new DalogAbs() {
+ new TextToDialog("选择签名", keysList, new DialogInterface() {
@Override
public void onSuccess() {
String key=adbList.get(keysList.getSelectedIndex());
diff --git a/src/com/qy/ui/TextToDialog.java b/src/com/qy/ui/TextToDialog.java
index f5676ad..a2e6d08 100644
--- a/src/com/qy/ui/TextToDialog.java
+++ b/src/com/qy/ui/TextToDialog.java
@@ -5,22 +5,22 @@ import java.awt.event.MouseEvent;
import javax.swing.*;
-import com.qy.Interfaces.DalogAbs;
+import com.qy.Interfaces.DialogInterface;
public class TextToDialog extends JFrame {
/**
*
*/
- DalogAbs abs;
+ DialogInterface abs;
private static final long serialVersionUID = 1L;
- public TextToDialog(String title, String text, DalogAbs abs) {
+ public TextToDialog(String title, String text, DialogInterface abs) {
super(title);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.abs=abs;
initView(text,null);
}
- public TextToDialog(String title, JComponent view,DalogAbs abs){
+ public TextToDialog(String title, JComponent view, DialogInterface abs){
super(title);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.abs=abs;
diff --git a/src/com/qy/utils/ApkSignTools.java b/src/com/qy/utils/ApkSignTools.java
index 7630c4e..b5970a2 100644
--- a/src/com/qy/utils/ApkSignTools.java
+++ b/src/com/qy/utils/ApkSignTools.java
@@ -74,6 +74,7 @@ public class ApkSignTools {
}
public void setApkFile(File apkFile) {
this.apkFile = apkFile;
+ System.out.println("APK:"+apkFile.getAbsolutePath());
}
public boolean chack() {
// TODO Auto-generated method stub
diff --git a/src/com/qy/utils/AutoOutAPKTools.java b/src/com/qy/utils/AutoOutAPKTools.java
new file mode 100644
index 0000000..44869bd
--- /dev/null
+++ b/src/com/qy/utils/AutoOutAPKTools.java
@@ -0,0 +1,116 @@
+package com.qy.utils;
+
+import com.qy.Interfaces.SmaliApkToolsPath;
+import com.qy.ui.ApkSignUi;
+import org.json.JSONObject;
+
+import javax.swing.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+public class AutoOutAPKTools {
+ private String gameId;
+ private Map channel;
+ private JSONObject manifestMap;
+ private String appPath;
+ private SmaliApkToolsPath inter;
+
+ public AutoOutAPKTools(String gameId, Map channel) {
+ this.gameId = gameId;
+ this.channel = channel;
+ }
+ public void setAppPath(String path){
+ this.appPath=path;
+ }
+ public void setManifestMap(JSONObject map){
+ this.manifestMap=map;
+ }
+ public void start(SmaliApkToolsPath inter){
+ this.inter=inter;
+ outLog("复制游戏文件夹");
+ String newAppPath=appPath+"_"+gameId+"_"+Tools.getRandomString(6);
+ Tools.copy_dir(appPath,newAppPath);
+ outLog("游戏游戏文件夹复制完成");
+ appPath=newAppPath;
+ outLog("修改Manifest");
+ alterManifest(new File(appPath+File.separator+"AndroidManifest.xml"));
+ outLog("Manifest修改完成,开始生成assets");
+ outAssets();
+ outLog("生成完毕");
+ new SmaliUtils().bale(appPath, appPath + File.separator + "game_.apk", new SmaliApkToolsPath() {
+ @Override
+ public void smaliPath(String path) {
+ inter.smaliPath(appPath + File.separator + "game_.apk");
+ }
+ });
+ }
+ public void clear(){
+ Tools.deleteFiles(appPath);
+ }
+ private void alterManifest(File manifest){
+ String tmp;
+ StringBuilder str = new StringBuilder();
+ try {
+ List keys=new ArrayList<>(manifestMap.keySet());
+
+ BufferedReader reader = new BufferedReader( new InputStreamReader(new FileInputStream(manifest), StandardCharsets.UTF_8));
+ while ((tmp = reader.readLine()) != null) {
+ for (String key : keys) {
+ if(tmp.contains(key)){
+ JSONObject json=manifestMap.getJSONObject(key);
+ tmp=tmp.replace(json.getString("key"),json.getString("value"));
+ }
+ }
+ str.append(tmp).append("\n");
+ }
+ reader.close();
+ Tools.saveConfig(manifest,str.toString());
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ System.out.println(str);
+ }
+ }
+ private void outAssets(){
+ StringBuilder builder=new StringBuilder();
+ builder.append("GAME_ID=").append(gameId).append("\n");
+ for (String key : channel.keySet()) {
+ builder.append(key).append("=").append(channel.get(key)).append("\n");
+ }
+ Tools.saveConfig(new File(appPath+File.separator+"assets"+File.separator+"kusdkconf.ini"),
+ builder.toString());
+ }
+ private void outLog(String log){
+ System.out.println(log);
+ }
+
+ public static void main(String[] args) {
+ JSONObject json=new JSONObject();
+ JSONObject pa=new JSONObject();
+ JSONObject ji=new JSONObject();
+ pa.put("key","${packagename}");
+ pa.put("value","com.abc.def");
+ ji.put("key","${JPUSH_KEY}");
+ ji.put("value","aaabbccd");
+ json.put("package=",pa);
+ json.put("JPUSH_APPKEY",ji);
+
+ Map channel=new HashMap<>();
+ channel.put("TOUTIAO_APP_ID","112345");
+ AutoOutAPKTools tools=new AutoOutAPKTools(
+ "123456",
+ channel);
+ tools.setAppPath("C:\\Users\\admin\\Documents\\游戏母包\\仙侠神域\\xianxiashenyu_29321_wozaijianghukey_xxsy_1627");
+ tools.setManifestMap(json);
+ tools.start(new SmaliApkToolsPath() {
+ @Override
+ public void smaliPath(String path) {
+ System.out.println("ok:"+path);
+ }
+ });
+ }
+}
diff --git a/src/com/qy/utils/Tools.java b/src/com/qy/utils/Tools.java
index 1ac3870..17af3ab 100755
--- a/src/com/qy/utils/Tools.java
+++ b/src/com/qy/utils/Tools.java
@@ -365,4 +365,21 @@ public class Tools {
System.out.println(System.getProperties().getProperty("os.name"));
return System.getProperties().getProperty("os.name").toLowerCase().contains("windows");
}
+
+ public static String readFile(File manifest) {
+ String tmp;
+ StringBuilder str = new StringBuilder();
+ try {
+ BufferedReader reader = new BufferedReader( new InputStreamReader(new FileInputStream(manifest), StandardCharsets.UTF_8));
+ while ((tmp = reader.readLine()) != null) {
+ str.append(tmp);
+ }
+ reader.close();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ System.out.println(str);
+ }
+ return str.toString();
+ }
}