| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
- package com.jme3.gde.android;
- import java.io.BufferedOutputStream;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.OutputStreamWriter;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- import org.netbeans.api.project.Project;
- import org.openide.DialogDisplayer;
- import org.openide.NotifyDescriptor;
- import org.openide.NotifyDescriptor.Message;
- import org.openide.filesystems.FileChooserBuilder;
- import org.openide.filesystems.FileLock;
- import org.openide.filesystems.FileObject;
- import org.openide.filesystems.FileUtil;
- import org.openide.util.Exceptions;
- import org.openide.util.NbPreferences;
- import org.openide.util.Utilities;
- import org.openide.xml.XMLUtil;
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- import org.xml.sax.InputSource;
- import org.xml.sax.SAXException;
- /**
- *
- * @author normenhansen
- */
- public class AndroidSdkTool {
- /**
- * Starts the Android target configuration utility.
- */
- public static void startAndroidTool() {
- startAndroidTool(false);
- }
- public static void startAndroidTool(boolean modal) {
- final String path = getAndroidToolPath();
- if (path == null) {
- return;
- }
- Thread thread = new Thread(new Runnable() {
- @Override
- public void run() {
- String[] command = new String[]{path};
- ProcessBuilder builder = new ProcessBuilder(command);
- try {
- Process proc = builder.start();
- OutputReader outReader = new OutputReader(proc.getInputStream());
- OutputReader errReader = new OutputReader(proc.getErrorStream());
- outReader.start();
- errReader.start();
- proc.waitFor();
- } catch (InterruptedException ex) {
- Exceptions.printStackTrace(ex);
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
- }
- });
- if (modal) {
- thread.run();
- } else {
- thread.start();
- }
- }
- /**
- * Returns a FileObject for the android SDK folder, null if none is specified
- * @return
- */
- public static FileObject getSdkFolder() {
- String path = getSdkPath();
- if (path == null) {
- return null;
- }
- FileObject fileObj = FileUtil.toFileObject(new File(path));
- if (fileObj == null) {
- return null;
- }
- return fileObj;
- }
- /**
- * Returns a String with the path to the SDK or null if none is specified.
- * @return
- */
- public static String getSdkPath() {
- String path = NbPreferences.forModule(AndroidSdkTool.class).get("sdk_path", null);
- if (path == null) {
- FileChooserBuilder builder = new FileChooserBuilder(AndroidSdkTool.class);
- builder.setTitle("Please select Android SDK Folder");
- builder.setDirectoriesOnly(true);
- File file = builder.showOpenDialog();
- if (file != null) {
- FileObject folder = FileUtil.toFileObject(file);
- if (folder.getFileObject("tools") == null) {
- Message msg = new NotifyDescriptor.Message(
- "Not a valid SDK folder!",
- NotifyDescriptor.ERROR_MESSAGE);
- DialogDisplayer.getDefault().notifyLater(msg);
- } else {
- String name = file.getPath();
- NbPreferences.forModule(AndroidSdkTool.class).put("sdk_path", name);
- return name;
- }
- }
- } else {
- return path;
- }
- return null;
- }
- /**
- * Returns a string with the path to the android tool, specific for platform (.exe for windows)
- * @return
- */
- public static String getAndroidToolPath() {
- FileObject executable = null;
- FileObject folder = getSdkFolder();
- if (folder == null) {
- return null;
- }
- if (Utilities.isWindows()) {
- executable = folder.getFileObject("tools/android.bat");
- } else {
- executable = folder.getFileObject("tools/android");
- }
- if (executable != null) {
- return FileUtil.toFile(executable).getPath();
- } else {
- return null;
- }
- }
- /**
- * Gets a list of android targets registered in the SDK
- * @return
- */
- public static List<AndroidTarget> getTargetList() {
- ArrayList<AndroidTarget> list = new ArrayList<AndroidTarget>();
- final String path = getAndroidToolPath();
- if (path == null) {
- return list;
- }
- String[] command = new String[]{path, "list", "targets"};
- ProcessBuilder builder = new ProcessBuilder(command);
- try {
- Process proc = builder.start();
- ListReader outReader = new ListReader(proc.getInputStream(), list);
- OutputReader errReader = new OutputReader(proc.getErrorStream());
- outReader.start();
- errReader.start();
- proc.waitFor();
- } catch (InterruptedException ex) {
- Exceptions.printStackTrace(ex);
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
- return list;
- }
- //TODO: check mainJmeClass
- public static void checkProject(Project project, String target, String name, String activity, String packag, String mainJmeClass) {
- final String path = getAndroidToolPath();
- if (path == null) {
- return;
- }
- FileObject folder = project.getProjectDirectory().getFileObject("mobile");
- if (folder == null) {
- try {
- folder = project.getProjectDirectory().createFolder("mobile");
- createProject(project, target, name, activity, packag, mainJmeClass);
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- return;
- }
- } else {
- updateProject(project, target, name);
- }
- }
- public static void createProject(Project project, String target, String name, String activity, String packag, String mainJmeClass) {
- final String path = getAndroidToolPath();
- if (path == null) {
- return;
- }
- FileObject folder = project.getProjectDirectory().getFileObject("mobile");
- if (folder == null) {
- try {
- folder = project.getProjectDirectory().createFolder("mobile");
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- return;
- }
- }
- String[] command = new String[]{path, "create", "project",
- "--target", target,
- "--name", name,
- "--path", FileUtil.toFile(folder).getPath(),
- "--activity", activity,
- "--package", packag};
- ProcessBuilder builder = new ProcessBuilder(command);
- FileLock lock = null;
- try {
- Process proc = builder.start();
- OutputReader outReader = new OutputReader(proc.getInputStream());
- OutputReader errReader = new OutputReader(proc.getErrorStream());
- outReader.start();
- errReader.start();
- proc.waitFor();
- folder.refresh();
- String mainActName = "mobile/src/" + packag.replaceAll("\\.", "/") + "/MainActivity.java";
- FileObject mainAct = project.getProjectDirectory().getFileObject(mainActName);
- if (mainAct != null) {
- lock = mainAct.lock();
- OutputStreamWriter out = new OutputStreamWriter(new BufferedOutputStream(mainAct.getOutputStream(lock)));
- out.write(mainActivityString(mainJmeClass, packag));
- out.close();
- lock.releaseLock();
- } else {
- Logger.getLogger(AndroidSdkTool.class.getName()).log(Level.WARNING, "Cannot find {0}", mainActName);
- }
- } catch (InterruptedException ex) {
- Exceptions.printStackTrace(ex);
- } catch (IOException ex) {
- if (lock != null) {
- lock.releaseLock();
- }
- Exceptions.printStackTrace(ex);
- }
- updateAndroidManifest(project);
- updateAndroidApplicationName(project, name);
- }
- public static void updateProject(Project project, String target, String name) {
- final String path = getAndroidToolPath();
- if (path == null) {
- return;
- }
- FileObject folder = project.getProjectDirectory().getFileObject("mobile");
- if (folder == null) {
- return;
- }
- String[] command = new String[]{path, "update", "project",
- "--target", target,
- "--name", name,
- "--path", FileUtil.toFile(folder).getPath()};
- ProcessBuilder builder = new ProcessBuilder(command);
- try {
- Process proc = builder.start();
- OutputReader outReader = new OutputReader(proc.getInputStream());
- OutputReader errReader = new OutputReader(proc.getErrorStream());
- outReader.start();
- errReader.start();
- proc.waitFor();
- folder.refresh();
- } catch (InterruptedException ex) {
- Exceptions.printStackTrace(ex);
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
- updateAndroidApplicationName(project, name);
- }
- private static void updateAndroidManifest(Project project) {
- FileObject manifest = project.getProjectDirectory().getFileObject("mobile/AndroidManifest.xml");
- if (manifest == null) {
- Logger.getLogger(AndroidSdkTool.class.getName()).log(Level.WARNING, "Could not find AndroidManifest.xml");
- return;
- }
- InputStream in = null;
- FileLock lock = null;
- OutputStream out = null;
- try {
- in = manifest.getInputStream();
- Document configuration = XMLUtil.parse(new InputSource(in), false, false, null, null);
- in.close();
- in = null;
- boolean changed = false;
- Element sdkApplication = XmlHelper.findChildElement(configuration.getDocumentElement(), "application");
- if (sdkApplication != null) {
- Element sdkActivity = XmlHelper.findChildElement(sdkApplication, "activity");
- if (sdkActivity != null) {
- if (!sdkActivity.hasAttribute("android:launchMode")) {
- sdkActivity.setAttribute("android:launchMode", "singleTask");
- changed = true;
- }
- }
- // add the following after AndroidHarness.screenOrientation is depreciated
- // for jME 3.1
- // if (sdkActivity != null) {
- // if (sdkActivity.hasAttribute("android:screenOrientation")) {
- // String attrScreenOrientation = sdkActivity.getAttribute("android:screenOrientation");
- // } else {
- // Logger.getLogger(AndroidSdkTool.class.getName()).log(Level.INFO, "creating attrScreenOrientation");
- // sdkActivity.setAttribute("android:screenOrientation", "landscape");
- // changed = true;
- // }
- // }
- }
- Element sdkElement = XmlHelper.findChildElement(configuration.getDocumentElement(), "uses-sdk");
- if (sdkElement == null) {
- sdkElement = configuration.createElement("uses-sdk");
- configuration.getDocumentElement().appendChild(sdkElement);
- changed = true;
- }
- if (!"8".equals(sdkElement.getAttribute("android:minSdkVersion"))) {
- sdkElement.setAttribute("android:minSdkVersion", "8");
- changed = true;
- }
- Element screensElement = XmlHelper.findChildElement(configuration.getDocumentElement(), "supports-screens");
- if (screensElement == null) {
- screensElement = configuration.createElement("supports-screens");
- screensElement.setAttribute("android:anyDensity", "true");
- // screensElement.setAttribute("android:xlargeScreens", "true");
- screensElement.setAttribute("android:largeScreens", "true");
- screensElement.setAttribute("android:smallScreens", "true");
- screensElement.setAttribute("android:normalScreens", "true");
- configuration.getDocumentElement().appendChild(screensElement);
- changed = true;
- }
- if (changed) {
- lock = manifest.lock();
- out = manifest.getOutputStream(lock);
- XMLUtil.write(configuration, out, "UTF-8");
- out.close();
- out = null;
- lock.releaseLock();
- lock = null;
- }
- } catch (SAXException ex) {
- Exceptions.printStackTrace(ex);
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- } finally {
- if (lock != null) {
- lock.releaseLock();
- }
- try {
- if (in != null) {
- in.close();
- }
- if (out != null) {
- out.close();
- }
- } catch (IOException ex1) {
- Exceptions.printStackTrace(ex1);
- }
- }
- }
- private static void updateAndroidApplicationName(Project project, String name) {
- FileObject manifest = project.getProjectDirectory().getFileObject("mobile/res/values/strings.xml");
- if (manifest == null) {
- return;
- }
- InputStream in = null;
- FileLock lock = null;
- OutputStream out = null;
- try {
- in = manifest.getInputStream();
- Document configuration = XMLUtil.parse(new InputSource(in), false, false, null, null);
- in.close();
- in = null;
- Element sdkElement = XmlHelper.findChildElementWithAttribute(configuration.getDocumentElement(), "string", "name", "app_name");
- if (sdkElement == null) {
- sdkElement = configuration.createElement("string");
- sdkElement.setAttribute("name", "app_name");
- configuration.getDocumentElement().appendChild(sdkElement);
- }
- if (!sdkElement.getTextContent().trim().equals(name)) {
- sdkElement.setTextContent(name);
- lock = manifest.lock();
- out = manifest.getOutputStream(lock);
- XMLUtil.write(configuration, out, "UTF-8");
- out.close();
- out = null;
- lock.releaseLock();
- lock = null;
- }
- } catch (SAXException ex) {
- Exceptions.printStackTrace(ex);
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- } finally {
- if (lock != null) {
- lock.releaseLock();
- }
- try {
- if (in != null) {
- in.close();
- }
- if (out != null) {
- out.close();
- }
- } catch (IOException ex1) {
- Exceptions.printStackTrace(ex1);
- }
- }
- }
- private static String mainActivityString(String mainClass, String packag) {
- String str =
- "package " + packag + ";\n"
- + " \n"
- + "import android.content.pm.ActivityInfo;\n"
- + "import com.jme3.app.AndroidHarness;\n"
- + "import com.jme3.system.android.AndroidConfigChooser.ConfigType;\n"
- + "import java.util.logging.Level;\n"
- + "import java.util.logging.LogManager;\n"
- + " \n"
- + "public class MainActivity extends AndroidHarness{\n"
- + " \n"
- + " /*\n"
- + " * Note that you can ignore the errors displayed in this file,\n"
- + " * the android project will build regardless.\n"
- + " * Install the 'Android' plugin under Tools->Plugins->Available Plugins\n"
- + " * to get error checks and code completion for the Android project files.\n"
- + " */\n"
- + " \n"
- + " public MainActivity(){\n"
- + " // Set the application class to run\n"
- + " appClass = \"" + mainClass + "\";\n"
- + " // Try ConfigType.FASTEST; or ConfigType.LEGACY if you have problems\n"
- + " eglConfigType = ConfigType.BEST;\n"
- + " // Exit Dialog title & message\n"
- + " exitDialogTitle = \"Exit?\";\n"
- + " exitDialogMessage = \"Press Yes\";\n"
- + " // Enable verbose logging\n"
- + " eglConfigVerboseLogging = false;\n"
- + " // Choose screen orientation\n"
- + " screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;\n"
- + " // Enable MouseEvents being generated from TouchEvents (default = true)\n"
- + " mouseEventsEnabled = true;\n"
- + " // Set the default logging level (default=Level.INFO, Level.ALL=All Debug Info)\n"
- + " LogManager.getLogManager().getLogger(\"\").setLevel(Level.INFO);\n"
- + " }\n"
- + " \n"
- + "}\n";
- return str;
- }
- public static class AndroidTarget {
- private int id;
- private String name;
- private String title;
- private String platform;
- private int apiLevel;
- private int revision;
- private String skins;
- public AndroidTarget() {
- }
- public AndroidTarget(String name) {
- this.name = name;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getTitle() {
- return title;
- }
- public void setTitle(String title) {
- this.title = title;
- }
- public String getPlatform() {
- return platform;
- }
- public void setPlatform(String platform) {
- this.platform = platform;
- }
- public int getApiLevel() {
- return apiLevel;
- }
- public void setApiLevel(int apiLevel) {
- this.apiLevel = apiLevel;
- }
- public int getRevision() {
- return revision;
- }
- public void setRevision(int revision) {
- this.revision = revision;
- }
- public String getSkins() {
- return skins;
- }
- public void setSkins(String skins) {
- this.skins = skins;
- }
- @Override
- public String toString() {
- return getTitle();
- }
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof String && getName() != null) {
- return getName().equals(obj);
- } else {
- return super.equals(obj);
- }
- }
- }
- }
|