Sign in Join
Wiki copytemporary

Android Programming: what changed

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

OldNewLine
11*(Android only)*
22
33See also [[Custom Drawn Interface/Android]]
44
55Knowing general Android programming can be very useful to help develop the Lazarus Android Interface.
66
77## Platform Tips
88
99## How to...
1010
1111### Build the NDK OpenGL example
1212
1313Just follow these steps:
1414
1515**Step 1** - Download and install the Android NDK, Android SDK and Ant. More information here: [[Android Interface/Using the Android SDK, Emulator and Phones|Android_Interface/Using_the_Android_SDK%2C_Emulator_and_Phones]]
1616
1717**Step 2** - Install the pre-compiled FPC cross-compiler. Instructions here: [[Android Interface|Android_Interface#Using_the_pre-compiled_compiler]]
1818
1919**Step 3** - Download the latest lazarus-ccr sourceforge code:
2020
2121``` bash
2222svn co https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr lazarus-ccr
2323```
2424
2525or if you think it is too big you can download just the folder lazarus-ccr/bindings/android-ndk
2626
2727**Step 4** - Building the Pascal Library
2828
2929> **Note:** In the steps below, the directory /home/felipe/Programas or ~/Programas is used. Please adjust if your paths are different.
3030
3131Open the project lazarus-ccr/bindings/android-ndk/examples/opengltest/opengltest.lpi
3232
3333Go to Project-\>Project Options-\>Paths and where is written "Libraries -Fl" you should see a value like this:
3434
3535`/home/felipe/Programas/android-ndk-r5/platforms/android-9/arch-arm/usr/lib`
3636
3737Change it to the correct path in your system which points to the NDK and to the library folder for your minimal required Android API Level
3838
3939Now build the project using Lazarus.
4040
4141**Step 5** - Configuring the build environment
4242
4343Open the file opengltest/local.properties. Change this line to point to your SDK location:
4444
4545`sdk.dir=/home/felipe/Programas/android-sdk-linux`
4646
4747**Step 6** - Buildings the APK
4848
4949Open a terminal and type these commands:
5050
5151``` bash
5252cd lazarus-ccr/bindings/ndk/examples/opengltest/android
5353ant debug
5454```
5555
5656The APK file will be placed in opengltest/android/bin/
5757
5858**Step 7** - Install the APK
5959
6060In this step, if you get error messages about permissions read: [[Android Interface/Using the Android SDK, Emulator and Phones|Android_Interface/Using_the_Android_SDK%2C_Emulator_and_Phones#Recognition_of_devices_under_Linux]]
6161
6262The command to install our APK in the phone is:
6363
6464``` bash
6565cd opengltest/android
6666~/Programas/android-sdk-linux/platform-tools/adb install bin/OpenGLNDKTest-debug.apk
6767```
6868
6969You should see something like:
7070
7171`2395 KB/s (107299 bytes in 0.043s)`\
7272`       pkg: /data/local/tmp/OpenGLNDKTest-debug.apk`\
7373`Success`
7474
7575If you get an error message that it is already installed you can install with this command:
7676
7777``` bash
7878~/Programas/android-sdk-linux/platform-tools/adb uninstall com.pascal.opengltest
7979```
8080
8181And then you can run adb logcat to see what the log says while you start it in the phone via its newly added icon:
8282
8383``` bash
8484~/Programas/android-sdk-linux/platform-tools/adb logcat
8585```
8686
8787### Read the screen metrics
8888
8989First fill a TDisplayMetrics with the correct info:
9090
9191``` pascal
9292uses androidutil;
9393
9494var
9595 MyDisplayMetrics: TDisplayMetrics;
9696 Str: string;
9797 //
9898 lHeight, lWidth: Integer;
9999 xdpi, ydpi, lScreenSize: Single;
100100begin
101101 // ..
102102 // Objects
103103
104104 MyDisplayMetrics := TDisplayMetrics.Create;
105105 Activity.getWindowManager().getDefaultDisplay().getMetrics(MyDisplayMetrics);
106106```
107107
108108And then you can read it from the TDisplayMetrics:
109109
110110``` pascal
111111 lHeight := MyDisplayMetrics.heightPixels();
112112 lWidth := MyDisplayMetrics.widthPixels();
113113 xdpi := MyDisplayMetrics.xdpi();
114114 ydpi := MyDisplayMetrics.ydpi();
115115 lScreenSize := sqrt(sqr(lHeight / ydpi) + sqr(lWidth / xdpi));
116116 ldensity := MyDisplayMetrics.density();
117117 ldensityDpi := MyDisplayMetrics.densityDpi();
118118 scaledDensity := MyDisplayMetrics.scaledDensity();
119119```
120120
121121Note that lots of devices lie about the xdpi and ydpi, so don't trust the lScreenSize calculated above. Smartphones might report even 10 inches of screen size, while the correct is around 4.
122122
123123## Details about Android devices
124124
125125Since there are so many Android devices, it can be useful to keep track of some information about them. See also in the wikipedia Comparison of Android Devices [1](http://en.wikipedia.org/wiki/Comparison_of_Android_devices) and details about the processors in [2](https://wiki.mozilla.org/Mobile/Platforms/Android#System_Requirements).
126126
127127### Smartphones
128128
129129| Manufacturer | Model | Android API Name (Build.Model) | Processor | Android version | Multi-touch | Comments |
130130|----|----|----|----|----|----|----|
131131| HTC | Wildfire | HTC Wildfire | armv6 | 2.1=\>2.2 | Yes\|\|- | |
132132| Sony Erricson | Xperia X10 | X10i | armv7 | 1.6=\>2.1 | No\|\|- | |
133133
134134### Tablets
135135
136136| Manufacturer | Model | Android API Name (Build.Model) | Processor | Android version | Multi-touch | Comments |
137137|----|----|----|----|----|----|----|
138138| Toshiba | Folio 100 Tablet | TOSHIBA_FOLIO_AND_A | armv7 | 2.2 | Yes\|\|- | |
139139
140140### List of devices ordered by processor compatibility (ARMv6 vs ARMv7)
141141
142-<table>
143142<caption>List of ARMv7 devices</caption>
144143<tbody>
145-<tr>
146-<td>Advent Vega (P10AN01)</td>
147-<td>Dell Streak, Streak 7</td>
148-<td>HTC Desire</td>
149-<td>HTC Desire Z (T-Mobile G2)</td>
150-<td>HTC Desire HD</td>
151-</tr>
152-<tr>
153-<td>HTC Droid Incredible</td>
154-<td>HTC EVO 4G, EVO Shift 4G</td>
155-<td>HTC Glacier (T-Mobile myTouch 4G)</td>
156-<td>HTC Inspire 4G</td>
157-<td>HTC Nexus One</td>
158-</tr>
159-<tr>
160-<td>HTC Thunderbolt 4G</td>
161-<td>Huawei Ideos S7</td>
162-<td>LG Optimus Z</td>
163-<td>Motorola Atrix 4G</td>
164-<td>Motorola Bravo</td>
165-</tr>
166-<tr>
167-<td>Motorola Cliq 2 - untested</td>
168-<td>Motorola Defy</td>
169-<td>Motorola Droid 2, Droid 2 Global</td>
170-<td>Motorola Droid Pro (Motorola Pro)</td>
171-<td>Motorola Droid X</td>
172-</tr>
173-<tr>
174-<td>Motorola Xoom</td>
175-<td>POV Mobii Tegra Tablet</td>
176-<td>Samsung Continuum (i400)</td>
177-<td>Samsung Galaxy S (i9000, Captivate,<br />
144+
178145Fascinate, Vibrant, Epic 4G)</td>
179-<td>Samsung Galaxy Tab</td>
180-</tr>
181-<tr>
182-<td>Sharp IS03</td>
183-<td>Sony Ericsson Xperia X10</td>
184-<td>Toshiba AS100</td>
185-<td>Viewsonic gTablet</td>
186-<td>Acer Liquid E</td>
187-</tr>
188-<tr>
189-<td>Acer Liquid (Liquid A1)</td>
190-<td>Archos 101 Internet Tablet</td>
191-<td>Motorola Charm</td>
192-<td>Motorola Droid (Milestone)</td>
193-<td>Samsung Galaxy S 4G</td>
194-</tr>
195-<tr>
196-<td>Samsung Nexus S</td>
197-<td></td>
198-<td></td>
199-<td></td>
200-<td></td>
201-</tr>
146+
202147</tbody>
203-</table>
204148
205149| | | | |
206150|----|----|----|----|
207151| Android SDK emulator | Asus Garmin nuvifone A50 (T-Mobile Garminfone) | Augen GENTouch 78 Tablet | Coby Kyros Internet Tablet (MID7015) |
208152| Geeksphone One, Geeksphone Zero | HTC Aria | HTC ChaCha | HTC Dream (T-Mobile G1, Android Dev Phone 1) |
209153| HTC Droid Eris | HTC Espresso (T-Mobile myTouch 3G Slide) | HTC Hero (T-Mobile G2 Touch) | \|HTC Legend |
210154| HTC Magic (T-Mobile myTouch 3G, T-Mobile G1 Touch) | HTC Salsa | HTC Tattoo | HTC Wildfire |
211155| Huawei Ascend | Huawei Ideos U8150-B (T-Mobile Comet) | Huawei U8110 (T-Mobile Pulse Mini) | \|Huawei U8230 |
212156| LG Ally (Apex) (LG VS740) | LG GW620 (Eve, InTouch Max, LinkMe) | LG Optimus, Optimus M, Optimus T, Optimus S, Optimus V | LG Vortex |
213157| LG P500 | MAG iMiTO iM7 | vMAG iMiTO iM7S | Motorola Backflip |
214158| Motorola Citrus | Motorola Cliq (MB200) | Motorola Dext | Motorola Devour |
215159| Motorola i1 | Motorola Spice XT300 | Motorola Quench XT5 XT502 | Pandigital Novel |
216160| Samsung GT-S5570 Galaxy Mini | Samsung i5500 Galaxy 5 (Corby) | Samsung i5700 Galaxy Portal (Spica) | Samsung i5800 Galaxy 3 |
217161| Samsung i7500 Galaxy | Samsung Intercept | Samsung M900 Moment | Samsung S5830 Galaxy Ace |
218162| Samsung Transform | Sanyo ZIO M6000 | Sony Ericsson Xperia X8 | Sony Ericsson Xperia X10 Mini |
219163| Sony Ericsson Xperia X10 Mini Pro | Superpad 10.2" Tablet PC | Viewsonic ViewPad 7 Tablet | Velocity Micro T103 Cruz tablet |
220164| Vodafone 845 | ZTE Blade | | |
221165
222166List of ARMv6 processors:'''
223167
224168### Playing sounds and videos on the phones
225169
226170Each phone comes with different codecs installed, which means that the native Media Player will be able to play different formats in different phones. Below is a table showing which formats play in the native Media Player of each phone:
227171
228172| Telephone | Android | webm - VP8 | m4v - H.264 | ogv - Theora | mp4 - H.264 | mov - H.264 | avi - RLE | mpg - MPEG-1 | wmv - WM9 | 3gp - MPEG-4 |
229173|----|----|----|----|----|----|----|----|----|----|----|
230174| Emulator | 1.6 | x | x | x | x | x | x | x | x | OK |
231175| Emulator | 2.1 | x | x | x | x | x | x | x | x | OK |
232176| Nexus One | 2.2 | x | OK | x | OK | x | x | x | x | OK |
233177| HTC Desire | 1.6 | x | OK | x | OK | x | x | x | OK | OK |
234178| Toshiba Folio 100 | 2.2 | x | OK | x | OK | x | x | x | OK | OK |
235179| Xperia X10 | 2.1 | x | OK | x | x | x | x | x | OK | OK |
236180| Xperia X8 | 2.2 | x | OK | x | x | x | x | x | x | OK |
237181| HTC Wildfire | 2.1 | x | OK | x | x | x | x | x | x | OK |
238182| HTC Desire HD | 2.2 | x | OK | x | OK | x | x | x | x | OK |
239183| Galaxy Tab | 2.2 | x | OK | x | x | x | x | x | x | OK |
240184| myPhone A210 | 1.6 | x | OK | x | x | x | x | x | x | OK |
241185| Motorola Milestone | 2.1 | x | OK | x | x | x | x | x | OK | ? |
242186| Milestone 2 | 2.2 | x | OK | x | x | x | x | x | sound-only | OK |
243187
244188## Android file system
245189
246190Android recommends to use getApplicationContext().getFilesDir() to obtain the data directory for the application and this routine in my HTC Wildfire returns /data/data/\<package name\>
247191
248192The native libraries of the application are placed in /data/data/\<package\>/lib
249193
250194A good place where we have read and write access and we can create new files and even run files is /data/data/\<package name\>
251195
252196## Creating a new Java Android application
253197
254198This info can be useful for helping implement LCL-CustomDrawn-Android
255199
256200Generic instructions here: <http://developer.android.com/guide/developing/other-ide.html>
257201
258202### Showing/hiding the virtual keyboard
259203
260204See here: <http://android-codes-examples.blogspot.com/2011/11/show-or-hide-soft-keyboard-on-opening.html>
261205
262206To show it:
263207
264208``` java
265209InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
266210imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
267211```
268212
269213and for hiding the keyboard:
270214
271215``` java
272216InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
273217imm.hideSoftInputFromWindow(singleedittext.getWindowToken(),0);
274218```
275219
276220## Android JNI
277221
278222Using JNI (Java Native Interface) you can call most Android SDK APIs and also other Java libraries.
279223
280224### Table of Java types and Pascal JNI types
281225
282226All of the Java types except interfaces can be represented in JNI without problems. For each Java type there is a corresponding VM Type Signature which is utilized in routines such as javaEnvRef^^.GetMethodID. There is also the JNI native type, which is the type declared in the unit lazarus/lcl/interfaces/customdrawn/android/jni.pas and should be the type utilized in JNI code written in Pascal. The Pascal equivalent is provided just for comparison, as one should use the types from jni.pas when writing JNI code.
283227
284228| Java type | VM signature | Type in jni.pas | Pascal equivalent | Description |
285229|----|----|----|----|----|
286230| boolean | Z | jboolean | Boolean | |
287231| byte | B | jbyte | Byte | |
288232| char | C | jchar | Word | |
289233| short | S | jshort | Shortint | |
290234| int | I | jint | Integer | |
291235| long | J | jlong | Int64 | |
292236| float | F | jfloat | Single | |
293237| double | D | jdouble | Double | |
294238| a class, ie: String or InputStream | L\<full class name\> ie: Ljava/lang/String; | jobject | N/A | |
295239| Array, ie: int\[\] | \[\<type-name\> ie: \[I | N/A | | |
296240| A method type | (arg-types)ref-type | JMethodID | N/A | |
297241| void | V | N/A | procedure | |
298242
299243### Example 1: Creating a Java object and calling a Java method
300244
301245Let's say that you want to make Pascal JNI code equivalent to the following Java code:
302246
303247``` java
304248 HttpGet javaRequest = new HttpGet();
305249 URI myURI = new URI("http://magnifier.sourceforge.net/");
306250 javaRequest.setURI(myURI);
307251```
308252
309253First you need to get all Class IDs involved in the process, then get all method IDs which we will use and then make the calls. If the call has parameters, then pass it in an array. The following Pascal native code is equivalent to that Java code above:
310254
311255``` pascal
312256uses jni, customdrawnint;
313257
314258var
315259 javaClass_HttpGet, javaClass_URI: jclass;
316260 javaMethod_HttpGet_new, javaMethod_HttpGet_setURI,
317261 javaMethod_URI_new: jmethodid;
318262 javaRequest, javaURI: jobject;
319263 javaString: jstring;
320264 lParams: array[0..2] of JValue;
321265 lNativeString: PChar;
322266begin
323267 DebugLn(':>LoadHTMLPageViaJNI');
324268 // First call FindClass for all required classes
325269 javaClass_HttpGet := javaEnvRef^^.FindClass(javaEnvRef,
326270 'org/apache/http/client/methods/HttpGet');
327271 javaClass_URI := javaEnvRef^^.FindClass(javaEnvRef,
328272 'java/net/URI');
329273
330274 // Now all Method IDs
331275 DebugLn(':LoadHTMLPageViaJNI 1');
332276 javaMethod_HttpGet_new := javaEnvRef^^.GetMethodID(javaEnvRef, javaClass_HttpGet, '<init>', '()V');
333277 javaMethod_HttpGet_setURI := javaEnvRef^^.GetMethodID(javaEnvRef, javaClass_HttpGet, 'setURI', '(Ljava/net/URI;)V');
334278 javaMethod_URI_new := javaEnvRef^^.GetMethodID(javaEnvRef, javaClass_URI, '<init>', '(Ljava/lang/String;)V');
335279
336280 // Create a new instance for the HTTP request object
337281 // HttpGet javaRequest = new HttpGet();
338282 javaRequest := javaEnvRef^^.NewObject(javaEnvRef,
339283 javaClass_HttpGet,
340284 javaMethod_HttpGet_new);
341285
342286 DebugLn(':LoadHTMLPageViaJNI 4 javaRequest='+IntToHex(PtrInt(javaRequest), 8));
343287 // Add a URI for the request object
344288 // URI javaURI = new URI("http://magnifier.sourceforge.net/");
345289 lParams[0].l := javaEnvRef^^.NewStringUTF(javaEnvRef, 'http://magnifier.sourceforge.net');
346290 javaURI := javaEnvRef^^.NewObjectA(javaEnvRef,
347291 javaClass_URI, javaMethod_URI_new, @lParams[0]);
348292 javaEnvRef^^.DeleteLocalRef(javaEnvRef, lParams[0].l);
349293 // javaRequest.setURI(javaURI);
350294 lParams[0].l := javaURI;
351295 javaEnvRef^^.CallVoidMethodA(javaEnvRef, javaRequest,
352296 javaMethod_HttpGet_setURI, @lParams[0]);
353297```
354298
355299### Example 2: Calling a static method
356300
357301Let's say that you want to call the following static method located in the Bass class: <http://jerome.jouvie.free.fr/nativebass/javadoc/org/jouvieje/bass/Bass.html>
358302
359303``` java
360304 public static native int BASS_StreamCreateFile(String file, long offset, long length, int flags);
361305```
362306
363307First you need to get all Class IDs involved in the process, then get the static method ID and then make the call with the parameter in the array:
364308
365309``` pascal
366310uses jni, customdrawnint;
367311
368312var
369313 javaClass_Bass: jclass;
370314 javaMethod_Bass_BASS_StreamCreateFile: jmethodid;
371315 javaString: jstring;
372316 lParams: array[0..3] of JValue;
373317 lRetInt: jint;
374318begin
375319 // First call FindClass for all required classes
376320 javaClass_Bass := javaEnvRef^^.FindClass(javaEnvRef, 'org/jouvieje/bass/Bass');
377321
378322 // Now all Method IDs
379323 javaMethod_Bass_BASS_StreamCreateFile := javaEnvRef^^.GetStaticMethodID(javaEnvRef, javaClass_Bass, 'BASS_StreamCreateFile', '(Ljava/lang/String;JJI)I');
380324
381325 // Make the call
382326 lParams[0].l := javaEnvRef^^.NewStringUTF(javaEnvRef, '/path/to/file');
383327 lParams[1].j := 0; // offset
384328 lParams[2].j := 200; // length
385329 lParams[3].i := 0; // flags
386330 lRetInt := javaEnvRef^^.CallStaticIntMethodA(javaEnvRef, javaClass_Bass, javaMethod_Bass_BASS_StreamCreateFile, @lParams[0]);
387331 javaEnvRef^^.DeleteLocalRef(javaEnvRef, lParams[0].l);
388332```
389333
390334## References
391335
392336- <http://developer.android.com/guide/developing/other-ide.html>
393337- [Tutorial "Lazarus and Android"](https://dl.dropboxusercontent.com/u/3753548/Lazarus%20and%20Android.pdf) (PDF file)
394338
395339---
396340*From the Free Pascal wiki, page "Android Programming", as it stood on 2019-12-16 after a change by Trev, 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