需求:
unity将游戏导出android工程之后,打成aar包的工具
第一种:
高版本的unity导出的android工程是android studio版的,那么打成aar的流程就是
1.build.gradle文件中把apply plugin: 'com.android.application'改成apply plugin: 'com.android.library' 2.build.gradle文件中buildToolsVersion改为25.0.2 3.注释掉applicationId这一行 4.清单文件AndroidManifest.xml中启动Activity,一般是UnityPlayerActiity,标签内全部删除 5.src.java下类UnityPlayerActiity共三个都删除 6.然后在主目录下执行命令gradlew.bat assembleDebug生成aar
把上述流程做成java自动的工具,代码如下
package com.jinkejoy.build_aar; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.Map; import java.util.Properties; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextField; public class ASBuildAarFile { private static final String CACHE_PATH = "C:\build-apk-path.properties"; private JFrame jFrame; private JTextField sourcePath_text; private JButton sourcePath_button; private File sourceFile; private JTextField output_text; private JButton output_button; private File outputFile; private JTextField sdk_text; private JButton sdk_button; private File sdkFile; private JTextField ndk_text; private JButton ndk_button; private File ndkFile; private JButton buildAar_button; private JButton outputAar_button; public static void main(String[] args) { new ASBuildAarFile(); } public ASBuildAarFile() { openFileWindow(); } private void openFileWindow() { jFrame = new JFrame(); jFrame.setTitle("将android工程打成aar"); jFrame.setBounds(500, 500, 700, 200); jFrame.setVisible(true); FlowLayout layout = new FlowLayout(); layout.setAlignment(FlowLayout.LEFT); //选择文件 JLabel filePath_label = new JLabel("工程路径:"); sourcePath_text = new JTextField(50); sourcePath_button = new JButton("浏览"); //输出路径 JLabel output_label = new JLabel("出包路径:"); output_text = new JTextField(50); output_button = new JButton("浏览"); //sdk JLabel sdk_label = new JLabel("本地sdk路径:"); sdk_text = new JTextField(48); sdk_button = new JButton("浏览"); //ndk JLabel ndk_label = new JLabel("本地ndk路径(sdk路径下):"); ndk_text = new JTextField(42); ndk_button = new JButton("浏览"); //构建 buildAar_button = new JButton("构建aar"); outputAar_button = new JButton("弹出aar(构建aar成功后再点)"); jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jFrame.setLayout(layout); jFrame.setResizable(false); jFrame.add(filePath_label); jFrame.add(sourcePath_text); jFrame.add(sourcePath_button); jFrame.add(output_label); jFrame.add(output_text); jFrame.add(output_button); jFrame.add(sdk_label); jFrame.add(sdk_text); jFrame.add(sdk_button); jFrame.add(ndk_label); jFrame.add(ndk_text); jFrame.add(ndk_button); jFrame.add(buildAar_button); jFrame.add(outputAar_button); choosePath(); outputPath(); sdkPath(); ndkPath(); buildAar(); outputAar(); getCachePath(); } public void choosePath() { sourcePath_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); chooser.showDialog(new JLabel(), "选择"); sourceFile = chooser.getSelectedFile(); sourcePath_text.setText(sourceFile.getAbsolutePath().toString()); } }); } private void outputPath() { output_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); chooser.showDialog(new JLabel(), "选择"); outputFile = chooser.getSelectedFile(); output_text.setText(outputFile.getAbsolutePath().toString()); } }); } private void sdkPath() { sdk_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); chooser.showDialog(new JLabel(), "选择"); sdkFile = chooser.getSelectedFile(); sdk_text.setText(sdkFile.getAbsolutePath().toString()); } }); } private void ndkPath() { ndk_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); chooser.showDialog(new JLabel(), "选择"); ndkFile = chooser.getSelectedFile(); ndk_text.setText(ndkFile.getAbsolutePath().toString()); } }); } private void buildAar() { buildAar_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { buildAarImpl(); } }); } private void outputAar() { outputAar_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { outputAarImpl(sourcePath_text.getText().toString()); } }); } private void cachePath() { String cache = "sourcePath=" + sourcePath_text.getText().toString().replace("\", "\\") + " " + "outputPath=" + output_text.getText().toString().replace("\", "\\") + " " + "sdkPath=" + sdk_text.getText().toString().replace("\", "\\") + " " + "ndkPath=" + ndk_text.getText().toString().replace("\", "\\") + " "; File cacheFile = new File(CACHE_PATH); if (!cacheFile.exists()) { try { cacheFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } try { FileOutputStream fop = new FileOutputStream(cacheFile); fop.write(cache.getBytes()); fop.flush(); fop.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void getCachePath() { File cacheFile = new File(CACHE_PATH); if (cacheFile.exists()) { try { FileInputStream fip = new FileInputStream(cacheFile); Properties properties = new Properties(); properties.load(fip); Iterator<Map.Entry<Object, Object>> iterator = properties.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<Object, Object> entry = iterator.next(); switch (entry.getKey().toString()) { case "sourcePath": sourcePath_text.setText(entry.getValue().toString()); break; case "outputPath": output_text.setText(entry.getValue().toString()); break; case "sdkPath": sdk_text.setText(entry.getValue().toString()); break; case "ndkPath": ndk_text.setText(entry.getValue().toString()); break; } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } private void buildAarImpl() { if (checkInput()) return; cachePath(); String filePath = sourcePath_text.getText().toString(); findUpdateFile(filePath); gradleBuildAar(); } private void gradleBuildAar() { String command = "cmd /c start gradle clean assembleDebug"; File cmdPath = new File(sourcePath_text.getText().toString()); Runtime runtime = Runtime.getRuntime(); try { Process process = runtime.exec(command, null, cmdPath); } catch (IOException e) { e.printStackTrace(); } } private void outputAarImpl(String filePath) { if (checkInput()) return; findAarFile(filePath); String command = "cmd /k start " + output_text.getText().toString(); Runtime runtime = Runtime.getRuntime(); try { runtime.exec(command); } catch (IOException e) { e.printStackTrace(); } } private void findAarFile(String filePath) { File file = new File(filePath); if (!file.exists()) { return; } File[] files = file.listFiles(); for (File outputFile : files) { if (outputFile.isDirectory()) { findAarFile(outputFile.getAbsolutePath()); } else { String fileName = outputFile.getName().toString(); if (fileName.endsWith(".aar")) { String time = timeStamp2Date(String.valueOf(System.currentTimeMillis())); String aarName = fileName.substring(0, fileName.length() - 4); File aarFile = new File(output_text.getText().toString() + "\" + aarName + time + ".aar"); outputFile.renameTo(aarFile); } } } } private void findUpdateFile(String filePath) { File file = new File(filePath); if (!file.exists()) { return; } File[] files = file.listFiles(); for (File updateFile : files) { if (updateFile.isDirectory()) { findUpdateFile(updateFile.getAbsolutePath()); } else { switch (updateFile.getName().toString()) { case "build.gradle": updateBuildGradle(updateFile.getAbsolutePath()); break; case "AndroidManifest.xml": updateManifestFile(updateFile.getAbsolutePath()); break; case "local.properties": updateSdkFile(updateFile.getAbsolutePath()); break; case "UnityPlayerActivity.java": case "UnityPlayerNativeActivity.java": case "UnityPlayerProxyActivity.java": updateFile.delete(); break; } } } } private void updateSdkFile(String filePath) { try { RandomAccessFile sdkFile = new RandomAccessFile(filePath, "rw"); String line; long lastPoint = 0; while ((line = sdkFile.readLine()) != null) { final long point = sdkFile.getFilePointer(); if (line.contains("sdk.dir")) { String s = line.substring(0); String sdkStr = sdk_text.getText().toString(); String sdkPan = sdkStr.substring(0, 1); sdkStr = sdkStr.substring(1).replace("\", "\\"); String ndkStr = ndk_text.getText().toString(); String ndkPan = ndkStr.substring(0, 1); ndkStr = ndkStr.substring(1).replace("\", "\\"); String replaceStr = "sdk.dir=" + sdkPan + "\" + sdkStr + " " + "ndk.dir=" + ndkPan + "\" + ndkStr + " "; String str = line.replace(s, replaceStr); sdkFile.seek(lastPoint); sdkFile.writeBytes(str); } lastPoint = point; } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void updateManifestFile(String filePath) { try { RandomAccessFile manifestFile = new RandomAccessFile(filePath, "rw"); String line; long lastPoint = 0; while ((line = manifestFile.readLine()) != null) { final long ponit = manifestFile.getFilePointer(); if (line.contains("<activity") && line.contains("UnityPlayerActivity") && !line.contains("<!--<activity")) { String str = line.replace("<activity", "<!--<activity"); manifestFile.seek(lastPoint); manifestFile.writeBytes(str); } if (line.contains("</activity>") && !line.contains("</activity>-->")) { String str = line.replace("</activity>", "</activity>--> "); manifestFile.seek(lastPoint); manifestFile.writeBytes(str); } lastPoint = ponit; } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void updateBuildGradle(String filePath) { try { RandomAccessFile buildGradleFile = new RandomAccessFile(filePath, "rw"); String line; long lastPoint = 0; while ((line = buildGradleFile.readLine()) != null) { final long ponit = buildGradleFile.getFilePointer(); if (line.contains("classpath 'com.android.tools.build:gradle")) { String s = line.substring(line.indexOf("classpath")); String str = line.replace(s, "classpath 'com.android.tools.build:gradle:2.3.0' "); buildGradleFile.seek(lastPoint); buildGradleFile.writeBytes(str); } if (line.contains("com.android.application")) { String str = line.replace("'com.android.application'", "'com.android.library' "); buildGradleFile.seek(lastPoint); buildGradleFile.writeBytes(str); } if (line.contains("compileSdkVersion") && !line.contains("compileSdkVersion 25")) { String s = line.substring(line.indexOf("compileSdkVersion")).toString(); String str = line.replace(s, "compileSdkVersion 25 "); buildGradleFile.seek(lastPoint); buildGradleFile.writeBytes(str); } if (line.contains("buildToolsVersion") && !line.contains("buildToolsVersion '25.0.2'")) { String s = line.substring(line.indexOf("buildToolsVersion")).toString(); String str = line.replace(s, "buildToolsVersion '25.0.2' "); buildGradleFile.seek(lastPoint); buildGradleFile.writeBytes(str); } if (line.contains("targetSdkVersion") && !line.contains("targetSdkVersion 25")) { String s = line.substring(line.indexOf("targetSdkVersion")).toString(); String str = line.replace(s, "targetSdkVersion 25 "); buildGradleFile.seek(lastPoint); buildGradleFile.writeBytes(str); } if (line.contains("applicationId") && !line.contains("//applicationId")) { String s = line.substring(line.indexOf("applicationId")).toString(); String str = line.replace(s, "//" + s + " "); buildGradleFile.seek(lastPoint); buildGradleFile.writeBytes(str); } lastPoint = ponit; } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private boolean checkInput() { if ("".equals(sourcePath_text.getText().toString())) { JOptionPane.showMessageDialog(jFrame, "请输入源工程文件路径"); return true; } if ("".equals(output_text.getText().toString())) { JOptionPane.showMessageDialog(jFrame, "请输入apk输出路径"); return true; } if ("".equals(sdk_text.getText().toString())) { JOptionPane.showMessageDialog(jFrame, "请输入本地sdk路径"); return true; } if ("".equals(ndk_text.getText().toString())) { JOptionPane.showMessageDialog(jFrame, "请输入本地ndk路径"); return true; } return false; } public static String timeStamp2Date(String time) { Long timeLong = Long.parseLong(time); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");//要转换的时间格式 Date date; try { date = sdf.parse(sdf.format(timeLong)); return sdf.format(date); } catch (ParseException e) { e.printStackTrace(); return null; } } }
方法名写的很清楚,我就不加注释了。
jar包打成可运行程序参考android studio打可执行jar包
第二种:
低版本的unity导出的android工程是Eclipse版的
Eclipse版的android工程和android studio版的android工程还是有不小区别的,
android studio版eclipse版
所以我增加了一个母包,用于把eclipse版变成android studio版,代码如下
package com.jinkejoy.build_aar; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.Map; import java.util.Properties; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextField; public class EcBuildAarFile { private static final String CACHE_PATH = "C:\build-apk-path.properties"; private JFrame jFrame; private JTextField sourcePath_text; private JButton sourcePath_button; private File sourceFile; private JTextField output_text; private JButton output_button; private File outputFile; private JTextField sdk_text; private JButton sdk_button; private File sdkFile; private JTextField ndk_text; private JButton ndk_button; private File ndkFile; private JTextField main_text; private JButton main_button; private File mainFile; private JButton buildAar_button; private JButton outputAar_button; public static void main(String[] args) { new EcBuildAarFile(); } public EcBuildAarFile() { openFileWindow(); } private void openFileWindow() { jFrame = new JFrame(); jFrame.setTitle("将android工程打成aar"); jFrame.setBounds(500, 500, 700, 250); jFrame.setVisible(true); FlowLayout layout = new FlowLayout(); layout.setAlignment(FlowLayout.LEFT); //选择文件 JLabel filePath_label = new JLabel("工程路径:"); sourcePath_text = new JTextField(50); sourcePath_button = new JButton("浏览"); //输出路径 JLabel output_label = new JLabel("出包路径:"); output_text = new JTextField(50); output_button = new JButton("浏览"); //sdk JLabel sdk_label = new JLabel("本地sdk路径:"); sdk_text = new JTextField(48); sdk_button = new JButton("浏览"); //ndk JLabel ndk_label = new JLabel("本地ndk路径(sdk路径下):"); ndk_text = new JTextField(42); ndk_button = new JButton("浏览"); //母包 JLabel main_label = new JLabel("本地母包文件路径:"); main_text = new JTextField(45); main_button = new JButton("浏览"); //构建 buildAar_button = new JButton("构建aar"); outputAar_button = new JButton("弹出aar(构建aar成功后再点)"); jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jFrame.setLayout(layout); jFrame.setResizable(false); jFrame.add(filePath_label); jFrame.add(sourcePath_text); jFrame.add(sourcePath_button); jFrame.add(output_label); jFrame.add(output_text); jFrame.add(output_button); jFrame.add(sdk_label); jFrame.add(sdk_text); jFrame.add(sdk_button); jFrame.add(ndk_label); jFrame.add(ndk_text); jFrame.add(ndk_button); jFrame.add(main_label); jFrame.add(main_text); jFrame.add(main_button); jFrame.add(buildAar_button); jFrame.add(outputAar_button); choosePath(); outputPath(); sdkPath(); ndkPath(); mainPath(); buildAar(); outputAar(); getCachePath(); } public void choosePath() { sourcePath_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); chooser.showDialog(new JLabel(), "选择"); sourceFile = chooser.getSelectedFile(); sourcePath_text.setText(sourceFile.getAbsolutePath().toString()); } }); } private void outputPath() { output_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); chooser.showDialog(new JLabel(), "选择"); outputFile = chooser.getSelectedFile(); output_text.setText(outputFile.getAbsolutePath().toString()); } }); } private void sdkPath() { sdk_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); chooser.showDialog(new JLabel(), "选择"); sdkFile = chooser.getSelectedFile(); sdk_text.setText(sdkFile.getAbsolutePath().toString()); } }); } private void ndkPath() { ndk_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); chooser.showDialog(new JLabel(), "选择"); ndkFile = chooser.getSelectedFile(); ndk_text.setText(ndkFile.getAbsolutePath().toString()); } }); } private void mainPath() { main_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); chooser.showDialog(new JLabel(), "选择"); mainFile = chooser.getSelectedFile(); main_text.setText(mainFile.getAbsolutePath().toString()); } }); } private void buildAar() { buildAar_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { buildAarImpl(); } }); } private void outputAar() { outputAar_button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { outputAarImpl(main_text.getText().toString()); } }); } private void cachePath() { String cache = "sourcePath=" + sourcePath_text.getText().toString().replace("\", "\\") + " " + "outputPath=" + output_text.getText().toString().replace("\", "\\") + " " + "sdkPath=" + sdk_text.getText().toString().replace("\", "\\") + " " + "ndkPath=" + ndk_text.getText().toString().replace("\", "\\") + " " + "mainPath=" + main_text.getText().toString().replace("\", "\\"); File cacheFile = new File(CACHE_PATH); if (!cacheFile.exists()) { try { cacheFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } try { FileOutputStream fop = new FileOutputStream(cacheFile); fop.write(cache.getBytes()); fop.flush(); fop.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void getCachePath() { File cacheFile = new File(CACHE_PATH); if (cacheFile.exists()) { try { FileInputStream fip = new FileInputStream(cacheFile); Properties properties = new Properties(); properties.load(fip); Iterator<Map.Entry<Object, Object>> iterator = properties.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<Object, Object> entry = iterator.next(); switch (entry.getKey().toString()) { case "sourcePath": sourcePath_text.setText(entry.getValue().toString()); break; case "outputPath": output_text.setText(entry.getValue().toString()); break; case "sdkPath": sdk_text.setText(entry.getValue().toString()); break; case "ndkPath": ndk_text.setText(entry.getValue().toString()); break; case "mainPath": main_text.setText(entry.getValue().toString()); break; } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } private void buildAarImpl() { if (checkInput()) return; cachePath(); createAs(); findUpdateFile(main_text.getText().toString()); gradleBuildAar(); } private void createAs() { String sourcePath = sourcePath_text.getText().toString(); String mainPath = main_text.getText().toString(); //delete history String deletePath = mainPath + "\app\src\main"; delAllFile(deletePath); String buildPath1 = mainPath + "\build"; delFolder(buildPath1); String buildPath2 = mainPath + "\app\build"; delFolder(buildPath2); //assets String assets = sourcePath + "\assets"; String newAssets = mainPath + "\app\src\main\assets"; copyFolder(assets, newAssets); //unity-classes.jar String unity = sourcePath + "\libs\unity-classes.jar"; String newUnity = mainPath + "\app\libs\unity-classes.jar"; copyFile(new File(unity), new File(newUnity)); //libs String libs = sourcePath + "\libs"; String jniLibs = mainPath + "\app\src\main\jniLibs"; copyFolder(libs, jniLibs); File jni_unity = new File(jniLibs + "\unity-classes.jar"); jni_unity.delete(); //res String res = sourcePath + "\res"; String newRes = mainPath + "\app\src\main\res"; copyFolder(res, newRes); //src String src = sourcePath + "\src"; String java = mainPath + "\app\src\main\java"; copyFolder(src, java); //AndroidManifest.xml String manifest = sourcePath + "\AndroidManifest.xml"; String newManifest = mainPath + "\app\src\main\AndroidManifest.xml"; copyFile(new File(manifest), new File(newManifest)); } public boolean delAllFile(String path) { boolean flag = false; File file = new File(path); if (!file.exists()) { return flag; } if (!file.isDirectory()) { return flag; } String[] tempList = file.list(); File temp = null; for (int i = 0; i < tempList.length; i++) { if (path.endsWith(File.separator)) { temp = new File(path + tempList[i]); } else { temp = new File(path + File.separator + tempList[i]); } if (temp.isFile()) { temp.delete(); } if (temp.isDirectory()) { delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件 delFolder(path + "/" + tempList[i]);//再删除空文件夹 flag = true; } } return flag; } public void delFolder(String folderPath) { try { delAllFile(folderPath); //删除完里面所有内容 String filePath = folderPath; filePath = filePath.toString(); java.io.File myFilePath = new java.io.File(filePath); myFilePath.delete(); //删除空文件夹 } catch (Exception e) { e.printStackTrace(); } } private static void copyFile(File source, File dest) { FileChannel inputChannel = null; FileChannel outputChannel = null; try { inputChannel = new FileInputStream(source).getChannel(); outputChannel = new FileOutputStream(dest).getChannel(); outputChannel.transferFrom(inputChannel, 0, inputChannel.size()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { inputChannel.close(); } catch (IOException e) { e.printStackTrace(); } try { outputChannel.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void copyFolder(String oldPath, String newPath) { try { // 如果文件夹不存在,则建立新文件夹 (new File(newPath)).mkdirs(); // 读取整个文件夹的内容到file字符串数组,下面设置一个游标i,不停地向下移开始读这个数组 File filelist = new File(oldPath); String[] file = filelist.list(); // 要注意,这个temp仅仅是一个临时文件指针 // 整个程序并没有创建临时文件 File temp = null; for (int i = 0; i < file.length; i++) { // 如果oldPath以路径分隔符/或者结尾,那么则oldPath/文件名就可以了 // 否则要自己oldPath后面补个路径分隔符再加文件名 // 谁知道你传递过来的参数是f:/a还是f:/a/啊? if (oldPath.endsWith(File.separator)) { temp = new File(oldPath + file[i]); } else { temp = new File(oldPath + File.separator + file[i]); } // 如果游标遇到文件 if (temp.isFile()) { FileInputStream input = new FileInputStream(temp); // 复制并且改名 FileOutputStream output = new FileOutputStream(newPath + "/" + (temp.getName()).toString()); byte[] bufferarray = new byte[1024 * 64]; int prereadlength; while ((prereadlength = input.read(bufferarray)) != -1) { output.write(bufferarray, 0, prereadlength); } output.flush(); output.close(); input.close(); } // 如果游标遇到文件夹 if (temp.isDirectory()) { copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]); } } } catch (Exception e) { System.out.println("复制整个文件夹内容操作出错"); } } private void gradleBuildAar() { String command = "cmd /c start gradle clean assembleDebug"; File cmdPath = new File(main_text.getText().toString()); Runtime runtime = Runtime.getRuntime(); try { Process process = runtime.exec(command, null, cmdPath); } catch (IOException e) { e.printStackTrace(); } } private void outputAarImpl(String filePath) { if (checkInput()) return; findAarFile(filePath); String command = "cmd /k start " + output_text.getText().toString(); Runtime runtime = Runtime.getRuntime(); try { runtime.exec(command); } catch (IOException e) { e.printStackTrace(); } } private void findAarFile(String filePath) { File file = new File(filePath); if (!file.exists()) { return; } File[] files = file.listFiles(); for (File outputFile : files) { if (outputFile.isDirectory()) { findAarFile(outputFile.getAbsolutePath()); } else { String fileName = outputFile.getName().toString(); if (fileName.endsWith(".aar")) { String time = timeStamp2Date(String.valueOf(System.currentTimeMillis())); String aarName = fileName.substring(0, fileName.length() - 4); File aarFile = new File(output_text.getText().toString() + "\" + aarName + time + ".aar"); outputFile.renameTo(aarFile); } } } } private void findUpdateFile(String filePath) { File file = new File(filePath); if (!file.exists()) { return; } File[] files = file.listFiles(); for (File updateFile : files) { if (updateFile.isDirectory()) { findUpdateFile(updateFile.getAbsolutePath()); } else { switch (updateFile.getName().toString()) { case "build.gradle": updateBuildGradle(updateFile.getAbsolutePath()); break; case "AndroidManifest.xml": updateManifestFile(updateFile.getAbsolutePath()); break; case "local.properties": updateSdkFile(updateFile.getAbsolutePath()); break; case "UnityPlayerActivity.java": case "UnityPlayerNativeActivity.java": case "UnityPlayerProxyActivity.java": updateFile.delete(); break; } } } } private void updateSdkFile(String filePath) { try { RandomAccessFile sdkFile = new RandomAccessFile(filePath, "rw"); String line; long lastPoint = 0; while ((line = sdkFile.readLine()) != null) { final long point = sdkFile.getFilePointer(); if (line.contains("sdk.dir")) { String s = line.substring(0); String sdkStr = sdk_text.getText().toString(); String sdkPan = sdkStr.substring(0, 1); sdkStr = sdkStr.substring(1).replace("\", "\\"); String ndkStr = ndk_text.getText().toString(); String ndkPan = ndkStr.substring(0, 1); ndkStr = ndkStr.substring(1).replace("\", "\\"); String replaceStr = "sdk.dir=" + sdkPan + "\" + sdkStr + " " + "ndk.dir=" + ndkPan + "\" + ndkStr + " "; String str = line.replace(s, replaceStr); sdkFile.seek(lastPoint); sdkFile.writeBytes(str); } lastPoint = point; } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void updateManifestFile(String filePath) { try { RandomAccessFile manifestFile = new RandomAccessFile(filePath, "rw"); String line; long lastPoint = 0; while ((line = manifestFile.readLine()) != null) { final long ponit = manifestFile.getFilePointer(); if (line.contains("<activity") && line.contains("UnityPlayerActivity") && !line.contains("<!--<activity")) { String str = line.replace("<activity", "<!--<activity"); manifestFile.seek(lastPoint); manifestFile.writeBytes(str); } if (line.contains("</activity>") && !line.contains("</activity>-->")) { String str = line.replace("</activity>", "</activity>--> "); manifestFile.seek(lastPoint); manifestFile.writeBytes(str); } lastPoint = ponit; } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void updateBuildGradle(String filePath) { try { RandomAccessFile buildGradleFile = new RandomAccessFile(filePath, "rw"); String line; long lastPoint = 0; while ((line = buildGradleFile.readLine()) != null) { final long ponit = buildGradleFile.getFilePointer(); if (line.contains("classpath 'com.android.tools.build:gradle")) { String s = line.substring(line.indexOf("classpath")); String str = line.replace(s, "classpath 'com.android.tools.build:gradle:2.3.0' "); buildGradleFile.seek(lastPoint); buildGradleFile.writeBytes(str); } if (line.contains("com.android.application")) { String str = line.replace("'com.android.application'", "'com.android.library' "); buildGradleFile.seek(lastPoint); buildGradleFile.writeBytes(str); } if (line.contains("compileSdkVersion") && !line.contains("compileSdkVersion 25")) { String s = line.substring(line.indexOf("compileSdkVersion")).toString(); String str = line.replace(s, "compileSdkVersion 25 "); buildGradleFile.seek(lastPoint); buildGradleFile.writeBytes(str); } if (line.contains("buildToolsVersion") && !line.contains("buildToolsVersion '25.0.2'")) { String s = line.substring(line.indexOf("buildToolsVersion")).toString(); String str = line.replace(s, "buildToolsVersion '25.0.2' "); buildGradleFile.seek(lastPoint); buildGradleFile.writeBytes(str); } if (line.contains("targetSdkVersion") && !line.contains("targetSdkVersion 25")) { String s = line.substring(line.indexOf("targetSdkVersion")).toString(); String str = line.replace(s, "targetSdkVersion 25 "); buildGradleFile.seek(lastPoint); buildGradleFile.writeBytes(str); } if (line.contains("applicationId") && !line.contains("//applicationId")) { String s = line.substring(line.indexOf("applicationId")).toString(); String str = line.replace(s, "//" + s + " "); buildGradleFile.seek(lastPoint); buildGradleFile.writeBytes(str); } lastPoint = ponit; } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private boolean checkInput() { if ("".equals(sourcePath_text.getText().toString())) { JOptionPane.showMessageDialog(jFrame, "请输入源工程文件路径"); return true; } if ("".equals(output_text.getText().toString())) { JOptionPane.showMessageDialog(jFrame, "请输入apk输出路径"); return true; } if ("".equals(sdk_text.getText().toString())) { JOptionPane.showMessageDialog(jFrame, "请输入本地sdk路径"); return true; } if ("".equals(ndk_text.getText().toString())) { JOptionPane.showMessageDialog(jFrame, "请输入本地ndk路径"); return true; } return false; } public static String timeStamp2Date(String time) { Long timeLong = Long.parseLong(time); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");//要转换的时间格式 Date date; try { date = sdf.parse(sdf.format(timeLong)); return sdf.format(date); } catch (ParseException e) { e.printStackTrace(); return null; } } }
效果图