Sign in Join
Wiki copytemporary

Custom Drawn Interface/Android/ja: what changed

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

OldNewLine
11Go back to [[Custom Drawn Interface]]\
22
33※今のところ、Windows上でAndroidプログラミングを実際にできるようにすることを優先目標として記述しています。そのため、原文の翻訳となっていないところが多いです。間違い等はどんどん修正していただけると幸いです。(2014-01-26 by malcome)\
44
55## Architecture
66
77LCL-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.
88
99Our 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]].
1010
1111## Roadmap
1212
1313Part 1, until March 2012:
1414
15151. Build the set of [[Lazarus Custom Drawn Controls]]
16162. Initial bindings for the Android APIs
17173. Create an application to automatically generate the bindings
18184. Start the new widgetset
19195. Implement support for JNI
20206. Merge the Lazarus Custom Drawn Controls into the LCL and use them to implement all basic controls
21217. Add text support for Android
22228. Implement basic window client area scrolling
23239. Add mobile emulator for desktop platforms
242410. Improve the mobile scrolling
252511. Add text support in X11
262612. Add DPI awareness and adaptation in the LCL
272713. Add non-native text support via pasfreetype
2828
2929Part 2: April, May, June 2012:
3030
31311. TButton improve the Android visual
32322. TBitBtn
33333. TRadioButton finish the native look
34344. 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
35355. MaskEdit
36366. Improve TComboBox
37377. TMemo
38388. TListView as a list with columns
39399. TMainMenu
404010. Database with sqlite
414111. Barcode reading
424212. Windows add-on installer
4343
4444## Using the Android SDK, Emulator and Phones
4545
4646[[Custom Drawn Interface/Using the Android SDK, Emulator and Phones]]
4747
4848## Android Programming
4949
5050See [[Android Programming]], also includes caracteristics of the various phones relevant for programming.
5151
5252## Configuring the Free Pascal Compiler for Android
5353
5454### Use the ready Virtual Box Image with FPC and Lazarus
5555
5656The 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.
5757
5858The 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.
5959
6060The 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”.
6161
6262Note 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.
6363
6464### Windows 上で Lazarus を用いて Android アプリを開発するための準備
6565
6666**Step 1** - Android SDK の準備
6767
6868<http://developer.android.com/sdk/index.html> から Windows 用 Android SDK の zip ファイルをダウンロードし、適当なフォルダ(以下ではc:\work\android\sdkと仮定)に解凍します。\
69692015-12-07追記: 上記ウェブサイトの、「Other Download Options」「SDK Tools Only」セクションにある、android-sdk_r24.4.1-windows.zip で動作することを確認しました。\
7070
7171**Step 2** - Android NDK の準備
7272
7373<http://developer.android.com/ndk/downloads/index.html> から Windows 用 Android NDK をダウンロードし、適当なフォルダ(以下ではc:\work\android\ndkと仮定)に解凍します。\
74742015-12-07追記: android-ndk-r10e-windows-x86.exe にて動作確認しました。\
7575
7676**Step 3** - Android JDK の準備
7777
7878作成予定のプログラムで JAVAのライブラリを使用しない場合でも、apk ファイルの作成のために JDK に含まれるツールを使用します。したがって、JDK をインストールする必要があります。\
7979<http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html> から Windows 用 JDK の exe ファイルをダウンロードしてインストールしてください。(以下ではC:\Program Files\Java\jdk1.7.0_51 にインストールしたと仮定します)\
80802014-01-25 動作確認: jdk-7u51-windows-i586.exe\
8181
8282**Step 4** - Apatch Ant の準備
8383
8484原文では Windows で Apatch Ant を使用せずに apk ファイルを作成できることを紹介していますが、Apatch Ant を使用した方が楽ですしネット上の情報も多いです。\
8585<http://ant.apache.org/bindownload.cgi> から Apache Ant をダウンロードし(2015-12-03追記:apache-ant-1.9.6-bin.zipで動作確認しました)、適当なフォルダ(以下ではc:\work\tools\antと仮定)に展開してください。\
8686Apatch Ant による apk ファイルの作成方法:\
8787アプリケーション固有の build.xml があるフォルダ内に次のような buildapk.bat を作成して、コマンドプロンプトから「buildapk debug」などとしてバッチを実行することで apk ファイルが作成できます。
8888
8989 REM Adjust the path to yours path
9090 set ANT_HOME=C:\work\tools\ant
9191 set JAVA_HOME=C:\Program Files\Java\jdk1.7.0_51
9292
9393 set Path=%JAVA_HOME%\bin
9494
9595 %ANT_HOME%\bin\ant %1 %2 %3 %4 %5 %6 %7 %8 %9
9696
9797**Step 5** - Lazarus の準備
9898
9999通常は最新の安定版をダウンロードしてインストールすれば十分です。(以下では、c:\lazarus にインストールされたものと仮定する)\
100100
101101**Step 6** - FPC 3.0.0 の準備
102102
103103<ftp://wiki.freepascal.org/pub/fpc/dist/3.0.0/source/> から、fpc-3.0.0.source.zip をダウンロードして適当なフォルダ(以下では c:\work\fpcsrc と仮定)に展開します。\
104104次に、c:\work\fpcsrc\buildfpc.bat を次の内容で作成します。\
105105各PATH は環境に合わせて設定しなおしてください。なお、ここでは ARMv6 を最低現の対象機種としています。 また、FPCのバージョン部分は適切に修正してください。下記ではLazarus 1.4.4 に付属しているFPC2.6.4を使用してFPC3.0.0をビルドしています。 なお、Lazarus にすでに FPC 3.0.0 をインストール済みの場合は、クロスコンパイラだけビルドすればよいので、バッチ内の「Build FPC」、「Create fpc.cfg」という部分は不要です。
106106
107107 REM Adjust the path to yours path
108108 SET LAZ_PATH=C:\lazarus
109109 SET NDK_PATH=C:\work\android\ndk\toolchains\arm-linux-androideabi-4.8\prebuilt\windows\bin
110110
111111 Set Path=%NDK_PATH%;%LAZ_PATH%\fpc\2.6.4\bin\i386-win32
112112
113113 REM =============== Build FPC
114114 make all
115115 make install INSTALL_PREFIX=%LAZ_PATH%\fpc\3.0.0
116116
117117 REM =============== Build cross compiler
118118 make clean crossall crossinstall OS_TARGET=android CPU_TARGET=arm CROSSOPT="-OoFASTMATH -CpARMV6" INSTALL_PREFIX=%LAZ_PATH%\fpc\3.0.0
119119
120120 REM =============== Create fpc.cfg
121121 %LAZ_PATH%\fpc\3.0.0\bin\i386-win32\fpcmkcfg.exe -d basepath=%LAZ_PATH%\fpc\3.0.0 -o %LAZ_PATH%\fpc\3.0.0\bin\i386-win32\fpc.cfg
122122
123123次に、コマンドプロンプトを起動し、下記のコマンドを入力します。
124124
125125 cd c:\work\fpcsrc
126126 bildfpc
127127
128128これで FPC の準備ができました。\
129129
130130**Step 7** - cross-binutils のコピー
131131
132132C:\work\Android\ndk\toolchains\arm-linux-androideabi-4.8\prebuilt\windows\bin フォルダ内のすべてのファイル(おそらくすべて arm-linux-androideabi-*.exe という名前)を、C:\lazarus\fpc\3.0.0\bin\i386-win32 フォルダにコピーします。\
133133
134134**Step 8** - Lazarus の設定
135135
136136Lazarus を起動し、Tools-\>Options の、Environment-\>Files の、Compiler executable の 2.6.4 という部分を 3.0.0 に変更します。\
137137例) 「C:\lazarus\fpc\2.6.4\bin\i386-win32\fpc.exe」を、「C:\lazarus\fpc\3.0.0\bin\i386-win32\fpc.exe」に変更。\
138138
139139・・・この後は、新規プロジェクトでLinuxライブラリ(.so)を作成し各種設定をしますが、Android プログラミングの知識がやや必要になります。・・・\
140140
141141Project-\>Project Options の、Compiler Options-\>Paths の、Libraries に\
142142C:\work\Android\ndk\platforms\android-9\arch-arm\usr\lib\\\
143143を追加する。(andoroid-9 の数字の部分は minimum API レベルにより変わる)\
144144
145145Project-\>Project Options の、Compiler Options-\>Other の、Custom options に\
146146-OoFASTMATH\
147147などを追加する。なお、古いサンプルソースなんかですと「-dANDROID」というオプションが追加されていることがありますが現在は不要のようです。\
148148
149149Project-\>Project Options の、Compiler Options-\>Config and Target の、 Target OS を Android に、Taget CPU を arm に、Target processor を ARMV6などに設定する。\
150150
151151さらに、Android SDK に付属する SDK Manager.exe を用いて、使用するAPI(例:Android 2.3.3(API10))を導入するなどの作業も必要です。\
152152
153153・・・ここまですれば [[Android Programming/ja|Android_Programming]] で紹介されている NDK_OpenGL_example はコンパイルできましたし、完成した apk を実機にインストールして見事に動作させることができました。しかし、今のところ、下記の androidlcltest.lpi は、「・・・fpc\2.7.1\bin\i386-win32\arm-linux-androideabi-ld.bfd.exe: BFD (GNU Binutils) 2.23.2 assertion fail /s/ndk-toolchain/src/build/../binutils/binutils-2.23/bfd/elf32-arm.c:12336」というエラーが出てコンパイルできませんでした。個人的には NDK で OpenGL が使えれば十分なので、Custom Drawn についての調査は時間がかかるかもしれません。識者の情報をお待ちします。\
154154
155155Now you can already build the example project androidlcltest.lpi using the Windows-Release build mode
156156
157157### Building the compiler yourself in Linux
158158
159159See [[Setup Cross Compile For ARM]] and make sure to use the option OPT="-dFPC_ARMEL" for building the compiler.
160160
161161### Using the pre-compiled compiler in Linux
162162
163163A pre-compiled compiler is provided for convenience for users. The following steps were tested in Mandriva Linux 2010.0 and 2010.1:
164164
165165**Required Environment**
166166
167167- The latest stable FPC installed in the system via the RPM / DEB / TAR package
168168
169169**Step 1** - Install the cross-binutils
170170
171171For 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>
172172
173173Just download the RPM package and install it using:
174174
175-`rpm -ivh cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm `
175+```text
176+rpm -ivh cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm
177+```
176178
177179In 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:
178180
179-`rpm -ivh --nodeps cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm `
181+```text
182+rpm -ivh --nodeps cross-arm-binutils-2.20.51.0.4-2mnb2.i586.rpm
183+```
180184
181185For other distributions use the corresponding package, or else read the instructions for building the cross-binutils yourself at [[Setup Cross Compile For ARM]]
182186
183187**Step 2** - Configure the cross-binutils
184188
185189The 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:
186190
187-`su`\
188-`mv /usr/bin/arm-linux-as /usr/bin/arm-linux-as_org`\
189-`gedit /usr/bin/arm-linux-as`
191+```text
192+su
193+mv /usr/bin/arm-linux-as /usr/bin/arm-linux-as_org
194+gedit /usr/bin/arm-linux-as
195+```
190196
191197Now paste into the editor this code:
192198
193-`#!/bin/sh`\
194-`/usr/bin/arm-linux-as_org -meabi=5 $@`
199+```text
200+#!/bin/sh
201+/usr/bin/arm-linux-as_org -meabi=5 $@
202+```
195203
196204And don't forget to then make it executable:
197205
198-`chmod 755 /usr/bin/arm-linux-as`
206+```text
207+chmod 755 /usr/bin/arm-linux-as
208+```
199209
200210**Step 3** - Install the Free Pascal Cross-Compiler
201211
202212At this point the pre-compiled FPC can be download from here: <http://sourceforge.net/projects/p-tools/files/Free%20Pascal%20for%20ARM/>
203213
204214Then use these commands to install the pre-compiled Free Pascal cross-compiler into /usr:
205215
206-`[felipe@localhost Programas]$ ls -l`\
207-`total 20664`\
208-`-rw-rw-r--  1 felipe felipe 17098552 2010-10-25 08:17 fpc-2.5.1.arm-linux.tar.gz`\
209-`[felipe@localhost Programas]$ su`\
210-`Password: `\
211-`[root@localhost Programas]# cp fpc-2.5.1.arm-linux.tar.gz /usr/`\
212-`[root@localhost Programas]# cd /usr/`\
213-`[root@localhost usr]# tar -xvf fpc-2.5.1.arm-linux.tar.gz `\
214-`[root@localhost usr]# ln -s /usr/lib/fpc/2.5.1/ppcrossarm /usr/bin/ppcrossarm`
216+```text
217+[felipe@localhost Programas]$ ls -l
218+total 20664
219+-rw-rw-r-- 1 felipe felipe 17098552 2010-10-25 08:17 fpc-2.5.1.arm-linux.tar.gz
220+[felipe@localhost Programas]$ su
221+Password:
222+[root@localhost Programas]# cp fpc-2.5.1.arm-linux.tar.gz /usr/
223+[root@localhost Programas]# cd /usr/
224+[root@localhost usr]# tar -xvf fpc-2.5.1.arm-linux.tar.gz
225+[root@localhost usr]# ln -s /usr/lib/fpc/2.5.1/ppcrossarm /usr/bin/ppcrossarm
226+```
215227
216228**Step 4** - Verify if your Cross-Compiler works
217229
218230If you made no errors in the previous steps, it should work, so try to call it like this:
219231
220-`[felipe@localhost Programas]$ /usr/bin/ppcrossarm`
232+```text
233+[felipe@localhost Programas]$ /usr/bin/ppcrossarm
234+```
221235
222236If 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:
223237
224238\[felipe@localhost Programas\]\$ ls -ls /usr/bin/ppc*
225239
226240Now 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.
227241
228242## Compiling the example LCL Android Application
229243
230244**Step 1 - Download the source code**
231245
232246The source code of the example is located inside the Lazarus sources in lazarus/examples/androidlcl/androidlcltest.lpi
233247
234248**Step 2 - Make sure you have the Java JDK and the Android SDK and NDK installed**
235249
236250Read here: [[Custom Drawn Interface/Android|Custom_Drawn_Interface/Android#Install_the_Java_JDK_and_the_Android_SDK_and_NDK]]
237251
238252**Step 3 - Build the project using the Lazarus IDE**
239253
240254Configuring 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"
241255
242256But 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:
243257
244258![](/wiki-images/b/b0/Configure_androidlcl_libraries.jpg)
245259
246260The 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.
247261
248262**Step 4 - Build the APK**
249263
250264If 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]]
251265
252266If 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:
253267
254268 # This file is automatically generated by Android Tools.
255269 # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
256270 #
257271 # This file must *NOT* be checked in Version Control Systems,
258272 # as it contains information specific to your local configuration.
259273
260274 # location of the SDK. This is only used by Ant
261275 # For customization when using a Version Control System, please read the
262276 # header note.
263277 sdk.dir=/home/felipe/Programas/android-sdk-linux
264278
265279After configuring that one, go to the command line and issue these commands:
266280
267-` cd lazarus/examples/androidlcl/android`\
268-` ant debug`
281+```text
282+ cd lazarus/examples/androidlcl/android
283+ ant debug
284+```
269285
270286The APK will be located in lazarus/examples/androidlcl/android/bin
271287
272288**Step 5 - Install the APK in your phone and run it**
273289
274290You can install via ADB or by copying the file to the sdcard. You should see this:
275291
276292![](/wiki-images/4/4c/Lcl_android_30_mar.png)
277293
278294## How to create an LCL Android Application
279295
280296To 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
281297
282298Then you will need to modify the build files to change them to your new project name and your new Java package name.
283299
284300### Step 1 - Creating the LPI
285301
286302You 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
287303
288304You need to adapt the exported JNI method names to your Android Package Name.
289305
290306### Step 2 - Building the library
291307
292308First 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:
293309
294310![](/wiki-images/6/64/Android_project_options_1.png)
295311
296312![](/wiki-images/f/f7/Android_project_options_2.png)
297313
298314![](/wiki-images/9/9f/Android_project_options_3.png)
299315
300316### Step 3 - Create the Android project structure
301317
302318Besides 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.
303319
304320### Step 4 - Creating the APK package
305321
306322#### Step 4 - Creating the APK package in Linux
307323
308324To 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
309325
310-`cd myproject/android ant debug`
326+```text
327+cd myproject/android
328+ant debug
329+```
311330
312331Ant and all dependencies must be installed using the package management of your linux distribution.
313332
314333#### Step 4 - Creating the APK package in Windows
315334
316335**Pre-requisites**:
317336
318337- Java JDK installed: <http://www.oracle.com/technetwork/java/javase/downloads/index.html>
319338- Android SDK Installed
320339
321340**Instructions**:
322341
323342In Windows we provide a APK build system which uses only the tools provided in the Android SDK and therefore does not require ANT.
324343
325344First it is necessary to create a debug key to use. To do this use this script:
326345
327-`lazarus/examples/androidlcl/android/generate_debug_key.bat`
346+```text
347+lazarus/examples/androidlcl/android/generate_debug_key.bat
348+```
328349
329350which can be copied from the example application to your own project folder.
330351
331352it contains following:
332353
333-`REM Adjust these paths to yours`\
334-`SET PATH=C:\Programme\Android\android-sdk\tools;C:\Programme\Android\android-sdk\platform-tools\;C:\Programme\Java\jdk1.6.0_38\bin`\
335-`SET APP_NAME=androidlcltest`\
336-`SET ANDROID_HOME=C:\Programme\Android\android-sdk`\
337-`SET APK_SDK_PLATFORM=C:\Programme\Android\android-sdk\platforms\android-9`\
338-`SET APK_PROJECT_PATH=C:\Programme\lazarus\examples\androidlcl\android`\
354+``` pascal
355+REM Adjust these paths to yours
356+SET PATH=C:\Programme\Android\android-sdk\tools;C:\Programme\Android\android-sdk\platform-tools\;C:\Programme\Java\jdk1.6.0_38\bin
357+SET APP_NAME=androidlcltest
358+SET ANDROID_HOME=C:\Programme\Android\android-sdk
359+SET APK_SDK_PLATFORM=C:\Programme\Android\android-sdk\platforms\android-9
360+SET APK_PROJECT_PATH=C:\Programme\lazarus\examples\androidlcl\android
339361
340-`mkdir bin`\
362+mkdir bin
341363
342-`keytool --help`\
364+keytool --help
343365
344-`keytool -genkey -v -keystore bin\LCLDebugKey.keystore -alias LCLDebugKey -keyalg RSA -validity 10000`\
366+keytool -genkey -v -keystore bin\LCLDebugKey.keystore -alias LCLDebugKey -keyalg RSA -validity 10000
345367
346-`REM call and pause together allow us to see the results in the end`\
347-`pause`\
368+REM call and pause together allow us to see the results in the end
369+pause
370+```
348371
349372You have to fix everything after SET to your own paths. Don't forget adjusting the android version from APK_SDK_PLATFORM!
350373
351374After generating the key, use the other script:
352375
353-`lazarus/examples/androidlcl/android/build_debug_apk.bat`
376+```text
377+lazarus/examples/androidlcl/android/build_debug_apk.bat
378+```
354379
355380To build the APK file. Also remember to edit this batch file to reflect your paths.
356381
357382This script contains the following:
358383
359-`REM Adjust these paths to yours`\
360-`SET PATH=C:\Programme\Android\android-sdk\tools;C:\Programme\Android\android-sdk\platform-tools\;C:\Programme\Java\jdk1.6.0_38\bin`\
361-`SET APP_NAME=androidlcltest`\
362-`SET ANDROID_HOME=C:\Programme\Android\android-sdk`\
363-`SET APK_SDK_PLATFORM=C:\Programme\Android\android-sdk\platforms\android-9`\
364-`SET APK_PROJECT_PATH=C:\lazarus\examples\androidlcl\android `\
384+```text
385+REM Adjust these paths to yours
386+SET PATH=C:\Programme\Android\android-sdk\tools;C:\Programme\Android\android-sdk\platform-tools\;C:\Programme\Java\jdk1.6.0_38\bin
387+SET APP_NAME=androidlcltest
388+SET ANDROID_HOME=C:\Programme\Android\android-sdk
389+SET APK_SDK_PLATFORM=C:\Programme\Android\android-sdk\platforms\android-9
390+SET APK_PROJECT_PATH=C:\lazarus\examples\androidlcl\android
365391
366-`REM Create necessary directory Structure`\
367-`mkdir bin`\
368-`mkdir bin\classes`\
369-`mkdir gen`\
370-`mkdir gen\com`\
371-`mkdir gen\com\pascal`\
372-`mkdir gen\com\pascal\lcltest`\
373-`mkdir raw`\
374-`mkdir raw\lib`\
375-`mkdir raw\lib\armeabi`\
392+REM Create necessary directory Structure
393+mkdir bin
394+mkdir bin\classes
395+mkdir gen
396+mkdir gen\com
397+mkdir gen\com\pascal
398+mkdir gen\com\pascal\lcltest
399+mkdir raw
400+mkdir raw\lib
401+mkdir raw\lib\armeabi
376402
377-`REM Cleanup`\
378-`del bin\%APP_NAME%.ap_`\
379-`del bin\%APP_NAME%.apk`\
380-`del raw\lib\armeabi*.so`\
403+REM Cleanup
404+del bin\%APP_NAME%.ap_
405+del bin\%APP_NAME%.apk
406+del raw\lib\armeabi*.so
381407
382-`REM More directory preparation`\
383-`copy libs\armeabi*.so raw\lib\armeabi\ `\
408+REM More directory preparation
409+copy libs\armeabi*.so raw\lib\armeabi\
384410
385-`REM Resource compilation`\
386-`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`\
411+REM Resource compilation
412+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
387413
388-`REM Java compiler`\
389-`call javac -verbose -classpath %APK_SDK_PLATFORM%\android.jar -d bin\classes src\com\pascal\lcltest\LCLActivity.java`\
414+REM Java compiler
415+call javac -verbose -classpath %APK_SDK_PLATFORM%\android.jar -d bin\classes src\com\pascal\lcltest\LCLActivity.java
390416
391-`REM DX to convert the java bytecode to dalvik bytecode`\
392-`call dx --dex --verbose --output=%APK_PROJECT_PATH%\bin\classes.dex %APK_PROJECT_PATH%\bin\classes `\
417+REM DX to convert the java bytecode to dalvik bytecode
418+call dx --dex --verbose --output=%APK_PROJECT_PATH%\bin\classes.dex %APK_PROJECT_PATH%\bin\classes
393419
394-`REM It seams that dx calls echo off`\
395-`@echo on`\
396-`REM Now build the unsigned APK`\
397-`del %APK_PROJECT_PATH%\bin\%APP_NAME%-unsigned.apk`\
398-`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`\
420+REM It seams that dx calls echo off
421+@echo on
422+REM Now build the unsigned APK
423+del %APK_PROJECT_PATH%\bin\%APP_NAME%-unsigned.apk
424+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
399425
400-`REM Generating on the fly a debug key`\
401-`rem keytool -genkey -v -keystore bin\LCLDebugKey.keystore -alias LCLDebugKey -keyalg RSA -validity 10000 -dname NAME -storepass senhas  -keypass senhas`\
426+REM Generating on the fly a debug key
427+rem keytool -genkey -v -keystore bin\LCLDebugKey.keystore -alias LCLDebugKey -keyalg RSA -validity 10000 -dname NAME -storepass senhas -keypass senhas
402428
403-`REM Signing the APK with a debug key`\
404-`del bin\%APP_NAME%-unaligned.apk`
429+REM Signing the APK with a debug key
430+del bin\%APP_NAME%-unaligned.apk
431+```
405432
406-`REM Change keypass and storepass pw                        here|         and here|`\
407-`jarsigner -verbose -keystore bin\LCLDebugKey.keystore -keypass senhas -storepass senhas -signedjar bin\%APP_NAME%-unaligned.apk  bin\%APP_NAME%-unsigned.apk LCLDebugKey`\
433+``` pascal
434+REM Change keypass and storepass pw here| and here|
435+jarsigner -verbose -keystore bin\LCLDebugKey.keystore -keypass senhas -storepass senhas -signedjar bin\%APP_NAME%-unaligned.apk bin\%APP_NAME%-unsigned.apk LCLDebugKey
408436
409-`REM Align the final APK package`\
410-`zipalign -v 4 bin\%APP_NAME%-unaligned.apk bin\%APP_NAME%.apk `\
437+REM Align the final APK package
438+zipalign -v 4 bin\%APP_NAME%-unaligned.apk bin\%APP_NAME%.apk
411439
412-`REM call and pause together allow us to see the results in the end`\
413-`pause`
440+REM call and pause together allow us to see the results in the end
441+pause
442+```
414443
415444Don't forget changing the set-variables in the top AND change the pw (see above where).
416445
417446### Building an LCL Android application with debug info
418447
419448It 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:
420449
421450![](/wiki-images/1/11/Android_project_options_4.png)
422451
423452## Oh no! My LCL Android application doesn't work
424453
425454There 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:
426455
427456``` bash
428457./adb logcat
429458```
430459
431460And then test one of the hypotheses in the next subsections.
432461
433462### The Pascal executable was compiled for a wrong architecture, operating system and/or widgetset
434463
435464This 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:
436465
437466[[How to build an LCL Android application]]
438467
439468To check if you library is arm-linux or not, execute the following commands:
440469
441470``` bash
442471cd libs/armeabi
443472ls -l
444473file liblclapp.so
445474ldd liblclapp.so
446475```
447476
448477If it mentions anything like 80386 or gtk, then your program was compiled for linux-x86 and gtk2, not for Android like it should.
449478
450479### My Pascal application crashed. How to get a stacktrace?
451480
452481If a Pascal application crashes you should use the command "adb logcat" to obtain the stack
453482
454483Read also this thread in the Google NDK group about converting addresses to lines: <http://groups.google.com/group/android-ndk/msg/2ed2286e85f4ccdd>?
455484
456485### The indispensable build options
457486
458487- -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
459488- -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>
460489- -dAndroid in the package LCLBase.lpk
461490- -Parm -Tlinux for the process and target operating system
462491- -Fl should contain the path to the NDK directory with the target link shared object, such as libc.so, liblog.so, libjni.so, etc
463492
464493### Wrong package name
465494
466495If 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:
467496
468497 CDWidgetset.ActivityClassName := 'com/pascal/lcltest/LCLActivity';
469498
470499If your new package name is com.pascal.myapp, then you should change the command above to this:
471500
472501 CDWidgetset.ActivityClassName := 'com/pascal/myapp/LCLActivity';
473502
474503## Free Pascal Bugs on Android Support
475504
476505The following summarizes the state of Android Support in Free Pascal:
477506
478507- 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/>
479508- 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>
480509- In the end of 2011 this revision <http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&revision=19036> broke linking Android projects
481510
482511We are in contact with FPC developers to fix the situation as can be seen in: <http://mantis.freepascal.org/view.php?id=20726>
483512
484513### FPC4Android Branches
485514
486515Because of FPC bugs related to Android support I have rolled my own branches.
487516
488517#### FPC4Android 2.5.1
489518
490519FPC4Android 2.5.1 has the following fixes applied to it:
491520
492521<http://bugs.freepascal.org/view.php?id=21208> <http://bugs.freepascal.org/view.php?id=21341> <http://bugs.freepascal.org/view.php?id=19559>
493522
494523And I have created a pre-compiled x86-linux -\> android-arm cross-compiler and hosted it here (it is the -v2 cross-compiler);
495524
496525<https://sourceforge.net/projects/p-tools/files/Free%20Pascal%20for%20ARM/>
497526
498527To download the source execute:
499528
500-`svn co `[`https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android`](https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android)` fpc4android`
529+```text
530+svn co https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android fpc4android
531+```
501532
502533#### FPC4Android 2.6.1
503534
504535This branch is not finished, it lacks patches to fix Android support, patches are welcome. SVN link:
505536
506-`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`
537+```text
538+svn co https://p-tools.svn.sourceforge.net/svnroot/p-tools/fpc4android_2_6 fpc4android_2_6
539+```
507540
508541## Android SDK and NDK bugs
509542
510543### Android NDK for Windows broken linker
511544
512545The 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.
513546
514547See <http://groups.google.com/group/android-ndk/browse_thread/thread/d8c88bd58ad6df87>
515548
516549### Error while calling DX: Trouble processing: bad class file magic (cafebabe)
517550
518551If while using the build script you get the following errors:
519552
520553 D:\djsystem\djpalm\android>call dx --dex --verbose --output=D:\djsystem\djpalm\a
521554 ndroid\bin\classes.dex D:\djsystem\djpalm\android\bin\classes
522555 processing D:\djsystem\djpalm\android\bin\classes\.\com\pascal\djpalm\LCLActivit
523556 y$1.class...
524557
525558 trouble processing:
526559 bad class file magic (cafebabe) or version (0033.0000)
527560 ...while parsing com/pascal/djpalm/LCLActivity$1.class
528561 ...while processing com/pascal/djpalm/LCLActivity$1.class
529562 processing D:\djsystem\djpalm\android\bin\classes\.\com\pascal\djpalm\LCLActivit
530563 y$2.class...
531564
532565 trouble processing:
533566 bad class file magic (cafebabe) or version (0033.0000)
534567 ...while parsing com/pascal/djpalm/LCLActivity$2.class
535568 ...while processing com/pascal/djpalm/LCLActivity$2.class
536569 processing D:\djsystem\djpalm\android\bin\classes\.\com\pascal\djpalm\LCLActivit
537570 y$3.class...
538571
539572This 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:
540573
541574- <http://stackoverflow.com/questions/8538891/bad-class-file-magic-when-using-dx-bat>
542575- <http://www.oracle.com/technetwork/java/javase/downloads/jdk6-downloads-1637591.html>
543576
544577## Development Notes
545578
546579### The mysterious JNI Crash
547580
548581See the thread: <http://groups.google.com/group/android-ndk/browse_thread/thread/ba542483f062a828>
549582
550583The 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.
551584
552585The answer was that one needs to specify -CpARMV6 when building because older instructions might fail in some devices
553586
554587### NDK Libraries available in Android 2.2 (API level 8)
555588
556589LCL-CustomDrawn targets Android 2.2+ and in this API level the following libraries are supported by the NDK:
557590
5585911. libc.so
5595922. libdl.so (linker)
5605933. OpenGL ES 1
5615944. OpenGL ES 2
5625955. libjnigraphics.so
5635966. liblog.so
5645977. libm.so
5655988. libz.so
5665999. libthread_db.so
56760010. libstdc++.so
568601
569602LCL-CustomDrawn-Android uses libjnigraphics.so and liblog.so at the moment.
570603
571604### Native text drawing
572605
573606Native text drawing is a bit convoluted in Android and the documentation is quite bad too. Some gotchas already found:
574607
575608- 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>
576609- 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.
577610
578611But there are also good things about it:
579612
580613- It can draw on a transparent bitmap and use alpha transparency to implement anti-aliasing and subpixel rendering. The text gets quite beaultiful.
581614- It can draw on the ARGB 32-bits non-premultiplied format which is a pretty good one
582615
583616### Flood of garbage collector messages when the caret is visible
584617
585618Something like this:
586619
587620 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 188 objects / 6664 bytes in 94ms
588621 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 170 objects / 6160 bytes in 78ms
589622 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5904 bytes in 82ms
590623 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5856 bytes in 78ms
591624 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5872 bytes in 80ms
592625 D/dalvikvm( 2825): GC_EXPLICIT freed 371 objects / 18480 bytes in 91ms
593626 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5896 bytes in 78ms
594627 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5896 bytes in 78ms
595628 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5896 bytes in 81ms
596629 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5920 bytes in 78ms
597630 D/dalvikvm( 6364): GC_EXTERNAL_ALLOC freed 162 objects / 5920 bytes in 83ms
598631
599632In 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.
600633
601634### Why the caret of a TEdit keeps blinking after clicking on the form
602635
603636When 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.
604637
605638### Android ComboBox
606639
607640For adding Android combobox support a new method was added to LCLIntf along with a global variable to store the callback of this dialog:
608641
609642``` pascal
610643var
611644 OnShowSelectItemDialogResult: TOnShowSelectItemDialogResult;
612645
613646function ShowSelectItemDialog(const AItems: TStrings): Boolean; override;
614647```
615648
616649This method will run a native item selection dialog, if the platform has one, or result false without doing anything otherwise.
617650
618651![](/wiki-images/8/82/Android_combobox.png)
619652
620653### Using the Native ListView Dialog
621654
622655To allow the user to select items from a list more easily we offer a routine which launch dialog with the native ListView.
623656
624657``` pascal
625658{$ifdef LCLCustomDrawn}
626659uses customdrawnint, lclintf;
627660{$endif}
628661
629662procedure TForm2.Button3Click(Sender: TObject);
630663begin
631664{$ifdef LCLCustomDrawn}
632665 LCLIntf.OnListViewDialogResult := @MyOnListViewDialogResult;
633666 CDWidgetSet.ShowListViewDialog('Dialog Title',
634667 ['Title1', 'Title2', 'Title3', 'Title4', 'Title5', 'Title6'],
635668 ['Descr1', 'Descr2', 'Descr3', 'Descr4', 'Descr5', 'Descr6']);
636669{$endif}
637670end;
638671
639672procedure TForm2.MyOnListViewDialogResult(ASelectedItem: Integer);
640673begin
641674 DebugLn(Format('[MyOnListViewDialogResult] ASelectedItem=%d', [ASelectedItem]));
642675end;
643676```
644677
645678LCLIntf.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.
646679
647680Note 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!
648681
649682``` pascal
650683procedure TCDWidgetSet.ShowListViewDialog(ATitle: string; ATitles,
651684 ADescriptions: array of string;
652685 AColorOddRow: jint = $ff292C29; AColorEvenRow: jint = $ff424542);
653686```
654687
655688![](/wiki-images/2/2c/Android_ListView.png)
656689
657690### LazDeviceAPIs
658691
659692See: [[LazDeviceAPIs]]
660693
661694---
662695*From the Free Pascal wiki, page "Custom Drawn Interface/Android/ja", 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).*

Back to history