JavaIDEdroid is an integrated development environment which runs on Android and allows to create native Android applications without the need to use the Android SDK on Windows or Linux.

JavaIDEdroid

What is JavaIDEdroid?
Getting started
PRO features
Manage projects
BeanShell scripts
Tools tab
Modules and JavaRunner
Using with other applications
Debugging
Legal issues

1. Introduction

JavaIDEdroid (in the following termed "the APP") is an integrated development environment which runs on Android and allows to create native Android applications without the need to use the Android SDK on Windows or Linux. It runs on Android 2.3 or higher.

There is a free version and a PRO version of the APP. The PRO version has many features that are missing in the free version.

Author: Tanapro GmbH (Tom Arn), www.tanapro.ch
Project home page
and support:
https://github.com/t-arn/java-ide-droid

Currently, following tools are integrated into the APP:

The APP can be extended with modules. The modules are loaded dynamically and the integrity of the module is checked before every start of the module. In the download area of the project's website you'll find some pre-built modules, for example for Ant or the jar tool.

The APP can be controlled and customized with BeanShell scripts. The APP supports the 'protected script mode' which verifies the integrity of the scripts before executing them.

top

2. Getting started

To get started, follow these steps:

  1. Install the APP
  2. Define "Development root dir" in the Settings
  3. Define "Module salt" in the Settings to make the module hashes unique for you
  4. Define "Script salt" in the Settings if you want to activate the 'Protected Script Mode'
  5. If needed, change the regex for error messages in the settings. The standard regex are
    (?.*\.xml):(?\d*)
    .* (?.*\.java):(?\d*)
    .* (?.*\.java).* (?\d*)
    Sourced file: (?.*\.bsh) :.*at Line: (?\d*)
    In file: (?.*\.bsh).* at line (?\d*).*
    The named group filename and linenumber are used to open the file with the internal editor and navigate to the place with the error or warning.
  6. Create your first project (see here)

To edit files you can use the built-in text editor or any other editor you download and install.

The APP comes with android-api8.jar which is automatically extracted to your storage card. You might need the android.jar from the Android SDK for higher API levels as well. For some API levels you'll find the android.jar also in the download area of the JavaIDEdroid projekt website.

If you want to use the complete functionality of the APP you need to purchase the PRO key.

top

2.1. PRO features

The PRO key activated following additional functionality:

  • Unlimited project support (the free version only supports very small projects)
  • DexMerger Tool: Allows to merge 2 .dex files. So, .jar libraries do not need to be re-dexed everytime.
  • Merge functionality in dx
  • Incremental option in dx
  • Script method JID.fnDexJarArchiveIncrementally
  • APK signing with user certificate
  • Unlimited JavaRunner (the free version only supports very small modules)
  • Incremental creation of JavaRunner modules

To activate the PRO features buy the JavaIDEdroidPRO 2.x Key from Google Play and install it to your device. If you already have the old JavaIDEdroidPRO 1.x version you do not need the 2.x PRO key. Get the latest update instead.

top

3. Project Support

In the PRO version you can define and manage any software projects (e.g. also non-Android projects). The free version only supports very small projects. In the project menu you have following options:

  • Create new project
  • Open project
  • Re-open project from recent project list
  • Edit project
  • Compile project
  • Build project
  • Install project APK
  • Close project

top

3.1 Create a new project

You can define following information for a project:

  • Project name: You can choose any name you like, but it makes sense to name the the project (and also the project definition file) the same as your package, e.g. HelloWorld
  • Project root directory: This is the directory where you put all your project files. The project definition file (*.jip) is always stored here.
  • Main Activity Java file: The path to the Java file containing your main activity, relative to the project root direcory. By compiling this file, all other Java files are also automatically compiled along.
  • Project APK: The APK file to be built and installed. If no value is defined, the APP will use JID.stPrjRootDir+"bin/test/"+JID.stName+"/"+JID.stName+".apk".
  • Android.jar: The path to a project specific android.jar, relative to the development root directory. If left empty, the android.jar from the global settings will be used
  • Library directory: The path of the library directory, relative to the project root direcory, e.g. libs/
    Leave empty if your project does not use external libraries (.jar or .so files).
  • Dex library directory: The path of the directory for the pre-dexed libraries, relative to the project root direcory, e.g. bin/test/dexlibs/
    Leave empty if you do not want to use dex libraries (.jar.dex.zip). See also here.
  • Asset directory: The path of the asset directory, relative to the project root direcory, e.g. assets/
    Leave empty if your project does not use assets.
  • Regex for error messages: Here you can define several regular expressions which replace the ones in the settings.
  • Exclude directories: To shorten the 'Directory list' in the 'Project File Manager' (see below), you can define a list of directories you want to exclude. Every directory must be on a separate line. You can use the browse button several times to add more directories.
  • Write time log: When this option is active the APP writes a time log for the project.

After defining the project root directory, you can press the 'Create project files from template' button and have the APP create a skeleton project for you from the chosen template file. The HelloWorld template is automatically extracted from the app package when it is not found on the storage card. You can customize this template to fit your needs and/or add your own templates.
The project root directory must NOT exist at the time when you press the button, to avoid existing data from being overwritten. So, if you use the browse button for the project root directory, you need to enter the last directory of the path by hand.

When you press the 'Save' button, the project specific information is stored in the project definition file (.jip files) in the root directory of the project. The path of the project root directory is not stored in .jip file. Instead, when opening a .jip file, the project root directory is set to the directory where the .jip file is located. This way, your project tree stays portable. The important thing to keep in mind is, that you must never manually move the .jip file away from the project root directory, or the APP will set a wrong project root directory for this project!

top

3.2 Open project

You can open a project by browing the development tree and picking the .jip file. You can also quickly open recent projects by picking them from the recent project list (see below). After opening a project, the project file manager is shown in the 'Project' tab of the APP.

top

3.2.1 Project file manager

The project file manager lets you browse and work with all the files of the opened project. When you long-press a file, you get a context menu with following items:

  • View/open file: This opens the file by calling the ACTION_VIEW intent. If more than one app can handle this intent, you can choose from a list.
  • Edit file (internal): Edit the file with the internal editor.
  • Edit file (external): This allows you to edit the file by calling the ACTION_EDIT intent. If more than one app can handle this intent, you can choose from a list. Make sure your editor (not included in the APP) saves the files in ANSI (iso-8859-1 / latin-1 / win1252) format, or you will get compilation errors!
  • Run script/module: This item is only active for .bsh files and modules and allows you to run the chosen BeanShell script/module. For scripts, the APP changes to the 'BeanShell' tab to show the result of the script execution. Modules are run in the 'Tools' tab.
  • Send file to script: Passes the file to a choosable script.
  • Rename file: Renames the file
  • Delete file: Deletes the file after a confirmation

The 'Directory list' button lets you quickly change to another directory of the project. When you long-press a directory, you get a context menu with following items:

  • New file: Creates a new file in the selected directory
  • Create directory: Creates a new directory below the selected directory
  • Rename directory: Renames the selected directory.
  • Delete directory: Deletes the selected directory after a confirmation.

New files are created based on file templates. If there is a file NewFileTemplate in the project root directory or in the working directory (under file-templates) which has the same extension (for example .java) as the new file, then the new file will be created based on this template. Otherwise a new empty file will be created.

top

3.3 Recent project list

You can open an existing project by picking it from the 'Recent project list'. This list is updated every time you save or open a project. The list is ordered by usage, the last used project is always on top.

top

3.4 Compile and build a project

When you select the menu items for compiling or building the project, the default BeanShell scripts /sdcard/.JavaIDEdroid/versionCode/compile.bsh or /sdcard/.JavaIDEdroid/versionCode/build.bsh are executed. These scripts should work for almost every project, because they get the project specific information from the currently opened project. You can customize these scripts to fit your specific needs. If you use the free version and your project becomes too large, you need to customize the scripts so they run without access to the project specific information.

If you have a project that cannot be compiled/built with the default scripts, you can copy the default scripts into the project root directory and customize them there for the specific project. When choosing 'compile' / 'build' from the project menu, the APP will then use these project specific scripts instead of the default scripts.

If your APP contains external Java libraries (*.jar) that are too large and generate an out-of-memory-exception when dexing, set the 'max dex size' in the settings to a lower value (PRO only). The .jar files will then be dexed incrementally. Alternatively, you can also dexify those classes on your PC and then copy them to the dexlibs directory of your project on your Android device (PRO version only). E.g. use following command on your PC to dexify ecj.jar:
dx.bat --dex --output=dexlibs\ecj.jar.dex.zip libs\ecj.jar
Make sure that you set the dexlib directory in your project (JID.stDexlibsDir) and that your dex libs have the extension .jar.dex.zip or the default build script will not be able to perform the dex merging. When the script finds ecj.jar.dex.zip and this file is newer than ecj.jar it will not try to generate it and you can therefore avoid the out-of-memory-exception.

top

3.5 Installing project APK

If you choose the menu option 'Install project APK', the APK file will be passed to the package manager and installed on your device.

top

3.6 Time Log

The time log allows you to calculate the time you needed to develop a project. The time log is saved in the project root directory in the file TimeLog.csv.

When the time log is active the currently worked time is displayed in the project tab. The time is not updated permanently but only when tabs are changed and onResume of the MainActivity. The time logging starts when a project is opened and ends when you close the project or exit the APP. If the APP is closed by Android the time logging does not end. Time intervals of less than 1 minute are not saved.

top

4. BeanShell

The integrated BeanShell interpreter allows you to automate and customize the build process by writing your own BeanShell scripts. The scripts can use stdin, stdout and stderr to input and output data. For entering data with stdin there is an entry in the context menu of the BeanShell tab (the same is true for the Tools tab).

4.1 Writing scripts

BeanShell scripts can access the functionality built into the APP by using the pre-defined variable JID.
This variable references JID.class with following accessible variables and methods:

  • JID.iMaxDexSize: max dex size (-1 = unlimited)
  • JID.iScriptResultCode: Scripts can return their result value here
  • JID.aScriptArguments: Array of Strings passed to the script
  • JID.stAndroidJarPath: Project-specific android.jar (relative to stDevRootDir)
  • JID.stAPK: The project APK file
  • JID.stAssetsDir: The directory containing the project assets (relative to stPrjRootDir)
  • JID.stBshVar1: User defined global variable 1
  • JID.stBshVar2: User defined global variable 2
  • JID.stBshVar3: User defined global variable 3
  • JID.stBshVar4: User defined global variable 4
  • JID.stBshVar5: User defined global variable 5
  • JID.stDevAndroidJarPath: The full path and filename to the default android.jar
  • JID.stDevRootDir: The development root directory
  • JID.stDexlibsDir: The directory containing the dexed libs (relative to stPrjRootDir)
  • JID.stLibsDir: The directory containing the project libs (relative to stPrjRootDir)
  • JID.stMainJava: The java file of the main activity
  • JID.stName: The name of the project and the project definition file (.jip)
  • JID.stPrjRootDir: The project root directory
  • JID.stPw1, JID.stPw2: Temporary passwords to be used by the scripts
  • int JID.fnAddToClasspath (String dexArchive) // PRO only
  • int JID.fnAddToLocallyLoadedClasses (String className) // e.g. "java.util.jar.JarOutputStream" or "java.util.jar.*"
  • int JID.fnAapt (String arguments)
  • int JID.fnAapt (String[] arguments)
  • int JID.fnApkBuilder (String arguments)
  • int JID.fnApkBuilder (String[] arguments)
  • void JID.fnClear() // clears BeanShell output
  • int JID.fnClearClasspath()
  • int JID.fnClearLocallyLoadedClasses()
  • int JID.fnCompile (String arguments)
  • int JID.fnCompile (String[] arguments)
  • int JID.fnDexJarArchiveIncrementally (String arguments)
  • int JID.fnDexJarArchiveIncrementally (String[] arguments)
  • int JID.fnDexMerger (String arguments)
  • int JID.fnDexMerger (String[] arguments)
  • int JID.fnDx (String arguments)
  • int JID.fnDx (String[] arguments)
  • String JID.fnGetPackageName()
  • int JID.fnGetVersionCode() // returns the version code
  • String JID.fnGetVersionName() // returns the version name and PRO info
  • void JID.fnInputDialog (String prompt) // shows input dialog for data input via stdin
  • boolean JID.fnIsCancelled() // returns true if user has aborted the task
  • boolean JID.isProjectClosed() // returns true if no project is open
  • void JID.fnPublishProgress (String msg) // writes text to console
  • void JID.fnPublishStatus() (String msg) // updates status message
  • int JID.fnRunJava (String arguments)
  • int JID.fnRunJava (String[] arguments)
  • int JID.fnSignApk (String arguments)
  • int JID.fnSignApk (String[] arguments)
  • void fnStartActivity (Intent intent)
  • Intent fnStartActivityForResult (Intent intent) // starts Activity and waits until it finishes. Returned Intent always contains extra bundle with jid.resultCode: 0=OK. 1=no return data, 2=error. On error, extra bundle contains jid.errorMessage with the error message String.
  • void JID.fnToast (String msg, int milliseconds) // shows a toast message
  • String[] JID.fnTokenize (String commandline) // tokenizes the commandline arguments

Meaning of the script return value JID.iScriptResultCode:

   0:   OK
   1:   warning
   >1:  error
   99:  no defined return value / exception
   

Example for calling ecj:
int rc = JID.fnCompile("--version");

top

4.2 Running scripts

BeanShell scripts must be stored somewhere on the Storage Card. You can enter the path and filename of the script in the edit field or choose the script by tapping the folder icon (or choose it in the 'Project Filemanager'). Optionally, you can add script arguments. The ">" button will start the specified BeanShell script.

The result of the script execution is displayed in the ScrollView which has a context menu with following options:

  • Top: Scroll to the top
  • Bottom: Scroll to the bottom
  • Goto error: Opens the file in the error message line at the 3 red arrows with the internal editor and scrolls to the line containing the error.
  • Copy to clipboard: The complete output is copied to the clipboard
  • Input to stdin: For entering data (only active while script is running)

top

4.3 Protected Script Mode

The 'Protected Script Mode' is activated by defining your 'Script Salt' in the Settings. In this mode the APP executes only scripts which are approved by you. Approval is done by saving the BeanShell script in the internal editor. This adds a hash value to the script which will then be checked every time the script is started. Before you approve a script make sure that it does not execute any unwanted code!

The 'Protected Script Mode' makes sure that no malicious program can change your scripts without you noticing it. When you change your script salt, you will need to re-approve all your scripts. The APP will detect if your script hash was created using your previous script salt and tell you so. Then, you don't need to check the script for unwanted changes before saving it in the internal editor.

top

5. Signing with user certificates

With the PRO version you can sign your applications with a certificate from your truststore. The APP supports the standard Java truststore (JKS) and the BouncyCastle truststore (BKS) format.

The default script expects the signing parameters in following variables:

  • Truststore file path: JID.stBshVar1
  • Truststore password: JID.stPw1
  • Certificate alias: JID.stBshVar2
  • Certificate passwort: JID.stPw2

You can reach the Password Activity from the main menu. For security reasons the passwords are not stored persistently, but they remain cached until you exit the APP from the main menu or until you enter the Password Activity again.

When the default script does not find a truststore password, it signs with the built-in testkey. Otherwise, it tries to sign with the defined user certificate. If the truststore password is wrong, ZipSigner generates a LoadKeystoreException. If the certificate password is wrong, an UnrecoverableKeyException is generated. In both cases the script aborts with an error code.

top

6. Tools

This tab provides a direct access to the built-in tools without the need for a BeanShell script. All arguments need to be entered in the edit field. This tab is used to create modules. It can also be used to see the help for the tools and try things out.

top

7. Modules and JavaRunner

JavaRunner allows to run any binary Java console application (.jar file) on your Android device. Modification of the source code is not necessary! The APP automatically creates a module (Android binary file with the extension .jar.dex.zip) and handles the redirection of stdin, stdout and stderr. To enter data, choose the item 'Input to stdin' from the context menu. The APP also prevents the execution of System.exit() because this would not only end JavaRunner but also the APP itself. The module is protected with a hash (checksum) which is checked on every run to make sure the file has not been tampered with. After running modules, they are automatically removed from the memory again and JID.fnClearClasspath is executed.

To create a module, just pass the full path of the .jar file to JavaRunner in the Tools tab. The module is created and the class defined in MANIFEST.MF is started. If the .jar file is too large and you run into an out-of-memory-exception during dexing, reduce the 'max dex size' value in the Settings (PRO only). A value of 300 KB should work in most cases. If you want to dex a large module on your PC, set 'max dex size' to -1 and let the APP throw an out-of-memory-exception. In this case the APP will leave the files to be dexed in a temp directory, e.g. /sdcard/.JavaIDEdroid/temp1369744458294. You can then copy the temp directory to your PC and create the .jar.dex.zip file with following command:
dx --dex --core-library --output=yourapp.jar.dex.zip /.JavaIDEdroid/temp1369744458294
When you run this module for the first time with JavaRunner, the APP will ask to add the missing hash to the module.

JavaRunner can also be used in a BeanShell script with the method JID.fnRunJava
If you need to load more than 1 module, you load them with JID.fnAddToClasspath before you load and run the main module with the JID.fnRunJava method. This is the way you load Ant custom tasks before you load and run Ant itself. Consult the Wiki on the project website to find out more about running Ant on Android.

Limitations

  • The Java console application might use classes that are not available on Android. If a necessary class is missing there will be an error at run time. You might be able to supply these missing classes in a module of your own. But this might not always be successful.
  • The modul is limited to the same permissions which are granted to the APP itself.

7.1 Module security

Modules are protected with a hash value which is checked every time a module is loaded. The 'module salt' defined in the Settings is used to make the hashes unique for you. The hash check ensures that the module's classes have not been modified unauthorized. If the hash does not match, the module will not be loaded.

If you changed your module salt, the hashes will not match anymore, but the APP will also check if the hashes match when using your previous module salt. If that is the case, the APP will allow you to update the hashes using your current (new) module salt. So, make sure to run all your modules after you change your module salt! If you change your module salt twice without updating the hashes in between, you will need to update the module hashes manually. The same is true for modules created with JavaIDEdroid 2.5.0 or older.

To update module hashes manually you need to remove the JavaIDEdroid entry from the META-INF/MANIFEST.MF file inside the module. On the next start of the module the APP will allow you to add a new hash. You should only update the hash of a module manually if you really trust the module! If you are not sure, it is more secure to re-create the module.

top

8. Using with other applications

The APP supports the "android.intent.action.VIEW" intent action for files with extensions .bsh , .jip and .json. If you click a .bsh file in your Android file manager (e.g. ASTRO) the APP will be started and the script path and filename prepopulated in the edit field. If you click a .jip file the APP will be started and the project file opened. With .json files, the APP reads the JSON string from the file, creates a JSONObject and gets the contained data elements.

The JSON string has following content:

{
  "ScriptPath": "/sdcard/Dev/HelloWorld/build.bsh",
  "ScriptArguments": ["arg 1", "arg 2"],
  "ProjectFilePath": "/sdcard/Dev/HelloWorld/HelloWorld.jip,
  "ScriptAutoRun": true,
  "ScriptAutoExit": true,
  "WantResultText": true
}
  • ScriptPath: This is the path and filename of the script to be run
  • ScriptArguments: These are the (String) arguments passed to the acript
  • ProjectFilePath: This is the path and filename of the project definition file which will be opened automatically
  • ScriptAutoRun: Set this to true to make the APP run the script immediately after starting
  • ScriptAutoExit: Set this to true to make the APP shut down after the script ran through
  • WantResultText: Set this to true to get back the script output of the BeanShell tab

The APP also supports the "android.intent.action.SEND" intent action and can be called from other applications using following code:

ComponentName cn = new ComponentName("ch.tanapro.JavaIDEdroid", "ch.tanapro.JavaIDEdroid.MainActivity");
data = "data:application/json,{\"ScriptPath\": \"/sdcard/Dev/HelloWorld/build.bsh\", \"ScriptArguments\": [\"arg 1\", \"arg 2\"], \"ProjectFilePath\": \"/sdcard/Dev/HelloWorld/HelloWorld.jip\", \"ScriptAutoRun\": true, \"ScriptAutoExit\": true, \"WantResultText\": true}"; 
Intent intent = new Intent("android.intent.action.SEND");
intent.setComponent(cn);
intent.setData(Uri.parse(data));
startActivityForResult(intent,123);

In the data URI, you pass the JSON string with the format declaration data:application/json,

You can get the data returned from the APP in the onActivityResult method with following code:

Bundle extras = intent.getExtras();
if (extras != null) 
{
  int iScriptResultCode=extras.getInt("android.intent.extra.ScriptResultCode",-1);
  String stResultText=extras.getString("android.intent.extra.ResultText");
}

ScriptResultCode is always returned and contains the value of JID.iScriptResultCode. If the script sets this variable, its value is returned to the calling app when the APP is finished automatically or by the user.

You can also get the script output of the BeanShell tab by reading the log file /sdcard/.JavaIDEdroid/LogOutput.txt. Of course, this only works if you have checked the setting 'Log output to file'

The APP supports the "android.intent.action.CREATE_SHORTCUT" intent action which is used to create a shortcut to JavaIDEdroid on the Android Home screen.

top

9. Debugging

If you have problems with the APP, you can set the Log Level in the APP settings to analyse them. If you define a value higher than NONE, the APP will log informationen to the logcat. The highest amount of information is written with log level VERBOSE.

To view the logs you can start the Logcat Activity from the main menu. It shows the log information from the APP and from the system. When the APP starts and when you leave the Logcat Activity, a marker is set in the log. When the Logcat Activity starts, it scrolls down to the last marker so you can quickly skip the log entries you've already seen.

top

10. Legal issues

Thank you for choosing this SOFTWARE! You may only use this SOFTWARE if you agree with the conditions listed further below:

COPYRIGHT
This SOFTWARE has been developed by Tanapro GmbH (Tom Arn), www.tanapro.ch (in the following termed AUTHOR). All rights reserved.

NO WARRANTY
The SOFTWARE is provided AS IS without a warranty of any kind. All express, implied or statutory warranties, including any implied warranty of merchantibility or fitness for a particular purpose, are hereby excluded. The AUTHOR does not warrant that the SOFTWARE is fail-safe or error-free. The user must bear all risks when using the SOFTWARE.

NO LIABILITY
In no event will the AUTHOR be liable for direct, indirect or consequential damages related to the use (or the inability of the use) of the SOFTWARE, even if the AUTHOR has been advised of the possibility of such damages.

top