Sign in Join
Wiki copytemporary

Android Programming/ko: what changed

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

Title: Android Programming/ko

OldNewLine
1+[[Custom Drawn Interface/Android|Custom Drawn Interface/Android도]] 보세요
2+
3+일반적인 안드로이드 프로그래밍을 아는 것은 라자루스 안드로이드 인터페이스를 개발에 매우 유용하다.
4+
5+## 방법...
6+
7+### NDK OpenGL 예제 빌드하기
8+
9+다음 단계를 따르시요:
10+
11+**1 단계** - 안드로이드 NDK, 안드로이드 SDK 및 Ant.를 다운로드하고 설치하세요. 더 많은 정보는 다음에: [[Android Interface/Using the Android SDK, Emulator and Phones|안드로이드 SDK와 에뮬레이터 및 폰을 사용한 안드로이드 인터페이스]]
12+
13+**2 단계** - 프리-컴파일 된 FPC 크로스-컴파일러를 설치한다. 설명은 이곳에: [[Android Interface|Android_Interface#Using_the_pre-compiled_compiler]]
14+
15+**3 단계** - 최신 라자루스 ccr소스포지 코드를 다운로드 한다:
16+
17+`svn co `[`https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr`](https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr)` lazarus-ccr`
18+
19+또는 만약 너무 크다고 생각한다면 lazarus-ccr/bindings/android-ndk 폴더만 다운로드하면 된다.
20+
21+**4 단계** - 파스칼 라이브러리를 빌드한다.
22+
23+lazarus-ccr/bindings/android-ndk/examples/opengltest/opengltest.lpi 프로젝트를 연다.
24+
25+Project-\>Project Options-\>Paths로 가서 "Libraries -Fl"이라고 쓰인 곳에서 이 값을 확인한다:
26+
27+`/home/felipe/Programas/android-ndk-r5/platforms/android-9/arch-arm/usr/lib`
28+
29+각자의 시스템에 있는 NDK와 최소 요구 안드로이드 API 레벨의 폴더를 가르키는 정확한 패스로 변경한다.
30+
31+이제 라자루스에서 프로젝트를 빌드한다.
32+
33+**5 단계** - 빌드환경을 구성한다.
34+
35+opengltest/local.propertie 파일을 열고 이 라인을 다음과 같이:
36+
37+`sdk.dir=/home/felipe/Programas/android-sdk-linux`
38+
39+이것을 SDK 위치로 변경한다.
40+
41+**6 단계** - APK를 빌드한다.
42+
43+터미널을 역고 다음 명령을 입력한다:
44+
45+cd lazarus-ccr/bindings/ndk/examples/opengltest/android ant debug
46+
47+APK파일이 opengltest/android/bin/에 위치해 있을 것이다.
48+
49+**7 단계** - APK를 설치한다.
50+
51+이 단계에서 퍼미션에 관한 에러가 발생하면 다음 글을 읽어라: [[Android Interface/Using the Android SDK, Emulator and Phones|리눅스에서 장치의 인식]]
52+
53+폰에서 APK를 설치하는 명령은:
54+
55+`cd opengltest/android`\
56+`~/Programas/android-sdk-linux/platform-tools/adb install bin/OpenGLNDKTest-debug.apk `\
57+`2395 KB/s (107299 bytes in 0.043s)`\
58+`       pkg: /data/local/tmp/OpenGLNDKTest-debug.apk`\
59+`Success`
60+
61+이미 설치되어 있다는 에러 메세지가 나오면 다음 명령으로 설치할 수가 있다:
62+
63+`~/Programas/android-sdk-linux/platform-tools/adb uninstall com.pascal.opengltest`
64+
65+그리고 나서 새로이 추가된 아이콘을 통해 폰에서 실행하는 동안 무슨 로그가 있는지 알려면 adb logcat을 실행하면 된다:
66+
67+`~/Programas/android-sdk-linux/platform-tools/adb logcat`
68+
69+### 스크린 metrics 읽기
70+
71+먼저 TDisplayMetrics에 정확한 정보를 넣는다:
72+
73+``` pascal
74+uses androidutil;
75+
76+var
77+ MyDisplayMetrics: TDisplayMetrics;
78+ Str: string;
79+ //
80+ lHeight, lWidth: Integer;
81+ xdpi, ydpi, lScreenSize: Single;
82+begin
83+ // ..
84+ // 객체
85+
86+ MyDisplayMetrics := TDisplayMetrics.Create;
87+ Activity.getWindowManager().getDefaultDisplay().getMetrics(MyDisplayMetrics);
88+```
89+
90+그리고 나면 TDisplayMetrics에 읽을 수 있다:
91+
92+``` pascal
93+ lHeight := MyDisplayMetrics.heightPixels();
94+ lWidth := MyDisplayMetrics.widthPixels();
95+ xdpi := MyDisplayMetrics.xdpi();
96+ ydpi := MyDisplayMetrics.ydpi();
97+ lScreenSize := sqrt(sqr(lHeight / ydpi) + sqr(lWidth / xdpi));
98+ ldensity := MyDisplayMetrics.density();
99+ ldensityDpi := MyDisplayMetrics.densityDpi();
100+ scaledDensity := MyDisplayMetrics.scaledDensity();
101+```
102+
103+많은 장치가 xdpi 와 ydpi가 다르다. 그러므로 위에서 계산한 lScreenSize 를 믿지마라. 스마트폰이 10 인치로 되어 있더라도, 정확한 값은 4 주변이다.
104+
105+## 안드로이드 기기에 대한 세부사항
106+
107+무척 많은 안드로이드 기기가 있이 때문에, 기기에 대한 몇가지 정보를 추적하는 것이 유용할 수 있다. 안드로이드 기기에 대해 위키피디아에서 비교한 \[ <http://en.wikipedia.org/wiki/Comparison_of_Android_devices>\] 것과\[<https://wiki.mozilla.org/Mobile/Platforms/Android#System_Requirements%5D에> 있는 프로세서의 자세한 명세를 읽어봐야 한다.
108+
109+### 스마트폰
110+
111+| 제조사 | 모델 | 안드로이드 API 이름 (빌드.모델) | 프로세서 | 안드로이드 버전 | 멀티터치 | 기타 |
112+|----|----|----|----|----|----|----|
113+| HTC | Wildfire | HTC Wildfire | armv6 | 2.1=\>2.2 | Yes\|\|- | |
114+| Sony Erricson | Xperia X10 | X10i | armv7 | 1.6=\>2.1 | No\|\|- | |
115+
116+### 태블릿
117+
118+| 제조사 | 모델 | 안드로이드 API 이름 (빌드.모델) | 프로세서 | 안드로이드 버전 | 멀티터치 | 기타 |
119+|----|----|----|----|----|----|----|
120+| Toshiba | Folio 100 Tablet | TOSHIBA_FOLIO_AND_A | armv7 | 2.2 | Yes\|\|- | |
121+
122+### 프로세서 호환(ARMv6 vs ARMv7) 순서에 따른 기기 리스트
123+
124+**ARMv7 기기리스트:**
125+
126+- Advent Vega (P10AN01)
127+- Dell Streak, Streak 7
128+- HTC Desire
129+- HTC Desire Z (T-Mobile G2)
130+- HTC Desire HD
131+- HTC Droid Incredible
132+- HTC EVO 4G, EVO Shift 4G
133+- HTC Glacier (T-Mobile myTouch 4G)
134+- HTC Inspire 4G
135+- HTC Nexus One
136+- HTC Thunderbolt 4G
137+- Huawei Ideos S7
138+- LG Optimus Z
139+- Motorola Atrix 4G
140+- Motorola Bravo
141+- Motorola Cliq 2 - untested
142+- Motorola Defy
143+- Motorola Droid 2, Droid 2 Global
144+- Motorola Droid Pro (Motorola PRO)
145+- Motorola Droid X
146+- Motorola Xoom
147+- POV Mobii Tegra Tablet
148+- Samsung Continuum (i400)
149+- Samsung Galaxy S (i9000, Captivate, Fascinate, Vibrant, Epic 4G)
150+- Samsung Galaxy Tab
151+- Sharp IS03
152+- Sony Ericsson Xperia X10
153+- Toshiba AS100
154+- Viewsonic gTablet
155+- Acer Liquid E
156+- Acer Liquid (Liquid A1)
157+- Archos 101 Internet Tablet
158+- Motorola Charm
159+- Motorola Droid (Milestone)
160+- Samsung Galaxy S 4G
161+- Samsung Nexus S
162+
163+**ARMv6 프로세서 리스트:**
164+
165+- Android SDK 에뮬레이터
166+- Asus Garmin nuvifone A50 (T-Mobile Garminfone)
167+- Augen GENTouch 78 Tablet
168+- Coby Kyros Internet Tablet (MID7015)
169+- Geeksphone One, Geeksphone Zero
170+- HTC Aria
171+- HTC ChaCha
172+- HTC Dream (T-Mobile G1, Android Dev Phone 1)
173+- HTC Droid Eris
174+- HTC Espresso (T-Mobile myTouch 3G Slide)
175+- HTC Hero (T-Mobile G2 Touch)
176+- HTC Legend
177+- HTC Magic (T-Mobile myTouch 3G, T-Mobile G1 Touch)
178+- HTC Salsa
179+- HTC Tattoo
180+- HTC Wildfire
181+- Huawei Ascend
182+- Huawei Ideos U8150-B (T-Mobile Comet)
183+- Huawei U8110 (T-Mobile Pulse Mini)
184+- Huawei U8230
185+- LG Ally (Apex) (LG VS740)
186+- LG GW620 (Eve, InTouch Max, LinkMe)
187+- LG Optimus, Optimus M, Optimus T, Optimus S, Optimus V
188+- LG Vortex
189+- LG P500
190+- MAG iMiTO iM7
191+- vMAG iMiTO iM7S
192+- Motorola Backflip
193+- Motorola Citrus
194+- Motorola Cliq (MB200)
195+- Motorola Dext
196+- Motorola Devour
197+- Motorola i1
198+- Motorola Spice XT300
199+- Motorola Quench XT5 XT502
200+- Pandigital Novel
201+- Samsung GT-S5570 Galaxy Mini
202+- Samsung i5500 Galaxy 5 (Corby)
203+- Samsung i5700 Galaxy Portal (Spica)
204+- Samsung i5800 Galaxy 3
205+- Samsung i7500 Galaxy
206+- Samsung Intercept
207+- Samsung M900 Moment
208+- Samsung S5830 Galaxy Ace
209+- Samsung Transform
210+- Sanyo ZIO M6000
211+- Sony Ericsson Xperia X8
212+- Sony Ericsson Xperia X10 Mini
213+- Sony Ericsson Xperia X10 Mini Pro
214+- Superpad 10.2" Tablet PC
215+- Viewsonic ViewPad 7 Tablet
216+- Velocity Micro T103 Cruz tablet
217+- Vodafone 845
218+- ZTE Blade
219+
220+### 폰에서 사운드와 비디오 재생하기
221+
222+각각의 폰은 서로 다른 코덱이 설치되어 있어서 네이티브 미디어플레이어가 폰에 따라 다른 포멧으로 플레이 할 수가 있다는 것을 의미한다. 다음은 각 폰의 네이티브 미디어 플레이어가 어떤 포맷을 플레이하는지 모여주는 표이다:
223+
224+| 전화기 | 안드로이드 | webm - VP8 | m4v - H.264 | ogv - Theora | mp4 - H.264 | mov - H.264 | avi - RLE | mpg - MPEG-1 | wmv - WM9 | 3gp - MPEG-4 |
225+|----|----|----|----|----|----|----|----|----|----|----|
226+| 에뮬레이터 | 1.6 | x | x | x | x | x | x | x | x | OK |
227+| 에뮬레이터 | 2.1 | x | x | x | x | x | x | x | x | OK |
228+| Nexus One | 2.2 | x | OK | x | OK | x | x | x | x | OK |
229+| HTC Desire | 1.6 | x | OK | x | OK | x | x | x | OK | OK |
230+| Toshiba Folio 100 | 2.2 | x | OK | x | OK | x | x | x | OK | OK |
231+| Xperia X10 | 2.1 | x | OK | x | x | x | x | x | OK | OK |
232+| Xperia X8 | 2.2 | x | OK | x | x | x | x | x | x | OK |
233+| HTC Wildfire | 2.1 | x | OK | x | x | x | x | x | x | OK |
234+| HTC Desire HD | 2.2 | x | OK | x | OK | x | x | x | x | OK |
235+| Galaxy Tab | 2.2 | x | OK | x | x | x | x | x | x | OK |
236+| myPhone A210 | 1.6 | x | OK | x | x | x | x | x | x | OK |
237+| Motorola Milestone | 2.1 | x | OK | x | x | x | x | x | OK | ? |
238+| Milestone 2 | 2.2 | x | OK | x | x | x | x | x | 사운드만 | OK |
239+
240+## 안드로이드 파일 시스템
241+
242+안드로이드는 어플리케이션이 데이터 디렉토리를 얻을 때 getApplicationContext().getFilesDir()의 사용을 추천하며 이 루틴은 HTC Wildfire에서는 /data/data/\<패키지 명\> 을 반환한다.
243+
244+어플리케이션의 네이티브 라이브러리는 /data/data/\<패키지\>/lib 에 위치한다.
245+
246+읽고 쓰고 새로운 파일을 생성하고 파일을 실행 시키기 좋은 곳은 /data/data/\<패키지 명\> 이다.
247+
248+## 새로운 Java 어플리케이션의 생성
249+
250+이 정보는 LCL-CustomDrawn-Android의 구현을 도와주는데 유용할 수 있다.
251+
252+일반적인 설명은 이곳에 있다: <http://developer.android.com/guide/developing/other-ide.html>
253+
254+### 가상 키보드를 보이고 / 숨기기
255+
256+이곳을 보세요: <http://android-codes-examples.blogspot.com/2011/11/show-or-hide-soft-keyboard-on-opening.html>
257+
258+나타내기:
259+
260+``` pascal
261+InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
262+imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
263+```
264+
265+키보드 감추기 위해서는:
266+
267+``` pascal
268+InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
269+imm.hideSoftInputFromWindow(singleedittext.getWindowToken(),0);
270+```
271+
272+## 안드로이드 JNI
273+
274+JNI (Java Native Interface)를 사용하여 대부분의 안드로이드 SDK API들과 다른 Java 라이브러리를 호출 할 수 있다.
275+
276+### Java 타입과 파스칼 JNI 타입에 대한 표
277+
278+인터페이스를 제외한 모든 Java 타입들은 JNI에서 문제없이 표시할 수 있다. 각각의 Java 타입에 대해 javaEnvRef^^.GetMethodID 과 같이 루틴에서 사용되는 VM 타입에 대응하는 것이 존재한다. 또한 JNI 네이티브 타입이 있으며, 이는 lazarus/lcl/interfaces/customdrawn/android/jni.pas 유닛에 선언되어 있고 파스칼로 작성된 JNI 코드에서 이용되는 타입이어야 한다. 파스칼에서 동등한 타입이 비교를 위해 제공 되며, JNI 코드를 작성할 때는 jni.pas 에서 선언된 타입이어야 한다.
279+
280+| Java Types | VM 시그너쳐 | jni.pas에서의 Types | 파스칼에서 | 설명 |
281+|----|----|----|----|----|
282+| boolean | Z | jboolean | Boolean | |
283+| byte | B | jbyte | Byte | |
284+| char | C | jchar | Word | |
285+| short | S | jshort | Shortint | |
286+| int | I | jint | Integer | |
287+| long | J | jlong | Int64 | |
288+| float | F | jfloat | Single | |
289+| double | D | jdouble | Double | |
290+| a class, ie: String or InputStream | L\<full class name\> ie: Ljava/lang/String; | jobject | N/A | |
291+| Array, ie: int\[\] | \[\<type-name\> ie: \[I | N/A | | |
292+| A method type | (arg-types)ref-type | JMethodID | N/A | |
293+| void | V | N/A | procedure | |
294+
295+### 예제 1: Java 오브젝트를 생성하고 Java 메서드를 호출하기
296+
297+다음 Java 코드에 대응하는 파스칼 JNI 코드를 원한다고 하자.
298+
299+``` java
300+ HttpGet javaRequest = new HttpGet();
301+ URI myURI = new URI("http://magnifier.sourceforge.net/");
302+ javaRequest.setURI(myURI);
303+```
304+
305+먼저 프로세스에 포함되는 모든 Class ID를 얻어야 한다. 그리고 나서 사용할 모든 메서드의 ID를 얻고 호출을 한다. 만약 호출이 파라메터를 가진다면, 배열로 전달한다. 다음 파스칼 네이티브 코드는 위의 Java 코드에 대응한다:
306+
307+``` pascal
308+uses jni, customdrawnint;
309+
310+var
311+ javaClass_HttpGet, javaClass_URI: jclass;
312+ javaMethod_HttpGet_new, javaMethod_HttpGet_setURI,
313+ javaMethod_URI_new: jmethodid;
314+ javaRequest, javaURI: jobject;
315+ javaString: jstring;
316+ lParams: array[0..2] of JValue;
317+ lNativeString: PChar;
318+begin
319+ DebugLn(':>LoadHTMLPageViaJNI');
320+ // 먼저 필요한 모든 클래스에 대하여 FindClass를 콜한다.
321+ javaClass_HttpGet := javaEnvRef^^.FindClass(javaEnvRef,
322+ 'org/apache/http/client/methods/HttpGet');
323+ javaClass_URI := javaEnvRef^^.FindClass(javaEnvRef,
324+ 'java/net/URI');
325+
326+ // 이제 모든 메서드 ID를 얻는다
327+ DebugLn(':LoadHTMLPageViaJNI 1');
328+ javaMethod_HttpGet_new := javaEnvRef^^.GetMethodID(javaEnvRef, javaClass_HttpGet, '<init>', '()V');
329+ javaMethod_HttpGet_setURI := javaEnvRef^^.GetMethodID(javaEnvRef, javaClass_HttpGet, 'setURI', '(Ljava/net/URI;)V');
330+ javaMethod_URI_new := javaEnvRef^^.GetMethodID(javaEnvRef, javaClass_URI, '<init>', '(Ljava/lang/String;)V');
331+
332+ // HTTP 응답 객체에 대한 새로운 인스턴스를 생성한다
333+ // HttpGet javaRequest = new HttpGet();
334+ javaRequest := javaEnvRef^^.NewObject(javaEnvRef,
335+ javaClass_HttpGet,
336+ javaMethod_HttpGet_new);
337+
338+ DebugLn(':LoadHTMLPageViaJNI 4 javaRequest='+IntToHex(PtrInt(javaRequest), 8));
339+ // 응답 객체에 URI를 추가한다
340+ // URI javaURI = new URI("http://magnifier.sourceforge.net/");
341+ lParams[0].l := javaEnvRef^^.NewStringUTF(javaEnvRef, 'http://magnifier.sourceforge.net');
342+ javaURI := javaEnvRef^^.NewObjectA(javaEnvRef,
343+ javaClass_URI, javaMethod_URI_new, @lParams[0]);
344+ javaEnvRef^^.DeleteLocalRef(javaEnvRef, lParams[0].l);
345+ // javaRequest.setURI(javaURI);
346+ lParams[0].l := javaURI;
347+ javaEnvRef^^.CallVoidMethodA(javaEnvRef, javaRequest,
348+ javaMethod_HttpGet_setURI, @lParams[0]);
349+```
350+
351+### 예제 2: 정적 메서드 호출
352+
353+Bass 클래스에 있는 다음 정적 메서드를 호출하기를 원한다고 하자. <http://jerome.jouvie.free.fr/nativebass/javadoc/org/jouvieje/bass/Bass.html>
354+
355+``` java
356+ public static native int BASS_StreamCreateFile(String file, long offset, long length, int flags);
357+```
358+
359+먼저 프로세스에 포함된 모든 Class ID를 얻고 정적 메서드의 ID를 얻으며 배열과 함께 파라메터를 넣어 호출한다:
360+
361+``` pascal
362+uses jni, customdrawnint;
363+
364+var
365+ javaClass_Bass: jclass;
366+ javaMethod_Bass_BASS_StreamCreateFile: jmethodid;
367+ javaString: jstring;
368+ lParams: array[0..3] of JValue;
369+ lRetInt: jint;
370+begin
371+ // 먼저 필요한 모든 클래스에 대하여 FindClass를 콜한다.
372+ javaClass_Bass := javaEnvRef^^.FindClass(javaEnvRef, 'org/jouvieje/bass/Bass');
373+
374+ // 모든 메서드 ID
375+ javaMethod_Bass_BASS_StreamCreateFile := javaEnvRef^^.GetStaticMethodID(javaEnvRef, javaClass_Bass, 'BASS_StreamCreateFile', '(Ljava/lang/String;JJI)I');
376+
377+ // 호출한다.
378+ lParams[0].l := javaEnvRef^^.NewStringUTF(javaEnvRef, '/path/to/file');
379+ lParams[1].j := 0; // 오프셋
380+ lParams[2].j := 200; // 길이
381+ lParams[3].i := 0; // 플래그
382+ lRetInt := javaEnvRef^^.CallStaticIntMethodA(javaEnvRef, javaClass_Bass, javaMethod_Bass_BASS_StreamCreateFile, @lParams[0]);
383+ javaEnvRef^^.DeleteLocalRef(javaEnvRef, lParams[0].l);
384+```
385+
386+## 참고
387+
388+- <http://developer.android.com/guide/developing/other-ide.html>
389+
390+---
391+*From the Free Pascal wiki, page "Android Programming/ko", as it stood on 2020-02-09 after a change by GAN, 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).*
392+Category: Android/ko

Back to history