Menu & splash screen example
============================

This project adds a splash screen and an Android menu to a Delphi XE5 Android project.

The splash screen is implemented in Java as an activity class, which needs to be compiled and coverted to an appropriate executable format (dex), and then merged into the other dex code deployed with an Android app.

The splash activity checks the OS and hardware are appropriate for a Delphi application and terminates the app with a toast message if something unsupported is found.

Android menus rely on overriding 2 methods in the relevant activity class: onCreateOptionsMenu and onOptionsItemSelected. A Delphi app's activity class is written in Java and we will need to inherit from Delphi's class in order to override the methods.

Build the Java support files:
----------------------------

In the java project directory are:

 - a splash screen source file, java\src\com\blong\test\SplashActivity.java
 - a source with a class that inherits from Delphi's FMXNativeActivity class, NativeActivitySubclass.java
 
These need to be compiled to .class files, which are then archived into a .jar file, converted from Java byte code to DEX (Dalvik Executable) format and merged into the normally used (by Delphi's Android deployment process) classes.dex.

However in order to compile the activity class descendant the Java compiler/linker needs access to the ancestor class. This requires using an additional tool to pull out the compiled FMXNativeActivity class from Delphi's classes.dex file, transformed into Java byte code. Extracting a compiled Java class from classes.dex has been deemed by Delphi Product Management not in violation of the Delphi license agreement so this is a risk-free process.

 - Get the dex2jar tool from https://code.google.com/p/dex2jar
 - Locate the directory containing the Delphi-supplied classes.dex, similar to C:\Program Files (x86)\Embarcadero\RAD 
Studio\12.0\lib\android\debug
 - Make a copy of classes.dex to some temporary directory
 - Ensure the Java Development Kit's bin directory is on the system PATH (e.g. C:\Program Files (x86)\Java\jdk1.6.0_23\bin)
 - Run a command-prompt in the temporary directory chosen above and ensure you can successfully launch each of these:
    - javac
    - jar
 - Run this command to transform the .dex Dalvik executable archive into a .jar Java archive:
     d2j-dex2jar.bat classes.dex
 - Run this command to extract the compiled Embarcadero-specific classes from the archive:
     jar xf classes-dex2jar.jar com/embarcadero/firemonkey
 - Now archive these classes alone into a new Java archive with this command:
     jar cf embarcadero.jar com

This archive, embarcadero.jar, now contains the ancestor to our replacement activity class. Copy it into the project's java subdirectory.

To proceed with compiling the Java source files:

 - Ensure the useful subdirectory of Android SDK's build-tools directory is on the system PATH (e.g. C:\Android\android-sdk-windows\build-tools\18.0.1 or C:\Users\Public\Documents\RAD Studio\12.0\PlatformSDKs\adt-bundle-windows-x86-20130522\sdk\build-tools\android-4.2.2)
 - Ensure the Java Development Kit's bin directory is on the system PATH (e.g. C:\Program Files (x86)\Java\jdk1.6.0_23\bin)
 - Run a command prompt in the project's java subdirectory and ensure you can successfully launch this command:
    - dx
 - Review the build.bat file and ensure the environment variables are set correctly:
    - ANDROID needs to point to your Android SDK base directory, e.g. C:\Users\Public\Documents\RAD Studio\12.0\PlatformSDKs\adt-bundle-windows-x86-20130522\sdk or C:\Android\android-sdk-windows
    - ANDROID_PLATFORM needs to point at an installed SDK platform installation, e.g. %ANDROID%\platforms\android-15 or %ANDROID%\platforms\android-17. Check for one that is installed.
    - DX_LIB needs to point to the lib subdirectory under the Android SDK build-tools directory, e.g. %ANDROID%\build-tools\18.0.1\lib or %ANDROID%\build-tools\android-4.2.2\lib
    - EMBO_DEX needs to point to the Delphi-supplied Android classes.dex file, wrapped in quotes to take care of any spaces in the path, e.g. "C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\lib\android\debug\classes.dex"
 - Run build.bat
 - You should now have a new file in the project directory tree called java\output\dex\classes.dex
 
This file replaces the supplied classes.dex and has the Java splash screen and activity descendant compiled classes included in it.

Set the new classes.dex for deployment:
--------------------------------------

Open the project in the IDE
Choose Project | Deployment
Note that the classes.dex file from the project's java\output\dex directory is set to be deployed.
You must ensure that the default classes.dex file must be de-selected. As you switch configurations, this de-selection will be lost (the file will be re-set to be deployed) and will need to again be de-selected. This is an IDE bug with Delphi XE5 RTM and is logged in Quality Central as bug 118472.

Register the splash screen activity:
-----------------------------------

This has already been done for this demo. It involves the following:

 - Open the Android manifest template, AndroidManifest.template.xml, which is generated on first compile, from the project directory
 - Add in a description of the new (splash screen) activity in the application element:
 
<activity android:name="com.blong.test.SplashActivity"
          android:screenOrientation="portrait">
</activity>

 - Move the intent-filter element from inside the FXNativeActivity to inside the splash activity in order to tell Android to launch the splash activity when the app is launched:
 
  <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>

Set up the Android resources:
----------------------------

The splash activity could set up the screen layout in code but instead uses Android resource files.
The menu is also defined in an Android resource.
So we have these resources:

 - res\layout\splash_activity.xml is a layout file to describe the splash screen layout
 - res\menu\main_menu.xml is the menu definition
 - res\values\strings.xml is a string file containing strings used by the splash screen's hardware/OS error messages and by the menu captions

In addition an image is chosen to act as the splash screen, and this image (or the deployed version of it) is referred to by the content of the layout file. For this project the chosen file is one supplied with Delphi, specified as C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png (update as required).
 
The IDE's Deployment Manager (Project | Deployment) has been used to deploy all these resource files. You can see for this project that these files are being deployed into the corresponding res subdirectories in the deployment area so the relevant Android tool can find them when building the .apk:

 - res\layout\splash_activity.xml
 - res\menu\main_menu.xml
 - res\values\strings.xml
 - res\drawable\splash.png

Build the Delphi Android application library:
--------------------------------------------

In the IDE choose Project | Compile MenuTest (or press Ctrl+F9)

Deploy the library to an Android application package (.apk):
-----------------------------------------------------------

In the IDE choose Project | Deploy libMenuTest.so

Install the app on the device:
-----------------------------

In the IDE choose Run | Run Without Debugging (or press Ctrl+Shift+F9)
This will implicitly do the compile and build steps above, so they are actually optional.
This step will uninstall the app if already installed and then install the newly built version.

Note the app will be installed but won't be launched. This is a side-effect of changing the launch activity and has been logged in Quality Central as bug 118450
You can launch the app on the device as usual.

Additional notes:
----------------

The overridden Java methods create a menu from the menu resource (onCreateOptionsMenu) and respond to a menu item being chosen (onOptionsItemSelected).
The latter method calls into a native Delphi command via JNI.
This requires some setup code in Delphi to register a native routine that the Java code calls.

The native Delphi method will be called on the Java UI thread, which is differet from the normal FMX Delphi thread.
Because of this the Delphi native routine (delphiOptionsItemSelectedNative) initiates a thread switch.
Within the FMX thread a regular method is called within the Delphi form (OnOptionsItemSelected) and this represents a Delphi proxy for the Java actvity method.