Sign in Join
Wiki copytemporary

Custom Drawn Interface/Android: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-*(Android only)*
1+[![Android robot.svg](https://upload.wikimedia.org/wikipedia/commons/thumb/d/d7/Android_robot.svg/50px-Android_robot.svg.png)](</File:Android_robot.svg>)
22
3-> **Warning:** THIS INFORMATION IS DATED AND NEEDS UPDATING
3+This article applies to [Android](</Category:Android> "Category:Android") only.
44
5+See also: [[Multiplatform Programming Guide]]
6+
7+[![Warning-icon.png](/wiki-images/b/b2/Warning-icon.png)](</File:Warning-icon.png>)
8+
9+**Warning:** THIS INFORMATION IS DATED AND NEEDS UPDATING
10+
11+│ **English (en)** │ **[[Custom Drawn Interface/Android/es|español (es)]]** │ **[[Custom Drawn Interface/Android/ja|日本語 (ja)]]** │ **[[Custom Drawn Interface/Android/ru|русский (ru)]]** │
12+****
13+
514Go back to [[Custom Drawn Interface]]
615
16+## Contents
17+
18+ * 1 Architecture
19+ * 2 Roadmap
20+ * 3 Using the Android SDK, Emulator and Phones
21+ * 4 Android Programming
22+ * 5 Configuring the Free Pascal Compiler for Android
23+ * 5.1 Use the ready Virtual Box Image with FPC and Lazarus
24+ * 5.2 Building the compiler yourself in Windows
25+ * 5.3 Using the pre-compiled compiler in Windows
26+ * 5.4 Building the compiler yourself in Linux
27+ * 5.5 Using the pre-compiled compiler in Linux
28+ * 6 Install the Java JDK and the Android SDK and NDK
29+ * 7 Compiling the example LCL Android Application
30+ * 8 How to create an LCL Android Application
31+ * 8.1 Step 1 - Creating the LPI
32+ * 8.2 Step 2 - Building the library
33+ * 8.3 Step 3 - Create the Android project structure
34+ * 8.4 Step 4 - Creating the APK package
35+ * 8.4.1 Step 4 - Creating the APK package in Linux
36+ * 8.4.2 Step 4 - Creating the APK package in Windows
37+ * 8.5 Building an LCL Android application with debug info
38+ * 9 Oh no! My LCL Android application doesn't work
39+ * 9.1 The Pascal executable was compiled for a wrong architecture, operating system and/or widgetset
40+ * 9.2 My Pascal application crashed. How to get a stacktrace?
41+ * 9.3 The indispensable build options
42+ * 9.4 Wrong package name
43+ * 10 Free Pascal Bugs on Android Support
44+ * 10.1 FPC4Android Branches
45+ * 10.1.1 FPC4Android 2.5.1
46+ * 10.1.2 FPC4Android 2.6.1
47+ * 11 Android SDK and NDK bugs
48+ * 11.1 Android NDK for Windows broken linker
49+ * 11.2 Error while calling DX: Trouble processing: bad class file magic (cafebabe)
50+ * 12 Development Notes
51+ * 12.1 The mysterious JNI Crash (SIGILL - illegal instruction)
52+ * 12.2 NDK Libraries available in Android 2.2 (API level 8)
53+ * 12.3 Native text drawing
54+ * 12.4 Flood of garbage collector messages when the caret is visible
55+ * 12.5 Why the caret of a TEdit keeps blinking after clicking on the form
56+ * 12.6 Android ComboBox
57+ * 12.7 Using the Native ListView Dialog
58+ * 12.8 LazDeviceAPIs
59+
760## Architecture
861
9-LCL-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.
62+LCL-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.
1063
11-Our 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]].
64+Our 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]].
1265
1366## Roadmap
1467
15-Part 1, until March 2012:
68+Part 1, until March 2012:
1669
17-1. Build the set of [[Lazarus Custom Drawn Controls]]
18-2. Initial bindings for the Android APIs
19-3. Create an application to automatically generate the bindings
20-4. Start the new widgetset
21-5. Implement support for JNI
22-6. Merge the Lazarus Custom Drawn Controls into the LCL and use them to implement all basic controls
23-7. Add text support for Android
24-8. Implement basic window client area scrolling
25-9. Add mobile emulator for desktop platforms
26-10. Improve the mobile scrolling
27-11. Add text support in X11
28-12. Add DPI awareness and adaptation in the LCL
29-13. Add non-native text support via pasfreetype
70+ 1. ~~Build the set of[[Lazarus Custom Drawn Controls]]~~
71+ 2. ~~Initial bindings for the Android APIs~~
72+ 3. ~~Create an application to automatically generate the bindings~~
73+ 4. ~~Start the new widgetset~~
74+ 5. ~~Implement support for JNI~~
75+ 6. ~~Merge the Lazarus Custom Drawn Controls into the LCL and use them to implement all basic controls~~
76+ 7. ~~Add text support for Android~~
77+ 8. ~~Implement basic window client area scrolling~~
78+ 9. Add mobile emulator for desktop platforms
79+ 10. Improve the mobile scrolling
80+ 11. ~~Add text support in X11~~
81+ 12. ~~Add DPI awareness and adaptation in the LCL~~
82+ 13. ~~Add non-native text support via pasfreetype~~
3083
31-Part 2: April, May, June 2012:
84+Part 2: April, May, June 2012:
3285
33-1. TButton improve the Android visual
34-2. TBitBtn
35-3. TRadioButton finish the native look
36-4. 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
37-5. MaskEdit
38-6. Improve TComboBox
39-7. TMemo
40-8. TListView as a list with columns
41-9. TMainMenu
42-10. Database with sqlite
43-11. Barcode reading
44-12. Windows add-on installer
86+ 1. ~~TButton improve the Android visual~~
87+ 2. TBitBtn
88+ 3. ~~TRadioButton finish the native look~~
89+ 4. 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
90+ 5. MaskEdit
91+ 6. ~~Improve TComboBox~~
92+ 7. TMemo
93+ 8. TListView as a list with columns
94+ 9. ~~TMainMenu~~
95+ 10. Database with sqlite
96+ 11. Barcode reading
97+ 12. Windows add-on installer
4598
4699## Using the Android SDK, Emulator and Phones
47100
48101[[Custom Drawn Interface/Using the Android SDK, Emulator and Phones]]
49102
50103## Android Programming
51104
52-See [[Android Programming]], also includes caracteristics of the various phones relevant for programming.
105+See [[Android Programming]], also includes caracteristics of the various phones relevant for programming.
53106
54107## Configuring the Free Pascal Compiler for Android
55108
56-| NOTE: |
57-|----|
58-| 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]]. |
59-
109+NOTE:
110+---
111+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]].
112+
60113### Use the ready Virtual Box Image with FPC and Lazarus
61114
62-The 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.
115+The 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.
63116
64-The 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.
117+The 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.
65118
66-The 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”.
119+The 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”.
67120
68-Note 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.
121+Note 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.
69122
70123### Building the compiler yourself in Windows
71124
72-**Step 1** - Install the Android SDK and NDK
73-
74-Download from Google and install both the SDK and the NDK for Windows.
125+**Step 1** \- Install the Android SDK and NDK
75126
76-Check 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
127+Download from Google and install both the SDK and the NDK for Windows.
77128
78-Also 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
129+Check 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
79130
80-**Step 2** - Download FPC 2.5.1 from January 19th
131+Also 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
81132
82-Create a folder to store the FPC trunk source code and checkout revision 16790
133+**Step 2** \- Download FPC 2.5.1 from January 19th
83134
84-Or if you want support for database and many other nice fixes use the branch fpc4android from here:
135+Create a folder to store the FPC trunk source code and checkout revision 16790
85136
86-svn co <https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android> fpc4android
137+Or if you want support for database and many other nice fixes use the branch fpc4android from here:
87138
88-**Step 3** - Install FPC 2.4.4
139+svn co <https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android> fpc4android
89140
90-An 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
141+**Step 3** \- Install FPC 2.4.4
91142
92-**Step 4** - Create the build script and built it
143+An 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
93144
94-Create the output directory, for example: C:\Programas\fpcandroid\output
145+**Step 4** \- Create the build script and built it
95146
96-Next create a file called build.bat in the fpc root folder, in our example C:\Programas\fpcandroid and copy to it:
147+Create the output directory, for example: C:\Programas\fpcandroid\output
97148
98- SET PATH=C:\Programas\lazarusfpc244\fpc\2.4.4\bin\i386-win32\
149+Next create a file called build.bat in the fpc root folder, in our example C:\Programas\fpcandroid and copy to it:
150+```
151+SET PATH=C:\Programas\lazarusfpc244\fpc\2.4.4\bin\i386-win32\
99152 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
100153 pause
154+```
101155
102-Next run this batch script and you should have FPC installed into C:\Programas\fpcandroid\output
156+Next run this batch script and you should have FPC installed into C:\Programas\fpcandroid\output
103157
104-**Step 5** - Copy some cross-binutils into the bin dir
158+**Step 5** \- Copy some cross-binutils into the bin dir
105159
106-You now should have a FPC binary in C:\Programas\fpcandroid\output\bin\i386-win32
160+You now should have a FPC binary in C:\Programas\fpcandroid\output\bin\i386-win32
107161
108-Now get these 3 files:
162+Now get these 3 files:
109163
110-C:\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
164+C:\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
111165
112-And copy and then rename to have:
166+And copy and then rename to have:
113167
114-C:\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
168+C:\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
115169
116-**Step 6** - Merge this into a Lazarus FPC setup
170+**Step 6** \- Merge this into a Lazarus FPC setup
117171
118-Let'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\\
172+Let'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\
119173
120-Now create a directory C:\Programas\lazarus31\fpc\2.5.1\units\arm-linux and copy C:\Programas\fpcandroid\output\units\arm-linux there
174+Now create a directory C:\Programas\lazarus31\fpc\2.5.1\units\arm-linux and copy C:\Programas\fpcandroid\output\units\arm-linux there
121175
122-Copy all .exe files from C:\Programas\fpcandroid\output\bin\i386-win32\\ into C:\Programas\lazarus31\fpc\2.6.1\bin\i386-win32
176+Copy all .exe files from C:\Programas\fpcandroid\output\bin\i386-win32\ into C:\Programas\lazarus31\fpc\2.6.1\bin\i386-win32
123177
124-(! copy the exe-files to FPC 2.6.1 !)
178+(! copy the exe-files to FPC 2.6.1 !)
125179
126-Now you can already build the example project androidlcltest.lpi using the Windows-Release build mode
180+Now you can already build the example project androidlcltest.lpi using the Windows-Release build mode
127181
128182### Using the pre-compiled compiler in Windows
129183
130-**Step 1** - Download and unzip the pre-compiled compiler
184+**Step 1** \- Download and unzip the pre-compiled compiler
131185
132186The download is available here: <https://sourceforge.net/projects/p-tools/files/Free%20Pascal%20for%20ARM/Windows/>
133187
134-**Step 2** - Merge it into the FPC installation
188+**Step 2** \- Merge it into the FPC installation
135189
136-Let'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\\
190+Let'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\
137191
138-Now 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
192+Now 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
139193
140-Copy 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)
194+Copy 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)
141195
142-**Step 3** - Install the Java JDK and the Android SDK and NDK
196+**Step 3** \- Install the Java JDK and the Android SDK and NDK
143197
144-If 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.
198+If 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.
145199
146-- Java JDK (!WARNING! Download JDK version 6! Version 7 does not work!!!): <http://www.oracle.com/technetwork/java/javase/downloads/index.html>
147-- 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>
148-- Android NDK version 7 download link: <http://dl.google.com/android/ndk/android-ndk-r7-windows.zip>
200+ * Java JDK (!WARNING! Download JDK version 6! Version 7 does not work!!!): <http://www.oracle.com/technetwork/java/javase/downloads/index.html>
201+ * 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>
202+ * Android NDK version 7 download link: <http://dl.google.com/android/ndk/android-ndk-r7-windows.zip>
149203
150204Now 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]]
151205
152206### Building the compiler yourself in Linux
153207
154-See [[Setup Cross Compile For ARM]] and make sure to use the option OPT="-dFPC_ARMEL" for building the compiler.
208+See [[Setup Cross Compile For ARM]] and make sure to use the option OPT="-dFPC_ARMEL" for building the compiler.
155209
156210### Using the pre-compiled compiler in Linux
157211
158-A pre-compiled compiler is provided for convenience for users. The following steps were tested in Mandriva Linux 2010.0 and 2010.1:
212+A pre-compiled compiler is provided for convenience for users. The following steps were tested in Mandriva Linux 2010.0 and 2010.1:
159213
160214**Required Environment**
161215
162-- The latest stable FPC installed in the system via the RPM / DEB / TAR package
216+ * The latest stable FPC installed in the system via the RPM / DEB / TAR package
163217
164-**Step 1** - Install the cross-binutils
218+**Step 1** \- Install the cross-binutils
165219
166220For 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>
167221
168-Just download the RPM package and install it using:
169-
170-`rpm -ivh cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm `
171-
172-In 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:
222+Just download the RPM package and install it using:
223+```
224+rpm -ivh cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm
225+```
173226
174-`rpm -ivh --nodeps cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm `
227+In 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:
228+```
229+rpm -ivh --nodeps cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm
230+```
175231
176232For other distributions use the corresponding package, or else read the instructions for building the cross-binutils yourself at [[Setup Cross Compile For ARM]]
177233
178-**Step 2** - Configure the cross-binutils
179-
180-The 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:
181-
182-`su`\
183-`mv /usr/bin/arm-linux-as /usr/bin/arm-linux-as_org`\
184-`gedit /usr/bin/arm-linux-as`
185-
186-Now paste into the editor this code:
234+**Step 2** \- Configure the cross-binutils
187235
188-`#!/bin/sh`\
189-`/usr/bin/arm-linux-as_org -meabi=5 $@`
236+The 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:
237+```
238+su
239+ mv /usr/bin/arm-linux-as /usr/bin/arm-linux-as_org
240+ gedit /usr/bin/arm-linux-as
241+```
190242
191-And don't forget to then make it executable:
243+Now paste into the editor this code:
244+```
245+#!/bin/sh
246+ /usr/bin/arm-linux-as_org -meabi=5 $@
247+```
192248
193-`chmod 755 /usr/bin/arm-linux-as`
249+And don't forget to then make it executable:
250+```
251+chmod 755 /usr/bin/arm-linux-as
252+```
194253
195-**Step 3** - Install the Free Pascal Cross-Compiler
254+**Step 3** \- Install the Free Pascal Cross-Compiler
196255
197256At this point the pre-compiled FPC can be download from here: <http://sourceforge.net/projects/p-tools/files/Free%20Pascal%20for%20ARM/>
198257
199-Then use these commands to install the pre-compiled Free Pascal cross-compiler into /usr:
200-
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`
210-
211-**Step 4** - Verify if your Cross-Compiler works
258+Then use these commands to install the pre-compiled Free Pascal cross-compiler into /usr:
259+```
260+[felipe@localhost Programas]$ ls -l
261+ total 20664
262+ -rw-rw-r-- 1 felipe felipe 17098552 2010-10-25 08:17 fpc-2.5.1.arm-linux.tar.gz
263+ [felipe@localhost Programas]$ su
264+ Password:
265+ [root@localhost Programas]# cp fpc-2.5.1.arm-linux.tar.gz /usr/
266+ [root@localhost Programas]# cd /usr/
267+ [root@localhost usr]# tar -xvf fpc-2.5.1.arm-linux.tar.gz
268+ [root@localhost usr]# ln -s /usr/lib/fpc/2.5.1/ppcrossarm /usr/bin/ppcrossarm
269+```
212270
213-If you made no errors in the previous steps, it should work, so try to call it like this:
271+**Step 4** \- Verify if your Cross-Compiler works
214272
215-`[felipe@localhost Programas]$ /usr/bin/ppcrossarm`
273+If you made no errors in the previous steps, it should work, so try to call it like this:
274+```
275+[felipe@localhost Programas]$ /usr/bin/ppcrossarm
276+```
216277
217-If 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:
278+If 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:
218279
219-\[felipe@localhost Programas\]\$ ls -ls /usr/bin/ppc*
280+[felipe@localhost Programas]$ ls -ls /usr/bin/ppc*
220281
221-Now 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.
282+Now 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.
222283
223284## Install the Java JDK and the Android SDK and NDK
224285
225-If 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.
286+If 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.
226287
227-- Java JDK (Choose version 6!): <http://www.oracle.com/technetwork/java/javase/downloads/index.html>
228-- Android SDK Download (Choose Use an existing IDE!): <http://developer.android.com/sdk/index.html>
229-- Android NDK version 7 download link: <http://dl.google.com/android/ndk/android-ndk-r7-windows.zip>
288+ * Java JDK (Choose version 6!): <http://www.oracle.com/technetwork/java/javase/downloads/index.html>
289+ * Android SDK Download (Choose Use an existing IDE!): <http://developer.android.com/sdk/index.html>
290+ * Android NDK version 7 download link: <http://dl.google.com/android/ndk/android-ndk-r7-windows.zip>
230291
231292Now 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]]
232293
233294## Compiling the example LCL Android Application
234295
235296**Step 1 - Download the source code**
236297
237-The source code of the example is located inside the Lazarus sources in lazarus/examples/androidlcl/androidlcltest.lpi
298+The source code of the example is located inside the Lazarus sources in lazarus/examples/androidlcl/androidlcltest.lpi
238299
239300**Step 2 - Make sure you have the Java JDK and the Android SDK and NDK installed**
240301
241302Read here: [[Custom Drawn Interface/Android|Custom_Drawn_Interface/Android#Install_the_Java_JDK_and_the_Android_SDK_and_NDK]]
242303
243304**Step 3 - Build the project using the Lazarus IDE**
244305
245-Configuring 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"
306+Configuring 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"
246307
247-But 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:
308+But 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:
248309
249-![](/wiki-images/b/b0/Configure_androidlcl_libraries.jpg)
310+[![Configure androidlcl libraries.jpg](/wiki-images/b/b0/Configure_androidlcl_libraries.jpg)](</File:Configure_androidlcl_libraries.jpg>)
250311
251-The 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.
312+The 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.
252313
253314**Step 4 - Build the APK**
254315
255316If 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]]
256317
257-If 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:
258-
259- # This file is automatically generated by Android Tools.
318+If 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:
319+```
320+# This file is automatically generated by Android Tools.
260321 # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
261322 #
262323 # This file must *NOT* be checked in Version Control Systems,
263324 # as it contains information specific to your local configuration.
264-
325+
265326 # location of the SDK. This is only used by Ant
266327 # For customization when using a Version Control System, please read the
267328 # header note.
268329 sdk.dir=/home/felipe/Programas/android-sdk-linux
269-
270-After configuring that one, go to the command line and issue these commands:
330+```
271331
272-` cd lazarus/examples/androidlcl/android`\
273-` ant debug`
332+After configuring that one, go to the command line and issue these commands:
333+```
334+cd lazarus/examples/androidlcl/android
335+ ant debug
336+```
274337
275-The APK will be located in lazarus/examples/androidlcl/android/bin
338+The APK will be located in lazarus/examples/androidlcl/android/bin
276339
277340**Step 5 - Install the APK in your phone and run it**
278341
279-You can install via ADB or by copying the file to the sdcard. You should see this:
342+You can install via ADB or by copying the file to the sdcard. You should see this:
280343
281-![](/wiki-images/4/4c/Lcl_android_30_mar.png)
344+[![lcl android 30 mar.png](/wiki-images/3/3e/lcl_android_30_mar.png)](</File:lcl_android_30_mar.png>)
282345
283346## How to create an LCL Android Application
284347
285-To 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
348+To 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
286349
287-Then you will need to modify the build files to change them to your new project name and your new Java package name.
350+Then you will need to modify the build files to change them to your new project name and your new Java package name.
288351
289352### Step 1 - Creating the LPI
290353
291-You 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
354+You 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
292355
293-You need to adapt the exported JNI method names to your Android Package Name.
356+You need to adapt the exported JNI method names to your Android Package Name.
294357
295358### Step 2 - Building the library
296359
297-First 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:
360+First 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:
298361
299-![](/wiki-images/6/64/Android_project_options_1.png)
362+[![Android project options 1.png](/wiki-images/6/64/Android_project_options_1.png)](</File:Android_project_options_1.png>)
300363
301-![](/wiki-images/f/f7/Android_project_options_2.png)
364+[![Android project options 2.png](/wiki-images/f/f7/Android_project_options_2.png)](</File:Android_project_options_2.png>)
302365
303-![](/wiki-images/9/9f/Android_project_options_3.png)
366+[![Android project options 3.png](/wiki-images/9/9f/Android_project_options_3.png)](</File:Android_project_options_3.png>)
304367
305368### Step 3 - Create the Android project structure
306369
307-Besides 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.
370+Besides 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.
308371
309372### Step 4 - Creating the APK package
310373
311374#### Step 4 - Creating the APK package in Linux
312375
313-To 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
376+To 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
314377
315-`cd myproject/android ant debug`
378+` cd myproject/android ant debug `
316379
317-Ant and all dependencies must be installed using the package management of your linux distribution.
380+Ant and all dependencies must be installed using the package management of your linux distribution.
318381
319382#### Step 4 - Creating the APK package in Windows
320383
321-**Pre-requisites**:
322-
323-- Java JDK installed: <http://www.oracle.com/technetwork/java/javase/downloads/index.html>
324-- Android SDK Installed
325-
326-**Instructions**:
327-
328-In Windows we provide a APK build system which uses only the tools provided in the Android SDK and therefore does not require ANT.
329-
330-First it is necessary to create a debug key to use. To do this use this script:
331-
332-`lazarus/examples/androidlcl/android/generate_debug_key.bat`
333-
334-which can be copied from the example application to your own project folder.
335-
336-it contains following:
337-
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`\
344-
345-`mkdir bin`\
346-
347-`keytool --help`\
348-
349-`keytool -genkey -v -keystore bin\LCLDebugKey.keystore -alias LCLDebugKey -keyalg RSA -validity 10000`\
350-
351-`REM call and pause together allow us to see the results in the end`\
352-`pause`\
353-
354-You have to fix everything after SET to your own paths. Don't forget adjusting the android version from APK_SDK_PLATFORM!
355-
356-After generating the key, use the other script:
357-
358-`lazarus/examples/androidlcl/android/build_debug_apk.bat`
359-
360-To build the APK file. Also remember to edit this batch file to reflect your paths.
361-
362-This script contains the following:
363-
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 `\
370-
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`\
381-
382-`REM Cleanup`\
383-`del bin\%APP_NAME%.ap_`\
384-`del bin\%APP_NAME%.apk`\
385-`del raw\lib\armeabi*.so`\
384+**Pre-requisites** :
386385
387-`REM More directory preparation`\
388-`copy libs\armeabi*.so raw\lib\armeabi\ `\
386+ * Java JDK installed: <http://www.oracle.com/technetwork/java/javase/downloads/index.html>
387+ * Android SDK Installed
389388
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`\
389+**Instructions** :
392390
393-`REM Java compiler`\
394-`call javac -verbose -classpath %APK_SDK_PLATFORM%\android.jar -d bin\classes src\com\pascal\lcltest\LCLActivity.java`\
391+In Windows we provide a APK build system which uses only the tools provided in the Android SDK and therefore does not require ANT.
395392
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 `\
393+First it is necessary to create a debug key to use. To do this use this script:
394+```
395+lazarus/examples/androidlcl/android/generate_debug_key.bat
396+```
398397
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`\
398+which can be copied from the example application to your own project folder.
404399
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`\
400+it contains following:
401+```
402+REM Adjust these paths to yours
403+ SET PATH=C:\Programme\Android\android-sdk\tools;C:\Programme\Android\android-sdk\platform-tools\;C:\Programme\Java\jdk1.6.0_38\bin
404+ SET APP_NAME=androidlcltest
405+ SET ANDROID_HOME=C:\Programme\Android\android-sdk
406+ SET APK_SDK_PLATFORM=C:\Programme\Android\android-sdk\platforms\android-9
407+ SET APK_PROJECT_PATH=C:\Programme\lazarus\examples\androidlcl\android
408+
409+ mkdir bin
410+
411+ keytool --help
412+
413+ keytool -genkey -v -keystore bin\LCLDebugKey.keystore -alias LCLDebugKey -keyalg RSA -validity 10000
414+
415+ REM call and pause together allow us to see the results in the end
416+ pause
417+```
407418
408-`REM Signing the APK with a debug key`\
409-`del bin\%APP_NAME%-unaligned.apk`
419+You have to fix everything after SET to your own paths. Don't forget adjusting the android version from APK_SDK_PLATFORM!
410420
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`\
421+After generating the key, use the other script:
422+```
423+lazarus/examples/androidlcl/android/build_debug_apk.bat
424+```
413425
414-`REM Align the final APK package`\
415-`zipalign -v 4 bin\%APP_NAME%-unaligned.apk bin\%APP_NAME%.apk `\
426+To build the APK file. Also remember to edit this batch file to reflect your paths.
416427
417-`REM call and pause together allow us to see the results in the end`\
418-`pause`
428+This script contains the following:
429+```
430+REM Adjust these paths to yours
431+ SET PATH=C:\Programme\Android\android-sdk\tools;C:\Programme\Android\android-sdk\platform-tools\;C:\Programme\Java\jdk1.6.0_38\bin
432+ SET APP_NAME=androidlcltest
433+ SET ANDROID_HOME=C:\Programme\Android\android-sdk
434+ SET APK_SDK_PLATFORM=C:\Programme\Android\android-sdk\platforms\android-9
435+ SET APK_PROJECT_PATH=C:\lazarus\examples\androidlcl\android
436+
437+ REM Create necessary directory Structure
438+ mkdir bin
439+ mkdir bin\classes
440+ mkdir gen
441+ mkdir gen\com
442+ mkdir gen\com\pascal
443+ mkdir gen\com\pascal\lcltest
444+ mkdir raw
445+ mkdir raw\lib
446+ mkdir raw\lib\armeabi
447+
448+ REM Cleanup
449+ del bin\%APP_NAME%.ap_
450+ del bin\%APP_NAME%.apk
451+ del raw\lib\armeabi\*.so
452+
453+ REM More directory preparation
454+ copy libs\armeabi\*.so raw\lib\armeabi\
455+
456+ REM Resource compilation
457+ 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
458+
459+ REM Java compiler
460+ call javac -verbose -classpath %APK_SDK_PLATFORM%\android.jar -d bin\classes src\com\pascal\lcltest\LCLActivity.java
461+
462+ REM DX to convert the java bytecode to dalvik bytecode
463+ call dx --dex --verbose --output=%APK_PROJECT_PATH%\bin\classes.dex %APK_PROJECT_PATH%\bin\classes
464+
465+ REM It seams that dx calls echo off
466+ @echo on
467+ REM Now build the unsigned APK
468+ del %APK_PROJECT_PATH%\bin\%APP_NAME%-unsigned.apk
469+ 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
470+
471+ REM Generating on the fly a debug key
472+ rem keytool -genkey -v -keystore bin\LCLDebugKey.keystore -alias LCLDebugKey -keyalg RSA -validity 10000 -dname NAME -storepass senhas -keypass senhas
473+
474+ REM Signing the APK with a debug key
475+ del bin\%APP_NAME%-unaligned.apk
476+```
477+```
478+REM Change keypass and storepass pw here| and here|
479+ jarsigner -verbose -keystore bin\LCLDebugKey.keystore -keypass senhas -storepass senhas -signedjar bin\%APP_NAME%-unaligned.apk bin\%APP_NAME%-unsigned.apk LCLDebugKey
480+
481+ REM Align the final APK package
482+ zipalign -v 4 bin\%APP_NAME%-unaligned.apk bin\%APP_NAME%.apk
483+
484+ REM call and pause together allow us to see the results in the end
485+ pause
486+```
419487
420-Don't forget changing the set-variables in the top AND change the pw (see above where).
488+Don't forget changing the set-variables in the top AND change the pw (see above where).
421489
422490### Building an LCL Android application with debug info
423491
424-It 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:
492+It 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:
425493
426-![](/wiki-images/1/11/Android_project_options_4.png)
494+[![Android project options 4.png](/wiki-images/1/11/Android_project_options_4.png)](</File:Android_project_options_4.png>)
427495
428496## Oh no! My LCL Android application doesn't work
429497
430-There 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:
431-
432-``` bash
498+There 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:
499+```
433500./adb logcat
434501```
435502
436-And then test one of the hypotheses in the next subsections.
503+And then test one of the hypotheses in the next subsections.
437504
438505### The Pascal executable was compiled for a wrong architecture, operating system and/or widgetset
439506
440-This 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:
441-
442-[[How to build an LCL Android application]]
507+This 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:
443508
444-To check if you library is arm-linux or not, execute the following commands:
509+[How_to_build_an_LCL_Android_application](</index.php?title=How_to_build_an_LCL_Android_application&action=edit&redlink=1> "How to build an LCL Android application \(page does not exist\)")
445510
446-``` bash
511+To check if you library is arm-linux or not, execute the following commands:
512+```
447513cd libs/armeabi
448-ls -l
449-file liblclapp.so
450-ldd liblclapp.so
514+ ls -l
515+ file liblclapp.so
516+ ldd liblclapp.so
451517```
452518
453-If it mentions anything like 80386 or gtk, then your program was compiled for linux-x86 and gtk2, not for Android like it should.
519+If it mentions anything like 80386 or gtk, then your program was compiled for linux-x86 and gtk2, not for Android like it should.
454520
455521### My Pascal application crashed. How to get a stacktrace?
456522
457-If a Pascal application crashes you should use the command "adb logcat" to obtain the stack
523+If a Pascal application crashes you should use the command "adb logcat" to obtain the stack
458524
459-Read also this thread in the Google NDK group about converting addresses to lines: <http://groups.google.com/group/android-ndk/msg/2ed2286e85f4ccdd>?
525+Read also this thread in the Google NDK group about converting addresses to lines: <http://groups.google.com/group/android-ndk/msg/2ed2286e85f4ccdd>?
460526
461527### The indispensable build options
462528
463-- -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
464-- -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>
465-- -dAndroid in the package LCLBase.lpk
466-- -Parm -Tlinux for the process and target operating system
467-- -Fl should contain the path to the NDK directory with the target link shared object, such as libc.so, liblog.so, libjni.so, etc
529+ * -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
530+ * -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>
531+ * -dAndroid in the package LCLBase.lpk
532+ * -Parm -Tlinux for the process and target operating system
533+ * -Fl should contain the path to the NDK directory with the target link shared object, such as libc.so, liblog.so, libjni.so, etc
468534
469535### Wrong package name
470536
471-If 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:
472-
473- CDWidgetset.ActivityClassName := 'com/pascal/lcltest/LCLActivity';
474-
475-If your new package name is com.pascal.myapp, then you should change the command above to this:
537+If 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:
538+```
539+CDWidgetset.ActivityClassName := 'com/pascal/lcltest/LCLActivity';
540+```
476541
477- CDWidgetset.ActivityClassName := 'com/pascal/myapp/LCLActivity';
542+If your new package name is com.pascal.myapp, then you should change the command above to this:
543+```
544+CDWidgetset.ActivityClassName := 'com/pascal/myapp/LCLActivity';
545+```
478546
479547## Free Pascal Bugs on Android Support
480548
481-The following summarizes the state of Android Support in Free Pascal:
549+The following summarizes the state of Android Support in Free Pascal:
482550
483-- 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/>
484-- 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>
485-- In the end of 2011 this revision <http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&revision=19036> broke linking Android projects
551+ * 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/>
552+ * On February this revision [http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&revision=16981](<http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&revision=16981>) introduced this bug: <http://mantis.freepascal.org/view.php?id=18833>
553+ * In the end of 2011 this revision [http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&revision=19036](<http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&revision=19036>) broke linking Android projects
486554
487555We are in contact with FPC developers to fix the situation as can be seen in: <http://mantis.freepascal.org/view.php?id=20726>
488556
489557### FPC4Android Branches
490558
491-Because of FPC bugs related to Android support I have rolled my own branches.
559+Because of FPC bugs related to Android support I have rolled my own branches.
492560
493561#### FPC4Android 2.5.1
494562
495-FPC4Android 2.5.1 has the following fixes applied to it:
563+FPC4Android 2.5.1 has the following fixes applied to it:
496564
497565<http://bugs.freepascal.org/view.php?id=21208> <http://bugs.freepascal.org/view.php?id=21341> <http://bugs.freepascal.org/view.php?id=19559>
498566
499-And I have created a pre-compiled x86-linux -\> android-arm cross-compiler and hosted it here (it is the -v2 cross-compiler);
567+And I have created a pre-compiled x86-linux -> android-arm cross-compiler and hosted it here (it is the -v2 cross-compiler);
500568
501569<https://sourceforge.net/projects/p-tools/files/Free%20Pascal%20for%20ARM/>
502570
503-To download the source execute:
504-
505-`svn co `[`https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android`](https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android)` fpc4android`
571+To download the source execute:
572+```
573+svn co <https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android> fpc4android
574+```
506575
507576#### FPC4Android 2.6.1
508577
509-This branch is not finished, it lacks patches to fix Android support, patches are welcome. SVN link:
510-
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`
578+This branch is not finished, it lacks patches to fix Android support, patches are welcome. SVN link:
579+```
580+svn co <https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android_2_6> fpc4android_2_6
581+```
512582
513583## Android SDK and NDK bugs
514584
515585### Android NDK for Windows broken linker
516586
517-The 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.
587+The 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.
518588
519589See <http://groups.google.com/group/android-ndk/browse_thread/thread/d8c88bd58ad6df87>
520590
521591### Error while calling DX: Trouble processing: bad class file magic (cafebabe)
522592
523-If while using the build script you get the following errors:
524-
525- D:\djsystem\djpalm\android>call dx --dex --verbose --output=D:\djsystem\djpalm\a
593+If while using the build script you get the following errors:
594+```
595+D:\djsystem\djpalm\android>call dx --dex --verbose --output=D:\djsystem\djpalm\a
526596 ndroid\bin\classes.dex D:\djsystem\djpalm\android\bin\classes
527597 processing D:\djsystem\djpalm\android\bin\classes\.\com\pascal\djpalm\LCLActivit
528598 y$1.class...
529-
599+
530600 trouble processing:
531601 bad class file magic (cafebabe) or version (0033.0000)
532602 ...while parsing com/pascal/djpalm/LCLActivity$1.class
533603 ...while processing com/pascal/djpalm/LCLActivity$1.class
534604 processing D:\djsystem\djpalm\android\bin\classes\.\com\pascal\djpalm\LCLActivit
535605 y$2.class...
536-
606+
537607 trouble processing:
538608 bad class file magic (cafebabe) or version (0033.0000)
539609 ...while parsing com/pascal/djpalm/LCLActivity$2.class
540610 ...while processing com/pascal/djpalm/LCLActivity$2.class
541611 processing D:\djsystem\djpalm\android\bin\classes\.\com\pascal\djpalm\LCLActivit
542612 y$3.class...
613+```
543614
544-This 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:
615+This 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:
545616
546-- <http://stackoverflow.com/questions/8538891/bad-class-file-magic-when-using-dx-bat>
547-- <http://www.oracle.com/technetwork/java/javase/downloads/jdk6-downloads-1637591.html>
617+ * <http://stackoverflow.com/questions/8538891/bad-class-file-magic-when-using-dx-bat>
618+ * <http://www.oracle.com/technetwork/java/javase/downloads/jdk6-downloads-1637591.html>
548619
549620## Development Notes
550621
551622### The mysterious JNI Crash (SIGILL - illegal instruction)
552623
553624See the thread: <http://groups.google.com/group/android-ndk/browse_thread/thread/ba542483f062a828>
554625
555-The 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.
626+The 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.
556627
557-The 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.
628+The 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.
558629
559630### NDK Libraries available in Android 2.2 (API level 8)
560631
561-LCL-CustomDrawn targets Android 2.2+ and in this API level the following libraries are supported by the NDK:
632+LCL-CustomDrawn targets Android 2.2+ and in this API level the following libraries are supported by the NDK:
562633
563-1. libc.so
564-2. libdl.so (linker)
565-3. OpenGL ES 1
566-4. OpenGL ES 2
567-5. libjnigraphics.so
568-6. liblog.so
569-7. libm.so
570-8. libz.so
571-9. libthread_db.so
572-10. libstdc++.so
634+ 1. libc.so
635+ 2. libdl.so (linker)
636+ 3. OpenGL ES 1
637+ 4. OpenGL ES 2
638+ 5. libjnigraphics.so
639+ 6. liblog.so
640+ 7. libm.so
641+ 8. libz.so
642+ 9. libthread_db.so
643+ 10. libstdc++.so
573644
574-LCL-CustomDrawn-Android uses libjnigraphics.so and liblog.so at the moment.
645+LCL-CustomDrawn-Android uses libjnigraphics.so and liblog.so at the moment.
575646
576647### Native text drawing
577648
578-Native text drawing is a bit convoluted in Android and the documentation is quite bad too. Some gotchas already found:
649+Native text drawing is a bit convoluted in Android and the documentation is quite bad too. Some gotchas already found:
579650
580-- 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>
581-- 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.
651+ * 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>
652+ * 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.
582653
583-But there are also good things about it:
654+But there are also good things about it:
584655
585-- It can draw on a transparent bitmap and use alpha transparency to implement anti-aliasing and subpixel rendering. The text gets quite beaultiful.
586-- It can draw on the ARGB 32-bits non-premultiplied format which is a pretty good one
656+ * It can draw on a transparent bitmap and use alpha transparency to implement anti-aliasing and subpixel rendering. The text gets quite beaultiful.
657+ * It can draw on the ARGB 32-bits non-premultiplied format which is a pretty good one
587658
588659### Flood of garbage collector messages when the caret is visible
589660
590-Something like this:
591-
592- D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 188 objects / 6664 bytes in 94ms
661+Something like this:
662+```
663+D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 188 objects / 6664 bytes in 94ms
593664 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 170 objects / 6160 bytes in 78ms
594665 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5904 bytes in 82ms
595666 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5856 bytes in 78ms
596667 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5872 bytes in 80ms
597668 D/dalvikvm( 2825): GC_EXPLICIT freed 371 objects / 18480 bytes in 91ms
598669 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5896 bytes in 78ms
599670 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5896 bytes in 78ms
600671 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5896 bytes in 81ms
601672 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5920 bytes in 78ms
602673 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5920 bytes in 83ms
674+```
603675
604-In 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.
676+In 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.
605677
606678### Why the caret of a TEdit keeps blinking after clicking on the form
607679
608-When 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.
680+When 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.
609681
610682### Android ComboBox
611683
612-For adding Android combobox support a new method was added to LCLIntf along with a global variable to store the callback of this dialog:
613-
614-``` pascal
684+For adding Android combobox support a new method was added to LCLIntf along with a global variable to store the callback of this dialog:
685+```
615686var
616- OnShowSelectItemDialogResult: TOnShowSelectItemDialogResult;
617-
618-function ShowSelectItemDialog(const AItems: TStrings): Boolean; override;
687+ OnShowSelectItemDialogResult: TOnShowSelectItemDialogResult;
688+
689+ function ShowSelectItemDialog(const AItems: TStrings): Boolean; override;
619690```
620691
621-This method will run a native item selection dialog, if the platform has one, or result false without doing anything otherwise.
692+This method will run a native item selection dialog, if the platform has one, or result false without doing anything otherwise.
622693
623-![](/wiki-images/8/82/Android_combobox.png)
694+[![Android combobox.png](/wiki-images/8/82/Android_combobox.png)](</File:Android_combobox.png>)
624695
625696### Using the Native ListView Dialog
626697
627-To allow the user to select items from a list more easily we offer a routine which launch dialog with the native ListView.
628-
629-``` pascal
630-{$ifdef LCLCustomDrawn}
631-uses customdrawnint, lclintf;
632-{$endif}
633-
634-procedure TForm2.Button3Click(Sender: TObject);
635-begin
698+To allow the user to select items from a list more easily we offer a routine which launch dialog with the native ListView.
699+```
636700{$ifdef LCLCustomDrawn}
637- LCLIntf.OnListViewDialogResult := @MyOnListViewDialogResult;
638- CDWidgetSet.ShowListViewDialog('Dialog Title',
639- ['Title1', 'Title2', 'Title3', 'Title4', 'Title5', 'Title6'],
640- ['Descr1', 'Descr2', 'Descr3', 'Descr4', 'Descr5', 'Descr6']);
641-{$endif}
642-end;
643-
644-procedure TForm2.MyOnListViewDialogResult(ASelectedItem: Integer);
645-begin
646- DebugLn(Format('[MyOnListViewDialogResult] ASelectedItem=%d', [ASelectedItem]));
647-end;
701+ uses customdrawnint, lclintf;
702+ {$endif}
703+
704+ procedure TForm2.Button3Click(Sender: TObject);
705+ begin
706+ {$ifdef LCLCustomDrawn}
707+ LCLIntf.OnListViewDialogResult := @MyOnListViewDialogResult;
708+ CDWidgetSet.ShowListViewDialog('Dialog Title',
709+ ['Title1', 'Title2', 'Title3', 'Title4', 'Title5', 'Title6'],
710+ ['Descr1', 'Descr2', 'Descr3', 'Descr4', 'Descr5', 'Descr6']);
711+ {$endif}
712+ end;
713+
714+ procedure TForm2.MyOnListViewDialogResult(ASelectedItem: Integer);
715+ begin
716+ DebugLn(Format('[MyOnListViewDialogResult] ASelectedItem=%d', [ASelectedItem]));
717+ end;
648718```
649719
650-LCLIntf.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.
651-
652-Note 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!
720+LCLIntf.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.
653721
654-``` pascal
722+Note 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!
723+```
655724procedure TCDWidgetSet.ShowListViewDialog(ATitle: string; ATitles,
656- ADescriptions: array of string;
657- AColorOddRow: jint = $ff292C29; AColorEvenRow: jint = $ff424542);
725+ ADescriptions: array of string;
726+ AColorOddRow: jint = $ff292C29; AColorEvenRow: jint = $ff424542);
658727```
659728
660-![](/wiki-images/2/2c/Android_ListView.png)
729+[![Android ListView.png](/wiki-images/2/2c/Android_ListView.png)](</File:Android_ListView.png>)
661730
662731### LazDeviceAPIs
663732
664733See: [[LazDeviceAPIs]]
665734
666735---
667-*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).*
668-Category: Android
669-Category: Custom Drawn
736+*From the Free Pascal wiki, page "Custom Drawn Interface/Android", as the Internet Archive kept it on 2023-01-28. 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).*

Back to history