Sign in Join
Wiki copytemporary

Android Programming: what changed

Revision 4 to 5. 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```text
3636/home/felipe/Programas/android-ndk-r5/platforms/android-9/arch-arm/usr/lib
3737```
3838
3939Change 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
4040
4141Now build the project using Lazarus.
4242
4343**Step 5** - Configuring the build environment
4444
4545Open the file opengltest/local.properties. Change this line to point to your SDK location:
4646
4747```text
4848sdk.dir=/home/felipe/Programas/android-sdk-linux
4949```
5050
5151**Step 6** - Buildings the APK
5252
5353Open a terminal and type these commands:
5454
5555``` bash
5656cd lazarus-ccr/bindings/ndk/examples/opengltest/android
5757ant debug
5858```
5959
6060The APK file will be placed in opengltest/android/bin/
6161
6262**Step 7** - Install the APK
6363
6464In 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]]
6565
6666The command to install our APK in the phone is:
6767
6868``` bash
6969cd opengltest/android
7070~/Programas/android-sdk-linux/platform-tools/adb install bin/OpenGLNDKTest-debug.apk
7171```
7272
7373You should see something like:
7474
7575```text
76762395 KB/s (107299 bytes in 0.043s)
7777 pkg: /data/local/tmp/OpenGLNDKTest-debug.apk
7878Success
7979```
8080
8181If you get an error message that it is already installed you can install with this command:
8282
8383``` bash
8484~/Programas/android-sdk-linux/platform-tools/adb uninstall com.pascal.opengltest
8585```
8686
8787And then you can run adb logcat to see what the log says while you start it in the phone via its newly added icon:
8888
8989``` bash
9090~/Programas/android-sdk-linux/platform-tools/adb logcat
9191```
9292
9393### Read the screen metrics
9494
9595First fill a TDisplayMetrics with the correct info:
9696
9797``` pascal
9898uses androidutil;
9999
100100var
101101 MyDisplayMetrics: TDisplayMetrics;
102102 Str: string;
103103 //
104104 lHeight, lWidth: Integer;
105105 xdpi, ydpi, lScreenSize: Single;
106106begin
107107 // ..
108108 // Objects
109109
110110 MyDisplayMetrics := TDisplayMetrics.Create;
111111 Activity.getWindowManager().getDefaultDisplay().getMetrics(MyDisplayMetrics);
112112```
113113
114114And then you can read it from the TDisplayMetrics:
115115
116116``` pascal
117117 lHeight := MyDisplayMetrics.heightPixels();
118118 lWidth := MyDisplayMetrics.widthPixels();
119119 xdpi := MyDisplayMetrics.xdpi();
120120 ydpi := MyDisplayMetrics.ydpi();
121121 lScreenSize := sqrt(sqr(lHeight / ydpi) + sqr(lWidth / xdpi));
122122 ldensity := MyDisplayMetrics.density();
123123 ldensityDpi := MyDisplayMetrics.densityDpi();
124124 scaledDensity := MyDisplayMetrics.scaledDensity();
125125```
126126
127127Note 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.
128128
129129## Details about Android devices
130130
131131Since 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).
132132
133133### Smartphones
134134
135135| Manufacturer | Model | Android API Name (Build.Model) | Processor | Android version | Multi-touch | Comments |
136136|----|----|----|----|----|----|----|
137137| HTC | Wildfire | HTC Wildfire | armv6 | 2.1=\>2.2 | Yes\|\|- | |
138138| Sony Erricson | Xperia X10 | X10i | armv7 | 1.6=\>2.1 | No\|\|- | |
139139
140140### Tablets
141141
142142| Manufacturer | Model | Android API Name (Build.Model) | Processor | Android version | Multi-touch | Comments |
143143|----|----|----|----|----|----|----|
144144| Toshiba | Folio 100 Tablet | TOSHIBA_FOLIO_AND_A | armv7 | 2.2 | Yes\|\|- | |
145145
146146### List of devices ordered by processor compatibility (ARMv6 vs ARMv7)
147147
148-<caption>List of ARMv7 devices</caption>
149-<tbody>
150-
151-Fascinate, Vibrant, Epic 4G)</td>
148+**List of ARMv7 devices**
152149
153-</tbody>
150+| Advent Vega (P10AN01) | Dell Streak, Streak 7 | HTC Desire | HTC Desire Z (T-Mobile G2) | HTC Desire HD |
151+|---|---|---|---|---|
152+| HTC Droid Incredible | HTC EVO 4G, EVO Shift 4G | HTC Glacier (T-Mobile myTouch 4G) | HTC Inspire 4G | HTC Nexus One |
153+| HTC Thunderbolt 4G | Huawei Ideos S7 | LG Optimus Z | Motorola Atrix 4G | Motorola Bravo |
154+| Motorola Cliq 2 - untested | Motorola Defy | Motorola Droid 2, Droid 2 Global | Motorola Droid Pro (Motorola Pro) | Motorola Droid X |
155+| Motorola Xoom | POV Mobii Tegra Tablet | Samsung Continuum (i400) | Samsung Galaxy S (i9000, Captivate, · Fascinate, Vibrant, Epic 4G) | Samsung Galaxy Tab |
156+| Sharp IS03 | Sony Ericsson Xperia X10 | Toshiba AS100 | Viewsonic gTablet | Acer Liquid E |
157+| Acer Liquid (Liquid A1) | Archos 101 Internet Tablet | Motorola Charm | Motorola Droid (Milestone) | Samsung Galaxy S 4G |
158+| Samsung Nexus S | | | | |
154159
155160| | | | |
156161|----|----|----|----|
157162| Android SDK emulator | Asus Garmin nuvifone A50 (T-Mobile Garminfone) | Augen GENTouch 78 Tablet | Coby Kyros Internet Tablet (MID7015) |
158163| Geeksphone One, Geeksphone Zero | HTC Aria | HTC ChaCha | HTC Dream (T-Mobile G1, Android Dev Phone 1) |
159164| HTC Droid Eris | HTC Espresso (T-Mobile myTouch 3G Slide) | HTC Hero (T-Mobile G2 Touch) | \|HTC Legend |
160165| HTC Magic (T-Mobile myTouch 3G, T-Mobile G1 Touch) | HTC Salsa | HTC Tattoo | HTC Wildfire |
161166| Huawei Ascend | Huawei Ideos U8150-B (T-Mobile Comet) | Huawei U8110 (T-Mobile Pulse Mini) | \|Huawei U8230 |
162167| LG Ally (Apex) (LG VS740) | LG GW620 (Eve, InTouch Max, LinkMe) | LG Optimus, Optimus M, Optimus T, Optimus S, Optimus V | LG Vortex |
163168| LG P500 | MAG iMiTO iM7 | vMAG iMiTO iM7S | Motorola Backflip |
164169| Motorola Citrus | Motorola Cliq (MB200) | Motorola Dext | Motorola Devour |
165170| Motorola i1 | Motorola Spice XT300 | Motorola Quench XT5 XT502 | Pandigital Novel |
166171| Samsung GT-S5570 Galaxy Mini | Samsung i5500 Galaxy 5 (Corby) | Samsung i5700 Galaxy Portal (Spica) | Samsung i5800 Galaxy 3 |
167172| Samsung i7500 Galaxy | Samsung Intercept | Samsung M900 Moment | Samsung S5830 Galaxy Ace |
168173| Samsung Transform | Sanyo ZIO M6000 | Sony Ericsson Xperia X8 | Sony Ericsson Xperia X10 Mini |
169174| Sony Ericsson Xperia X10 Mini Pro | Superpad 10.2" Tablet PC | Viewsonic ViewPad 7 Tablet | Velocity Micro T103 Cruz tablet |
170175| Vodafone 845 | ZTE Blade | | |
171176
172177List of ARMv6 processors:'''
173178
174179### Playing sounds and videos on the phones
175180
176181Each 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:
177182
178183| 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 |
179184|----|----|----|----|----|----|----|----|----|----|----|
180185| Emulator | 1.6 | x | x | x | x | x | x | x | x | OK |
181186| Emulator | 2.1 | x | x | x | x | x | x | x | x | OK |
182187| Nexus One | 2.2 | x | OK | x | OK | x | x | x | x | OK |
183188| HTC Desire | 1.6 | x | OK | x | OK | x | x | x | OK | OK |
184189| Toshiba Folio 100 | 2.2 | x | OK | x | OK | x | x | x | OK | OK |
185190| Xperia X10 | 2.1 | x | OK | x | x | x | x | x | OK | OK |
186191| Xperia X8 | 2.2 | x | OK | x | x | x | x | x | x | OK |
187192| HTC Wildfire | 2.1 | x | OK | x | x | x | x | x | x | OK |
188193| HTC Desire HD | 2.2 | x | OK | x | OK | x | x | x | x | OK |
189194| Galaxy Tab | 2.2 | x | OK | x | x | x | x | x | x | OK |
190195| myPhone A210 | 1.6 | x | OK | x | x | x | x | x | x | OK |
191196| Motorola Milestone | 2.1 | x | OK | x | x | x | x | x | OK | ? |
192197| Milestone 2 | 2.2 | x | OK | x | x | x | x | x | sound-only | OK |
193198
194199## Android file system
195200
196201Android 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\>
197202
198203The native libraries of the application are placed in /data/data/\<package\>/lib
199204
200205A good place where we have read and write access and we can create new files and even run files is /data/data/\<package name\>
201206
202207## Creating a new Java Android application
203208
204209This info can be useful for helping implement LCL-CustomDrawn-Android
205210
206211Generic instructions here: <http://developer.android.com/guide/developing/other-ide.html>
207212
208213### Showing/hiding the virtual keyboard
209214
210215See here: <http://android-codes-examples.blogspot.com/2011/11/show-or-hide-soft-keyboard-on-opening.html>
211216
212217To show it:
213218
214219``` java
215220InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
216221imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
217222```
218223
219224and for hiding the keyboard:
220225
221226``` java
222227InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
223228imm.hideSoftInputFromWindow(singleedittext.getWindowToken(),0);
224229```
225230
226231## Android JNI
227232
228233Using JNI (Java Native Interface) you can call most Android SDK APIs and also other Java libraries.
229234
230235### Table of Java types and Pascal JNI types
231236
232237All 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.
233238
234239| Java type | VM signature | Type in jni.pas | Pascal equivalent | Description |
235240|----|----|----|----|----|
236241| boolean | Z | jboolean | Boolean | |
237242| byte | B | jbyte | Byte | |
238243| char | C | jchar | Word | |
239244| short | S | jshort | Shortint | |
240245| int | I | jint | Integer | |
241246| long | J | jlong | Int64 | |
242247| float | F | jfloat | Single | |
243248| double | D | jdouble | Double | |
244249| a class, ie: String or InputStream | L\<full class name\> ie: Ljava/lang/String; | jobject | N/A | |
245250| Array, ie: int\[\] | \[\<type-name\> ie: \[I | N/A | | |
246251| A method type | (arg-types)ref-type | JMethodID | N/A | |
247252| void | V | N/A | procedure | |
248253
249254### Example 1: Creating a Java object and calling a Java method
250255
251256Let's say that you want to make Pascal JNI code equivalent to the following Java code:
252257
253258``` java
254259 HttpGet javaRequest = new HttpGet();
255260 URI myURI = new URI("http://magnifier.sourceforge.net/");
256261 javaRequest.setURI(myURI);
257262```
258263
259264First 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:
260265
261266``` pascal
262267uses jni, customdrawnint;
263268
264269var
265270 javaClass_HttpGet, javaClass_URI: jclass;
266271 javaMethod_HttpGet_new, javaMethod_HttpGet_setURI,
267272 javaMethod_URI_new: jmethodid;
268273 javaRequest, javaURI: jobject;
269274 javaString: jstring;
270275 lParams: array[0..2] of JValue;
271276 lNativeString: PChar;
272277begin
273278 DebugLn(':>LoadHTMLPageViaJNI');
274279 // First call FindClass for all required classes
275280 javaClass_HttpGet := javaEnvRef^^.FindClass(javaEnvRef,
276281 'org/apache/http/client/methods/HttpGet');
277282 javaClass_URI := javaEnvRef^^.FindClass(javaEnvRef,
278283 'java/net/URI');
279284
280285 // Now all Method IDs
281286 DebugLn(':LoadHTMLPageViaJNI 1');
282287 javaMethod_HttpGet_new := javaEnvRef^^.GetMethodID(javaEnvRef, javaClass_HttpGet, '<init>', '()V');
283288 javaMethod_HttpGet_setURI := javaEnvRef^^.GetMethodID(javaEnvRef, javaClass_HttpGet, 'setURI', '(Ljava/net/URI;)V');
284289 javaMethod_URI_new := javaEnvRef^^.GetMethodID(javaEnvRef, javaClass_URI, '<init>', '(Ljava/lang/String;)V');
285290
286291 // Create a new instance for the HTTP request object
287292 // HttpGet javaRequest = new HttpGet();
288293 javaRequest := javaEnvRef^^.NewObject(javaEnvRef,
289294 javaClass_HttpGet,
290295 javaMethod_HttpGet_new);
291296
292297 DebugLn(':LoadHTMLPageViaJNI 4 javaRequest='+IntToHex(PtrInt(javaRequest), 8));
293298 // Add a URI for the request object
294299 // URI javaURI = new URI("http://magnifier.sourceforge.net/");
295300 lParams[0].l := javaEnvRef^^.NewStringUTF(javaEnvRef, 'http://magnifier.sourceforge.net');
296301 javaURI := javaEnvRef^^.NewObjectA(javaEnvRef,
297302 javaClass_URI, javaMethod_URI_new, @lParams[0]);
298303 javaEnvRef^^.DeleteLocalRef(javaEnvRef, lParams[0].l);
299304 // javaRequest.setURI(javaURI);
300305 lParams[0].l := javaURI;
301306 javaEnvRef^^.CallVoidMethodA(javaEnvRef, javaRequest,
302307 javaMethod_HttpGet_setURI, @lParams[0]);
303308```
304309
305310### Example 2: Calling a static method
306311
307312Let'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>
308313
309314``` java
310315 public static native int BASS_StreamCreateFile(String file, long offset, long length, int flags);
311316```
312317
313318First 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:
314319
315320``` pascal
316321uses jni, customdrawnint;
317322
318323var
319324 javaClass_Bass: jclass;
320325 javaMethod_Bass_BASS_StreamCreateFile: jmethodid;
321326 javaString: jstring;
322327 lParams: array[0..3] of JValue;
323328 lRetInt: jint;
324329begin
325330 // First call FindClass for all required classes
326331 javaClass_Bass := javaEnvRef^^.FindClass(javaEnvRef, 'org/jouvieje/bass/Bass');
327332
328333 // Now all Method IDs
329334 javaMethod_Bass_BASS_StreamCreateFile := javaEnvRef^^.GetStaticMethodID(javaEnvRef, javaClass_Bass, 'BASS_StreamCreateFile', '(Ljava/lang/String;JJI)I');
330335
331336 // Make the call
332337 lParams[0].l := javaEnvRef^^.NewStringUTF(javaEnvRef, '/path/to/file');
333338 lParams[1].j := 0; // offset
334339 lParams[2].j := 200; // length
335340 lParams[3].i := 0; // flags
336341 lRetInt := javaEnvRef^^.CallStaticIntMethodA(javaEnvRef, javaClass_Bass, javaMethod_Bass_BASS_StreamCreateFile, @lParams[0]);
337342 javaEnvRef^^.DeleteLocalRef(javaEnvRef, lParams[0].l);
338343```
339344
340345## References
341346
342347- <http://developer.android.com/guide/developing/other-ide.html>
343348- [Tutorial "Lazarus and Android"](https://dl.dropboxusercontent.com/u/3753548/Lazarus%20and%20Android.pdf) (PDF file)
344349
345350---
346351*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