Sign in Join
Wiki copytemporary

Custom Drawn Interface/Android: what changed

Revision 4 to 5. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11*(Android only)*
22
33> **Warning:** THIS INFORMATION IS DATED AND NEEDS UPDATING
44
55Go back to [[Custom Drawn Interface]]
66
77## Architecture
88
99LCL-CustomDrawn-Android utilizes a minimal Java application which communicates with our Pascal library and sends all events to it and also obeys commands from it. The communication is done via JNI as supported by Google. The controls are not native, instead they are all drawing using TRawImage+TLazIntfImage+TLazCanvas and events and the painting are clipped using LazRegions. The drawing itself is done in Pascal using jnigraphics to draw on a Bitmap Java object which is then drawn by the minimal Java activity on a SurfaceView.
1010
1111Our previous and short-lived attempt to write an LCL Interface for Android (LCL-Android) utilized a non-standard method of using native executables which communicated with a Java machine via Pipes. This method was abandoned because it was considered unsupported by Google. It is considered obsolete and people should use LCL-CustomDrawn-Android instead. This older interface was documented in [[Android Interface]].
1212
1313## Roadmap
1414
1515Part 1, until March 2012:
1616
17171. Build the set of [[Lazarus Custom Drawn Controls]]
18182. Initial bindings for the Android APIs
19193. Create an application to automatically generate the bindings
20204. Start the new widgetset
21215. Implement support for JNI
22226. Merge the Lazarus Custom Drawn Controls into the LCL and use them to implement all basic controls
23237. Add text support for Android
24248. Implement basic window client area scrolling
25259. Add mobile emulator for desktop platforms
262610. Improve the mobile scrolling
272711. Add text support in X11
282812. Add DPI awareness and adaptation in the LCL
292913. Add non-native text support via pasfreetype
3030
3131Part 2: April, May, June 2012:
3232
33331. TButton improve the Android visual
34342. TBitBtn
35353. TRadioButton finish the native look
36364. Calendar dialog -\> Problematic as the LCL has no calendar dialog, it just opens a normal form and puts a calendar on it, so we need a TCDCalendar widget
37375. MaskEdit
38386. Improve TComboBox
39397. TMemo
40408. TListView as a list with columns
41419. TMainMenu
424210. Database with sqlite
434311. Barcode reading
444412. Windows add-on installer
4545
4646## Using the Android SDK, Emulator and Phones
4747
4848[[Custom Drawn Interface/Using the Android SDK, Emulator and Phones]]
4949
5050## Android Programming
5151
5252See [[Android Programming]], also includes caracteristics of the various phones relevant for programming.
5353
5454## Configuring the Free Pascal Compiler for Android
5555
5656| NOTE: |
5757|----|
5858| The cross-compiler instructions below are probably obsolete, since support for the [[Android|Android target]] is present in the trunk (development) version 2.7.1 of FPC. Here are up to date instructions: [[Android|building a cross-compiler for Android target]]. |
5959
6060### Use the ready Virtual Box Image with FPC and Lazarus
6161
6262The fastest way to configure Free Pascal and Lazarus for Android development is simply using a pre-configured virtual machine image which already includes Mageia Linux 1, KDE, Lazarus 0.9.31, Subversion, Free Pascal for both x86-linux and arm-linux (targetting Android), the Android SDK, the Android NDK, Java, Ant, Gtk2 and all it's development packages, the GNU debugger (GDB), subversion and everything else necessary for building Android applications with Lazarus.
6363
6464The download like for the virtual machine image is: <https://sourceforge.net/projects/p-tools/files/Lazarus_for_Android_VM_Image/snapshot_30_dez_2011/> (warning: the VirtualBox image was created using the Mac OS X default Zip utility and not all zip applications can handle it. The Mac OS X default zip application can, and [PeaZip](https://peazip.github.io/) too and [WinRAR](http://win-rar.com/download.html) too. Both 7-Zip and the Windows 7 default unzipper fail.
6565
6666The virtual machine image is composed by two files: “Android Devel VM.vbox” and “Android Devel VM.hdd”. Both need to be located in the same folder and also note that the source forge download is a zipped file, so it needs to be unzipped. After unzipping the VM image has 5,2GB. To use this virtual machine one should install Virtual Box and then use it to open the .vbox file. Then one can already use this Linux virtual machine to build Android applications. The process of building an application involves first opening Lazarus and building the application in Lazarus, for example the example project available on ~/Programas/lazarus/example/androidlcl/ and then going into the Linux terminal, navigating to ~/Programas/lazarus/example/androidlcl/android and issuing the command “ant debug” which will generate the APK file in ~/Programas/ lazarus/example/androidlcl/android/bin/LCLExample-debug.apk. There are two users in the virtual machine: “root” and “pascaldev” and both of them use the password “root”.
6767
6868Note that the virtual machine contains the Lazarus source code from when it was created, but one can also use svn update to get the latest code. Note that this involves some risks, however, as the trunk version might ocasionally contain problems.
6969
7070### Building the compiler yourself in Windows
7171
7272**Step 1** - Install the Android SDK and NDK
7373
7474Download from Google and install both the SDK and the NDK for Windows.
7575
7676Check your path to the binutils installed by the NDK. For example, for NDK r7 installed in C:\Programas\android-ndk-r7\\ the path is C:\Programas\android-ndk-r7\toolchains\arm-linux-androideabi-4.4.3\prebuilt\windows\bin
7777
7878Also check your path to the libraries installed by the NDK. For example, for NDK r7 installed in C:\Programas\android-ndk-r7\\ the path is C:\Programas\android-ndk-r7\platforms\android-8\arch-arm\usr
7979
8080**Step 2** - Download FPC 2.5.1 from January 19th
8181
8282Create a folder to store the FPC trunk source code and checkout revision 16790
8383
8484Or if you want support for database and many other nice fixes use the branch fpc4android from here:
8585
8686svn co <https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android> fpc4android
8787
8888**Step 3** - Install FPC 2.4.4
8989
9090An easy way to obtain a good FPC 2.4.4 is installing Lazarus 0.9.30.2. For example, let's say you install this Lazarus version in C:\Programas\lazarusfpc244
9191
9292**Step 4** - Create the build script and built it
9393
9494Create the output directory, for example: C:\Programas\fpcandroid\output
9595
9696Next create a file called build.bat in the fpc root folder, in our example C:\Programas\fpcandroid and copy to it:
9797
9898 SET PATH=C:\Programas\lazarusfpc244\fpc\2.4.4\bin\i386-win32\
9999 make crossinstall CPU_TARGET=arm OS_TARGET=linux CROSSBINDIR=C:\Programas\android-ndk-r7\toolchains\arm-linux-androideabi-4.4.3\prebuilt\windows\bin OPT=-dFPC_ARMEL BINUTILSPREFIX=arm-linux-androideabi- INSTALL_PREFIX=C:\Programas\fpcandroid\output
100100 pause
101101
102102Next run this batch script and you should have FPC installed into C:\Programas\fpcandroid\output
103103
104104**Step 5** - Copy some cross-binutils into the bin dir
105105
106106You now should have a FPC binary in C:\Programas\fpcandroid\output\bin\i386-win32
107107
108108Now get these 3 files:
109109
110110C:\Programas\android-ndk-r7\toolchains\arm-linux-androideabi-4.4.3\prebuilt\windows\bin\arm-linux-androideabi-as.exe C:\Programas\android-ndk-r7\toolchains\arm-linux-androideabi-4.4.3\prebuilt\windows\bin\arm-linux-androideabi-ld.exe C:\Programas\android-ndk-r7\toolchains\arm-linux-androideabi-4.4.3\prebuilt\windows\bin\arm-linux-androideabi-strip.exe
111111
112112And copy and then rename to have:
113113
114114C:\Programas\fpcandroid\output\bin\i386-win32\arm-linux-as.exe C:\Programas\fpcandroid\output\bin\i386-win32\arm-linux-ld.exe C:\Programas\fpcandroid\output\bin\i386-win32\arm-linux-strip.exe
115115
116116**Step 6** - Merge this into a Lazarus FPC setup
117117
118118Let's say you have the following Lazarus C:\Programas\lazarus31 with the following fpc installed inside it: C:\Programas\lazarus31\fpc\2.6.1\bin\i386-win32 and C:\Programas\lazarus31\fpc\2.6.1\units\\
119119
120120Now create a directory C:\Programas\lazarus31\fpc\2.5.1\units\arm-linux and copy C:\Programas\fpcandroid\output\units\arm-linux there
121121
122122Copy all .exe files from C:\Programas\fpcandroid\output\bin\i386-win32\\ into C:\Programas\lazarus31\fpc\2.6.1\bin\i386-win32
123123
124124(! copy the exe-files to FPC 2.6.1 !)
125125
126126Now you can already build the example project androidlcltest.lpi using the Windows-Release build mode
127127
128128### Using the pre-compiled compiler in Windows
129129
130130**Step 1** - Download and unzip the pre-compiled compiler
131131
132132The download is available here: <https://sourceforge.net/projects/p-tools/files/Free%20Pascal%20for%20ARM/Windows/>
133133
134134**Step 2** - Merge it into the FPC installation
135135
136136Let's say you have the following Lazarus C:\Programas\lazarus31 with the following fpc installed inside it: C:\Programas\lazarus31\fpc\2.6.1\bin\i386-win32 and C:\Programas\lazarus31\fpc\2.6.1\units\\
137137
138138Now create a directory C:\Programas\lazarus31\fpc\2.5.1\units\arm-linx and copy fpc4android_2_5_1_26_mar_2012\units\arm-linux there
139139
140140Copy all .exe files from fpc4android_2_5_1_26_mar_2012\bin\i386-win32\\ into C:\Programas\lazarus31\fpc\2.6.1\bin\i386-win32 (the version here should be of the installed Windows compiler, not the version of the cross-compiler, so might be 2.6.0 or 2.7.1 or something else)
141141
142142**Step 3** - Install the Java JDK and the Android SDK and NDK
143143
144144If you haven't done so already, then install the Java JDK and the Android SDK and NDK. I recommend the JDK 6 (JDK 7 doesnt work!), latest SDK and the NDK version 7. The Windows NDK 7b has a serious bug: [1](https://groups.google.com/group/android-ndk/browse_thread/thread/d8c88bd58ad6df87/5396d1223f0c65b1?hl=pl&lnk=gst&q=Felipe+Monteiro+de+Carvalho#5396d1223f0c65b1) Some people also report that 7c works fine, and I tested that 8c works fine.
145145
146146- Java JDK (!WARNING! Download JDK version 6! Version 7 does not work!!!): <http://www.oracle.com/technetwork/java/javase/downloads/index.html>
147147- Android SDK Download (!WARNING! Instead of clicking in the first download link that you see, go to "Use an existing IDE"!): <http://developer.android.com/sdk/index.html> !WARNING! The SDKs r21 and superior removed the nice apkbuilder.bat script which is utilized in our build system in Windows. If you want to use our Windows build scripts, download the SDK r20 from this link: <http://dl.google.com/android/installer_r20-windows.exe>
148148- Android NDK version 7 download link: <http://dl.google.com/android/ndk/android-ndk-r7-windows.zip>
149149
150150Now you can already build the example project androidlcltest.lpi using the Windows-Release build mode and these instructions: [[Custom Drawn Interface/Android|Custom Drawn Interface/Android#Compiling_the_example_LCL_Android_Application]]
151151
152152### Building the compiler yourself in Linux
153153
154154See [[Setup Cross Compile For ARM]] and make sure to use the option OPT="-dFPC_ARMEL" for building the compiler.
155155
156156### Using the pre-compiled compiler in Linux
157157
158158A pre-compiled compiler is provided for convenience for users. The following steps were tested in Mandriva Linux 2010.0 and 2010.1:
159159
160160**Required Environment**
161161
162162- The latest stable FPC installed in the system via the RPM / DEB / TAR package
163163
164164**Step 1** - Install the cross-binutils
165165
166166For Mandriva Linux the RPM package containing arm-linux-as, arm-linux-ld, etc, which are the cross-binutils can be found here: <http://rpm.pbone.net/index.php3/stat/4/idpl/14252825/dir/mandriva_2010/com/cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm.html>
167167
168168Just download the RPM package and install it using:
169169
170-`rpm -ivh cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm `
170+```text
171+rpm -ivh cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm
172+```
171173
172174In Mandriva Linux 2010.0 the dependencies won't match, as the package is for 2010.1, but one can simply ignore this problem and it works fine using --nodeps:
173175
174-`rpm -ivh --nodeps cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm `
176+```text
177+rpm -ivh --nodeps cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm
178+```
175179
176180For other distributions use the corresponding package, or else read the instructions for building the cross-binutils yourself at [[Setup Cross Compile For ARM]]
177181
178182**Step 2** - Configure the cross-binutils
179183
180184The assembler needs a parameter to tell it which ARM ABI to use. A choice which works good is EABI-5, which is compatible with all Android devices available as of Jan 2011. To set this, we will rename the original assembler and substitute it with a shell script which passes the desired parameter. These commands will do it:
181185
182-`su`\
183-`mv /usr/bin/arm-linux-as /usr/bin/arm-linux-as_org`\
184-`gedit /usr/bin/arm-linux-as`
186+```text
187+su
188+mv /usr/bin/arm-linux-as /usr/bin/arm-linux-as_org
189+gedit /usr/bin/arm-linux-as
190+```
185191
186192Now paste into the editor this code:
187193
188-`#!/bin/sh`\
189-`/usr/bin/arm-linux-as_org -meabi=5 $@`
194+```text
195+#!/bin/sh
196+/usr/bin/arm-linux-as_org -meabi=5 $@
197+```
190198
191199And don't forget to then make it executable:
192200
193-`chmod 755 /usr/bin/arm-linux-as`
201+```text
202+chmod 755 /usr/bin/arm-linux-as
203+```
194204
195205**Step 3** - Install the Free Pascal Cross-Compiler
196206
197207At this point the pre-compiled FPC can be download from here: <http://sourceforge.net/projects/p-tools/files/Free%20Pascal%20for%20ARM/>
198208
199209Then use these commands to install the pre-compiled Free Pascal cross-compiler into /usr:
200210
201-`[felipe@localhost Programas]$ ls -l`\
202-`total 20664`\
203-`-rw-rw-r--  1 felipe felipe 17098552 2010-10-25 08:17 fpc-2.5.1.arm-linux.tar.gz`\
204-`[felipe@localhost Programas]$ su`\
205-`Password: `\
206-`[root@localhost Programas]# cp fpc-2.5.1.arm-linux.tar.gz /usr/`\
207-`[root@localhost Programas]# cd /usr/`\
208-`[root@localhost usr]# tar -xvf fpc-2.5.1.arm-linux.tar.gz `\
209-`[root@localhost usr]# ln -s /usr/lib/fpc/2.5.1/ppcrossarm /usr/bin/ppcrossarm`
211+```text
212+[felipe@localhost Programas]$ ls -l
213+total 20664
214+-rw-rw-r-- 1 felipe felipe 17098552 2010-10-25 08:17 fpc-2.5.1.arm-linux.tar.gz
215+[felipe@localhost Programas]$ su
216+Password:
217+[root@localhost Programas]# cp fpc-2.5.1.arm-linux.tar.gz /usr/
218+[root@localhost Programas]# cd /usr/
219+[root@localhost usr]# tar -xvf fpc-2.5.1.arm-linux.tar.gz
220+[root@localhost usr]# ln -s /usr/lib/fpc/2.5.1/ppcrossarm /usr/bin/ppcrossarm
221+```
210222
211223**Step 4** - Verify if your Cross-Compiler works
212224
213225If you made no errors in the previous steps, it should work, so try to call it like this:
214226
215-`[felipe@localhost Programas]$ /usr/bin/ppcrossarm`
227+```text
228+[felipe@localhost Programas]$ /usr/bin/ppcrossarm
229+```
216230
217231If this command works and fpc shows its options, then you configured the cross-compiler correctly, if not, then try to find out if your symbolic link points to a correct location with this command:
218232
219233\[felipe@localhost Programas\]\$ ls -ls /usr/bin/ppc*
220234
221235Now we are ready to compile Android applications using the Lazarus IDE! Configuring the fpc.cfg file isn't necessary, the old compiler will automatically find the new compiler and it's object files.
222236
223237## Install the Java JDK and the Android SDK and NDK
224238
225239If you haven't done so already, then install the Java JDK and the Android SDK and NDK. I recommend the JDK 6 (JDK 7 doesnt work!), latest SDK and the NDK version 7. The Windows NDK 7b has a serious bug: [2](https://groups.google.com/group/android-ndk/browse_thread/thread/d8c88bd58ad6df87/5396d1223f0c65b1?hl=pl&lnk=gst&q=Felipe+Monteiro+de+Carvalho#5396d1223f0c65b1) Some people also report that 7c works fine, and I tested that 8c works fine.
226240
227241- Java JDK (Choose version 6!): <http://www.oracle.com/technetwork/java/javase/downloads/index.html>
228242- Android SDK Download (Choose Use an existing IDE!): <http://developer.android.com/sdk/index.html>
229243- Android NDK version 7 download link: <http://dl.google.com/android/ndk/android-ndk-r7-windows.zip>
230244
231245Now you can already build the example project androidlcltest.lpi using the Windows-Release build mode and these instructions: [[Custom Drawn Interface/Android|Custom Drawn Interface/Android#Compiling_the_example_LCL_Android_Application]]
232246
233247## Compiling the example LCL Android Application
234248
235249**Step 1 - Download the source code**
236250
237251The source code of the example is located inside the Lazarus sources in lazarus/examples/androidlcl/androidlcltest.lpi
238252
239253**Step 2 - Make sure you have the Java JDK and the Android SDK and NDK installed**
240254
241255Read here: [[Custom Drawn Interface/Android|Custom_Drawn_Interface/Android#Install_the_Java_JDK_and_the_Android_SDK_and_NDK]]
242256
243257**Step 3 - Build the project using the Lazarus IDE**
244258
245259Configuring Lazarus itself to use the new compiler should not normally be necessary because fpc should be able to find the symlink created, but if you have trouble in this part you can try to hard code the compiler path to use the new crosscompiler. To hardcode the compiler path in cause of trouble go to the menu "Tools-\>Options" and change the "Compiler Path" to "/usr/bin/ppcrossarm"
246260
247261But it is necessary to configure the LPI file to build the example. Open the Project Options dialog of the androidlcltest.lpi project and go to the section Paths and change the libraries path to reflect the correct paths of where your Android NDK was installed and where your jnigraphics.so, libc.so, etc, libraries are located for your target Android API level. For LCL-CustomDrawn-Android API level 8 is the best choice, because it supports Android 2.2+ like the LCL. The image below shows where to configure this:
248262
249263![](/wiki-images/b/b0/Configure_androidlcl_libraries.jpg)
250264
251265The actual lazarus release contains a error, they create a .so.so - file instead of a .so - file. So you have to change this manually in lazarus.
252266
253267**Step 4 - Build the APK**
254268
255269If you are using Windows, use these instructions to build the APK: [[Custom Drawn Interface/Android|Custom Drawn Interface/Android#Step_4_-_Creating_the_APK_package_in_Windows]]
256270
257271If you are using Linux follow these instructions instead: Before going to the command line to build the APK open the file lazarus/examples/androidlcl/android/local.properties and change it to reflect your Android SDK path. The file says you should not modify it, but ignore that and modify it anyway. Here is how the file looks like:
258272
259273 # This file is automatically generated by Android Tools.
260274 # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
261275 #
262276 # This file must *NOT* be checked in Version Control Systems,
263277 # as it contains information specific to your local configuration.
264278
265279 # location of the SDK. This is only used by Ant
266280 # For customization when using a Version Control System, please read the
267281 # header note.
268282 sdk.dir=/home/felipe/Programas/android-sdk-linux
269283
270284After configuring that one, go to the command line and issue these commands:
271285
272-` cd lazarus/examples/androidlcl/android`\
273-` ant debug`
286+```text
287+ cd lazarus/examples/androidlcl/android
288+ ant debug
289+```
274290
275291The APK will be located in lazarus/examples/androidlcl/android/bin
276292
277293**Step 5 - Install the APK in your phone and run it**
278294
279295You can install via ADB or by copying the file to the sdcard. You should see this:
280296
281297![](/wiki-images/4/4c/Lcl_android_30_mar.png)
282298
283299## How to create an LCL Android Application
284300
285301To create a new LCL-CustomDrawn-Android application simply copy all of the file structure and build and java files from the example project called "androidlcl". This example can be obtained from the Lazarus source tree in lazarus/examples/androidlcl
286302
287303Then you will need to modify the build files to change them to your new project name and your new Java package name.
288304
289305### Step 1 - Creating the LPI
290306
291307You need a separate LPI at the moment for the Android version of the application but all the rest of the code can be shared. Create it using the template for a "Library" and then adapt the code from the example located in the lazarus source code in lazarus/examples/androidlcl
292308
293309You need to adapt the exported JNI method names to your Android Package Name.
294310
295311### Step 2 - Building the library
296312
297313First of all, build the Pascal executable without debug information. This debug information is not so useful in Android and makes the executable much bigger. Open the menu Project-\>Project Options and set the build mode, widgetset, architecture and operating system targets, as shown in these screenshots:
298314
299315![](/wiki-images/6/64/Android_project_options_1.png)
300316
301317![](/wiki-images/f/f7/Android_project_options_2.png)
302318
303319![](/wiki-images/9/9f/Android_project_options_3.png)
304320
305321### Step 3 - Create the Android project structure
306322
307323Besides the LCL project building, such as configuring a proper LPI and having a library main project file, one also needs to add all of the android project structure. Simply copy from the example project in lazarus/examples/androidlcl and adapt it to the new project. Things to change are the path to the SDK, the package name. The package name needs to be updated in the build files, in the directory structure android/src/packagename, in the activity java source code and also in the main library pascal source in the exports section.
308324
309325### Step 4 - Creating the APK package
310326
311327#### Step 4 - Creating the APK package in Linux
312328
313329To create the APK package in Linux simply go to the directory "android" inside the project folder and issue the command "ant debug". The package will be in android/bin/MyProject.apk
314330
315-`cd myproject/android ant debug`
331+```text
332+cd myproject/android
333+ant debug
334+```
316335
317336Ant and all dependencies must be installed using the package management of your linux distribution.
318337
319338#### Step 4 - Creating the APK package in Windows
320339
321340**Pre-requisites**:
322341
323342- Java JDK installed: <http://www.oracle.com/technetwork/java/javase/downloads/index.html>
324343- Android SDK Installed
325344
326345**Instructions**:
327346
328347In Windows we provide a APK build system which uses only the tools provided in the Android SDK and therefore does not require ANT.
329348
330349First it is necessary to create a debug key to use. To do this use this script:
331350
332-`lazarus/examples/androidlcl/android/generate_debug_key.bat`
351+```text
352+lazarus/examples/androidlcl/android/generate_debug_key.bat
353+```
333354
334355which can be copied from the example application to your own project folder.
335356
336357it contains following:
337358
338-`REM Adjust these paths to yours`\
339-`SET PATH=C:\Programme\Android\android-sdk\tools;C:\Programme\Android\android-sdk\platform-tools\;C:\Programme\Java\jdk1.6.0_38\bin`\
340-`SET APP_NAME=androidlcltest`\
341-`SET ANDROID_HOME=C:\Programme\Android\android-sdk`\
342-`SET APK_SDK_PLATFORM=C:\Programme\Android\android-sdk\platforms\android-9`\
343-`SET APK_PROJECT_PATH=C:\Programme\lazarus\examples\androidlcl\android`\
359+``` pascal
360+REM Adjust these paths to yours
361+SET PATH=C:\Programme\Android\android-sdk\tools;C:\Programme\Android\android-sdk\platform-tools\;C:\Programme\Java\jdk1.6.0_38\bin
362+SET APP_NAME=androidlcltest
363+SET ANDROID_HOME=C:\Programme\Android\android-sdk
364+SET APK_SDK_PLATFORM=C:\Programme\Android\android-sdk\platforms\android-9
365+SET APK_PROJECT_PATH=C:\Programme\lazarus\examples\androidlcl\android
344366
345-`mkdir bin`\
367+mkdir bin
346368
347-`keytool --help`\
369+keytool --help
348370
349-`keytool -genkey -v -keystore bin\LCLDebugKey.keystore -alias LCLDebugKey -keyalg RSA -validity 10000`\
371+keytool -genkey -v -keystore bin\LCLDebugKey.keystore -alias LCLDebugKey -keyalg RSA -validity 10000
350372
351-`REM call and pause together allow us to see the results in the end`\
352-`pause`\
373+REM call and pause together allow us to see the results in the end
374+pause
375+```
353376
354377You have to fix everything after SET to your own paths. Don't forget adjusting the android version from APK_SDK_PLATFORM!
355378
356379After generating the key, use the other script:
357380
358-`lazarus/examples/androidlcl/android/build_debug_apk.bat`
381+```text
382+lazarus/examples/androidlcl/android/build_debug_apk.bat
383+```
359384
360385To build the APK file. Also remember to edit this batch file to reflect your paths.
361386
362387This script contains the following:
363388
364-`REM Adjust these paths to yours`\
365-`SET PATH=C:\Programme\Android\android-sdk\tools;C:\Programme\Android\android-sdk\platform-tools\;C:\Programme\Java\jdk1.6.0_38\bin`\
366-`SET APP_NAME=androidlcltest`\
367-`SET ANDROID_HOME=C:\Programme\Android\android-sdk`\
368-`SET APK_SDK_PLATFORM=C:\Programme\Android\android-sdk\platforms\android-9`\
369-`SET APK_PROJECT_PATH=C:\lazarus\examples\androidlcl\android `\
389+```text
390+REM Adjust these paths to yours
391+SET PATH=C:\Programme\Android\android-sdk\tools;C:\Programme\Android\android-sdk\platform-tools\;C:\Programme\Java\jdk1.6.0_38\bin
392+SET APP_NAME=androidlcltest
393+SET ANDROID_HOME=C:\Programme\Android\android-sdk
394+SET APK_SDK_PLATFORM=C:\Programme\Android\android-sdk\platforms\android-9
395+SET APK_PROJECT_PATH=C:\lazarus\examples\androidlcl\android
370396
371-`REM Create necessary directory Structure`\
372-`mkdir bin`\
373-`mkdir bin\classes`\
374-`mkdir gen`\
375-`mkdir gen\com`\
376-`mkdir gen\com\pascal`\
377-`mkdir gen\com\pascal\lcltest`\
378-`mkdir raw`\
379-`mkdir raw\lib`\
380-`mkdir raw\lib\armeabi`\
397+REM Create necessary directory Structure
398+mkdir bin
399+mkdir bin\classes
400+mkdir gen
401+mkdir gen\com
402+mkdir gen\com\pascal
403+mkdir gen\com\pascal\lcltest
404+mkdir raw
405+mkdir raw\lib
406+mkdir raw\lib\armeabi
381407
382-`REM Cleanup`\
383-`del bin\%APP_NAME%.ap_`\
384-`del bin\%APP_NAME%.apk`\
385-`del raw\lib\armeabi*.so`\
408+REM Cleanup
409+del bin\%APP_NAME%.ap_
410+del bin\%APP_NAME%.apk
411+del raw\lib\armeabi*.so
386412
387-`REM More directory preparation`\
388-`copy libs\armeabi*.so raw\lib\armeabi\ `\
413+REM More directory preparation
414+copy libs\armeabi*.so raw\lib\armeabi\
389415
390-`REM Resource compilation`\
391-`call aapt p -v -f -M AndroidManifest.xml -F bin\%APP_NAME%.ap_ -I %APK_SDK_PLATFORM%\android.jar -S res -m -J gen raw`\
416+REM Resource compilation
417+call aapt p -v -f -M AndroidManifest.xml -F bin\%APP_NAME%.ap_ -I %APK_SDK_PLATFORM%\android.jar -S res -m -J gen raw
392418
393-`REM Java compiler`\
394-`call javac -verbose -classpath %APK_SDK_PLATFORM%\android.jar -d bin\classes src\com\pascal\lcltest\LCLActivity.java`\
419+REM Java compiler
420+call javac -verbose -classpath %APK_SDK_PLATFORM%\android.jar -d bin\classes src\com\pascal\lcltest\LCLActivity.java
395421
396-`REM DX to convert the java bytecode to dalvik bytecode`\
397-`call dx --dex --verbose --output=%APK_PROJECT_PATH%\bin\classes.dex %APK_PROJECT_PATH%\bin\classes `\
422+REM DX to convert the java bytecode to dalvik bytecode
423+call dx --dex --verbose --output=%APK_PROJECT_PATH%\bin\classes.dex %APK_PROJECT_PATH%\bin\classes
398424
399-`REM It seams that dx calls echo off`\
400-`@echo on`\
401-`REM Now build the unsigned APK`\
402-`del %APK_PROJECT_PATH%\bin\%APP_NAME%-unsigned.apk`\
403-`call apkbuilder %APK_PROJECT_PATH%\bin\%APP_NAME%-unsigned.apk -v -u -z %APK_PROJECT_PATH%\bin\%APP_NAME%.ap_ -f %APK_PROJECT_PATH%\bin\classes.dex`\
425+REM It seams that dx calls echo off
426+@echo on
427+REM Now build the unsigned APK
428+del %APK_PROJECT_PATH%\bin\%APP_NAME%-unsigned.apk
429+call apkbuilder %APK_PROJECT_PATH%\bin\%APP_NAME%-unsigned.apk -v -u -z %APK_PROJECT_PATH%\bin\%APP_NAME%.ap_ -f %APK_PROJECT_PATH%\bin\classes.dex
404430
405-`REM Generating on the fly a debug key`\
406-`rem keytool -genkey -v -keystore bin\LCLDebugKey.keystore -alias LCLDebugKey -keyalg RSA -validity 10000 -dname NAME -storepass senhas  -keypass senhas`\
431+REM Generating on the fly a debug key
432+rem keytool -genkey -v -keystore bin\LCLDebugKey.keystore -alias LCLDebugKey -keyalg RSA -validity 10000 -dname NAME -storepass senhas -keypass senhas
407433
408-`REM Signing the APK with a debug key`\
409-`del bin\%APP_NAME%-unaligned.apk`
434+REM Signing the APK with a debug key
435+del bin\%APP_NAME%-unaligned.apk
436+```
410437
411-`REM Change keypass and storepass pw                        here|         and here|`\
412-`jarsigner -verbose -keystore bin\LCLDebugKey.keystore -keypass senhas -storepass senhas -signedjar bin\%APP_NAME%-unaligned.apk  bin\%APP_NAME%-unsigned.apk LCLDebugKey`\
438+``` pascal
439+REM Change keypass and storepass pw here| and here|
440+jarsigner -verbose -keystore bin\LCLDebugKey.keystore -keypass senhas -storepass senhas -signedjar bin\%APP_NAME%-unaligned.apk bin\%APP_NAME%-unsigned.apk LCLDebugKey
413441
414-`REM Align the final APK package`\
415-`zipalign -v 4 bin\%APP_NAME%-unaligned.apk bin\%APP_NAME%.apk `\
442+REM Align the final APK package
443+zipalign -v 4 bin\%APP_NAME%-unaligned.apk bin\%APP_NAME%.apk
416444
417-`REM call and pause together allow us to see the results in the end`\
418-`pause`
445+REM call and pause together allow us to see the results in the end
446+pause
447+```
419448
420449Don't forget changing the set-variables in the top AND change the pw (see above where).
421450
422451### Building an LCL Android application with debug info
423452
424453It is useful to add another Android build mode which has debug info. Use all of the same options as shown above, except for the debug information:
425454
426455![](/wiki-images/1/11/Android_project_options_4.png)
427456
428457## Oh no! My LCL Android application doesn't work
429458
430459There are various reasons why the app may not work. The most important thing to do when an app doesn't work is to open the logcat and see what the log says. This can be done by running this command line command:
431460
432461``` bash
433462./adb logcat
434463```
435464
436465And then test one of the hypotheses in the next subsections.
437466
438467### The Pascal executable was compiled for a wrong architecture, operating system and/or widgetset
439468
440469This is the leading cause of executables not running. Always verify that you compiled the program to the "android" widgetset, "linux" operating system and "arm" architecture. This is done by going into the menu Project-\>Project Options. Then set these in the dialog all options as explained in this section:
441470
442471[[How to build an LCL Android application]]
443472
444473To check if you library is arm-linux or not, execute the following commands:
445474
446475``` bash
447476cd libs/armeabi
448477ls -l
449478file liblclapp.so
450479ldd liblclapp.so
451480```
452481
453482If it mentions anything like 80386 or gtk, then your program was compiled for linux-x86 and gtk2, not for Android like it should.
454483
455484### My Pascal application crashed. How to get a stacktrace?
456485
457486If a Pascal application crashes you should use the command "adb logcat" to obtain the stack
458487
459488Read also this thread in the Google NDK group about converting addresses to lines: <http://groups.google.com/group/android-ndk/msg/2ed2286e85f4ccdd>?
460489
461490### The indispensable build options
462491
463492- -Xd This build option is indispensable when cross-compiling from x86-linux to Android or else FPC will try to link the application against for example /usr/lib/libc.so instead of the libc.so in the NDK, even if you specify a -Fl library path
464493- -CpARMV6 This build option is indispensable because code generated for older ARM versions is unsupported by Android and might crash in some devices. See <http://groups.google.com/group/android-ndk/browse_thread/thread/ba542483f062a828>
465494- -dAndroid in the package LCLBase.lpk
466495- -Parm -Tlinux for the process and target operating system
467496- -Fl should contain the path to the NDK directory with the target link shared object, such as libc.so, liblog.so, libjni.so, etc
468497
469498### Wrong package name
470499
471500If you change the package name of the project, then you need to adapt the main project file to inform the widgetset of the change. In the example project this is done in the main project file, androidlcltest.lpr in this part:
472501
473502 CDWidgetset.ActivityClassName := 'com/pascal/lcltest/LCLActivity';
474503
475504If your new package name is com.pascal.myapp, then you should change the command above to this:
476505
477506 CDWidgetset.ActivityClassName := 'com/pascal/myapp/LCLActivity';
478507
479508## Free Pascal Bugs on Android Support
480509
481510The following summarizes the state of Android Support in Free Pascal:
482511
483512- The pre-compiled snapshot for x86-linux -\> Android is known to work very well and it was built on 19th January 2011: <https://sourceforge.net/projects/p-tools/files/Free%20Pascal%20for%20ARM/>
484513- On February this revision <http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&revision=16981> introduced this bug: <http://mantis.freepascal.org/view.php?id=18833>
485514- In the end of 2011 this revision <http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&revision=19036> broke linking Android projects
486515
487516We are in contact with FPC developers to fix the situation as can be seen in: <http://mantis.freepascal.org/view.php?id=20726>
488517
489518### FPC4Android Branches
490519
491520Because of FPC bugs related to Android support I have rolled my own branches.
492521
493522#### FPC4Android 2.5.1
494523
495524FPC4Android 2.5.1 has the following fixes applied to it:
496525
497526<http://bugs.freepascal.org/view.php?id=21208> <http://bugs.freepascal.org/view.php?id=21341> <http://bugs.freepascal.org/view.php?id=19559>
498527
499528And I have created a pre-compiled x86-linux -\> android-arm cross-compiler and hosted it here (it is the -v2 cross-compiler);
500529
501530<https://sourceforge.net/projects/p-tools/files/Free%20Pascal%20for%20ARM/>
502531
503532To download the source execute:
504533
505-`svn co `[`https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android`](https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android)` fpc4android`
534+```text
535+svn co https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android fpc4android
536+```
506537
507538#### FPC4Android 2.6.1
508539
509540This branch is not finished, it lacks patches to fix Android support, patches are welcome. SVN link:
510541
511-`svn co `[`https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android_2_6`](https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android_2_6)` fpc4android_2_6`
542+```text
543+svn co https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android_2_6 fpc4android_2_6
544+```
512545
513546## Android SDK and NDK bugs
514547
515548### Android NDK for Windows broken linker
516549
517550The linker in android-ndk-r7b (path C:\Programas\android-ndk-r7\toolchains\arm-linux-androideabi-4.4.3\prebuilt\windows\bin\arm-linux-androideabi-ld.exe) crashes for no reason while linking LCL apps =( The linker from android-ndk-r7 and r5 work correctly.
518551
519552See <http://groups.google.com/group/android-ndk/browse_thread/thread/d8c88bd58ad6df87>
520553
521554### Error while calling DX: Trouble processing: bad class file magic (cafebabe)
522555
523556If while using the build script you get the following errors:
524557
525558 D:\djsystem\djpalm\android>call dx --dex --verbose --output=D:\djsystem\djpalm\a
526559 ndroid\bin\classes.dex D:\djsystem\djpalm\android\bin\classes
527560 processing D:\djsystem\djpalm\android\bin\classes\.\com\pascal\djpalm\LCLActivit
528561 y$1.class...
529562
530563 trouble processing:
531564 bad class file magic (cafebabe) or version (0033.0000)
532565 ...while parsing com/pascal/djpalm/LCLActivity$1.class
533566 ...while processing com/pascal/djpalm/LCLActivity$1.class
534567 processing D:\djsystem\djpalm\android\bin\classes\.\com\pascal\djpalm\LCLActivit
535568 y$2.class...
536569
537570 trouble processing:
538571 bad class file magic (cafebabe) or version (0033.0000)
539572 ...while parsing com/pascal/djpalm/LCLActivity$2.class
540573 ...while processing com/pascal/djpalm/LCLActivity$2.class
541574 processing D:\djsystem\djpalm\android\bin\classes\.\com\pascal\djpalm\LCLActivit
542575 y$3.class...
543576
544577This probably means that you are using JDK 7. Unfortunatelly the current Android SDK r20 is not compatible with JDK 7, only with JDK 5 and 6. Please install JDK 6 and use that instead. See:
545578
546579- <http://stackoverflow.com/questions/8538891/bad-class-file-magic-when-using-dx-bat>
547580- <http://www.oracle.com/technetwork/java/javase/downloads/jdk6-downloads-1637591.html>
548581
549582## Development Notes
550583
551584### The mysterious JNI Crash (SIGILL - illegal instruction)
552585
553586See the thread: <http://groups.google.com/group/android-ndk/browse_thread/thread/ba542483f062a828>
554587
555588The problem was that vm^^.GetEnv would crash in HTC Wildfire, Alcatel and in the emulator with SIGILL but not in Xperia Mini, HTC Desire HD, Motorola Atrix and other smartphones.
556589
557590The answer was that one needs to specify -CpARMV6 when building because older instructions might fail in some devices. Also try restarting the emulator or running on a different device.
558591
559592### NDK Libraries available in Android 2.2 (API level 8)
560593
561594LCL-CustomDrawn targets Android 2.2+ and in this API level the following libraries are supported by the NDK:
562595
5635961. libc.so
5645972. libdl.so (linker)
5655983. OpenGL ES 1
5665994. OpenGL ES 2
5676005. libjnigraphics.so
5686016. liblog.so
5696027. libm.so
5706038. libz.so
5716049. libthread_db.so
57260510. libstdc++.so
573606
574607LCL-CustomDrawn-Android uses libjnigraphics.so and liblog.so at the moment.
575608
576609### Native text drawing
577610
578611Native text drawing is a bit convoluted in Android and the documentation is quite bad too. Some gotchas already found:
579612
580613- It draws text starting on a Y coordinate which represents the baseline, which is the bottom of strings like "abc", but not the bottom of strings like "qg". See <http://code.google.com/p/android/issues/detail?id=393>
581614- There is no documentation about what the size in Paint.setTextSize represents. Some people say it is pixels, but to me it looks something else because it seams to differ across devices.
582615
583616But there are also good things about it:
584617
585618- It can draw on a transparent bitmap and use alpha transparency to implement anti-aliasing and subpixel rendering. The text gets quite beaultiful.
586619- It can draw on the ARGB 32-bits non-premultiplied format which is a pretty good one
587620
588621### Flood of garbage collector messages when the caret is visible
589622
590623Something like this:
591624
592625 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 188 objects / 6664 bytes in 94ms
593626 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 170 objects / 6160 bytes in 78ms
594627 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5904 bytes in 82ms
595628 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5856 bytes in 78ms
596629 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5872 bytes in 80ms
597630 D/dalvikvm( 2825): GC_EXPLICIT freed 371 objects / 18480 bytes in 91ms
598631 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5896 bytes in 78ms
599632 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5896 bytes in 78ms
600633 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5896 bytes in 81ms
601634 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5920 bytes in 78ms
602635 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5920 bytes in 83ms
603636
604637In my investigation this happens probably because the TCDEdit will request a full control invalidate on each timer tick, which currently will main a full form invalidate, so the GC needs to collect the bitmaps and other paint objects when painting that often.
605638
606639### Why the caret of a TEdit keeps blinking after clicking on the form
607640
608641When clicking on the form the LCL focus will refuse to move from the Edit to the Form because this behavior seems to be hard coded in the LCL, although maybe we might change this for Android. So even while we set focus into the form, the LCL refuses to do that and keeps its focus in the Edit, thus we have a focus mismatch. This might eventually be fixed in the future.
609642
610643### Android ComboBox
611644
612645For adding Android combobox support a new method was added to LCLIntf along with a global variable to store the callback of this dialog:
613646
614647``` pascal
615648var
616649 OnShowSelectItemDialogResult: TOnShowSelectItemDialogResult;
617650
618651function ShowSelectItemDialog(const AItems: TStrings): Boolean; override;
619652```
620653
621654This method will run a native item selection dialog, if the platform has one, or result false without doing anything otherwise.
622655
623656![](/wiki-images/8/82/Android_combobox.png)
624657
625658### Using the Native ListView Dialog
626659
627660To allow the user to select items from a list more easily we offer a routine which launch dialog with the native ListView.
628661
629662``` pascal
630663{$ifdef LCLCustomDrawn}
631664uses customdrawnint, lclintf;
632665{$endif}
633666
634667procedure TForm2.Button3Click(Sender: TObject);
635668begin
636669{$ifdef LCLCustomDrawn}
637670 LCLIntf.OnListViewDialogResult := @MyOnListViewDialogResult;
638671 CDWidgetSet.ShowListViewDialog('Dialog Title',
639672 ['Title1', 'Title2', 'Title3', 'Title4', 'Title5', 'Title6'],
640673 ['Descr1', 'Descr2', 'Descr3', 'Descr4', 'Descr5', 'Descr6']);
641674{$endif}
642675end;
643676
644677procedure TForm2.MyOnListViewDialogResult(ASelectedItem: Integer);
645678begin
646679 DebugLn(Format('[MyOnListViewDialogResult] ASelectedItem=%d', [ASelectedItem]));
647680end;
648681```
649682
650683LCLIntf.OnListViewDialogResult will be called with the selected item, with a zero-based index, or -1 if the dialog was cancelled by the user. One way to cancel the dialog is when the user pressed the back button.
651684
652685Note that there are 2 more parameters in the end of this routine with default values, which allow choosing the color for the odd and the other for the even rows. The color is an integer of 32-bits in the ARGB format, don't use TColor here!
653686
654687``` pascal
655688procedure TCDWidgetSet.ShowListViewDialog(ATitle: string; ATitles,
656689 ADescriptions: array of string;
657690 AColorOddRow: jint = $ff292C29; AColorEvenRow: jint = $ff424542);
658691```
659692
660693![](/wiki-images/2/2c/Android_ListView.png)
661694
662695### LazDeviceAPIs
663696
664697See: [[LazDeviceAPIs]]
665698
666699---
667700*From the Free Pascal wiki, page "Custom Drawn Interface/Android", as it stood on 2021-01-08 after a change by Giorgio Tani, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
668701Category: Android
669702Category: Custom Drawn

Back to history