안드로이드 API를 파이어몽키에서 사용방법을 공유합니다. 제가 이해한 내용 기반으로 작성해서 틀린부분이 있을 수 있으니 혹시 틀린부분이 보이시면 댓글달아 주세요.

안드로이드 API 사용을 위해 파이어몽키로 변환할 대상은 안드로이드 Toast를 기반으로 설명하겠습니다.

Toast는 아래의 그림과 같이 하단에 잠시 나타났다가 사라지는 메시지입니다. 파이어몽키에는 제공하지 않습니다.


Screenshot_2013-12-15-23-17-55.png


  • 샘플에서는 아래의 기능을 포함합니다.
    • 기본 위치(하단)에 Toast 메시지 표시
    • 지정된 위치에 Toast메시지 표시
    • 소스코드는 Github에 공개했습니다.
      • https://github.com/hjfactory/FMX.Devgear/tree/master/Samples/Android_Toast


설명은 아래의 순서대로 진행하겠습니다.

1, 안드로이드 API 문서확인
2, 파이어몽키에서 안드로이드 API 접근 시 구성
3, 안드로이드 API 컨버팅
4, 사용법 및 샘플코드

| 안드로이드 API 문서확인


변환할 대상인 Toast의 안드로이드 문서는 아래 링크에서 확인 할 수 있습니다.

위쪽 문서는 API 문서구요, 아래의 문서는 샘플코드 문서입니다.
Toast | Android Developers 2013-12-16 10-55-30 copy.jpg

우선 위의 API문서를 보시면 대략 아래와 같은 단락으로 구성되어있으니 숙지해 주시구요.
  • Contants
  • Public Constructors
  • Public Methods - 
  • Inherited Methods
  • Fields(Toast에서는 미사용)


| 파이어몽키에서 안드로이드 API 접근 시 구성


unit Android.JNI.Toast;
 
interface
 
{$IFDEF ANDROID}
uses
  Androidapi.JNIBridge,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI.GraphicsContentViewText;
 
type
  JToast = interface;
 
  JToastClass = interface(JObjectClass)
  ['{F227353E-DCE9-404B-8129-6B1BEFE68151}']
    {Property methods}
    function _GetLENGTH_LONG: Integer; cdecl;
    function _GetLENGTH_SHORT: Integer; cdecl;
    {Methods}
    function init(context: JContext): JToast; cdecl; overload;
    function makeText(context: JContext; text: JCharSequence;
      duration: Integer): JToast; cdecl;
    {Properties}
    property LENGTH_LONG: Integer read _GetLENGTH_LONG;
    property LENGTH_SHORT: Integer read _GetLENGTH_SHORT;
  end;
 
  [JavaSignature('android/widget/Toast')]
  JToast = interface(JObject)
  ['{FC9B3DFD-38CC-4693-9F11-7F3E3647683F}']
    {Methods}
    procedure cancel; cdecl;
    function getDuration: Integer; cdecl;
    function getGravity: Integer; cdecl;
    function getHorizontalMargin: Single; cdecl;
    function getVerticalMargin: Single; cdecl;
    function getView: JView; cdecl;
    function getXOffset: Integer; cdecl;
    function getYOffset: Integer; cdecl;
    procedure setDuration(value: Integer); cdecl;
    procedure setGravity(gravity, xOffset, yOffset: Integer); cdecl;
    procedure setMargin(horizontalMargin, verticalMargin: Single); cdecl;
    procedure setText(s: JCharSequence); cdecl;
    procedure setView(view: JView); cdecl;
    procedure show; cdecl;
  end;
  TJToast = class(TJavaGenericImport) end;
{$ENDIF}
 
implementation
 
end.
파이어몽키에서 Android API 사용하기 위해서는 JavaClass영역(JToastClass)과 JavaInterface영역(JToast)으로 구성 후 
실제 파이어몽키에서 사용할 수 있는 Class(TJToast)로 Generic형태로 Import해 사용합니다.
  • JToastClass - JavaClass interface
  • JToast - JavaInterface interface
  • TJToast - Delphi에서 사용할 Class

위와 같이 구성하기 위해서는 아래의 Unit들이 사용(uses)됩니다.
  • Androidapi.JNIBridge
  • Androidapi.JNI.JavaTypes
  • Androidapi.JNI.GraphicsContentViewText


| 안드로이드 API 컨버팅


델파이에서 구현할 부분은 크게 JavaClass와 JavaInterface입니다.

안드로이드 API문서를 보며 어느 부분을 JavaClass와 JavaInterface에 구현할지에 대해 알아보겠습니다.


Toast | Android Summury 2013-12-16 11-51-03 copy.jpg


위 그림의 붉은색 사각형에 포함된 내용이 JavaClass에 포함되고 나머지는 JavaInterface에 포함됩니다.


JavaClass 구현 할 항목


JToast = interface;
 
JToastClass = interface(JObjectClass)
['{F227353E-DCE9-404B-8129-6B1BEFE68151}']
  {Property methods}
  function _GetLENGTH_LONG: Integer; cdecl;
  function _GetLENGTH_SHORT: Integer; cdecl;
  {Methods}
  function init(context: JContext): JToast; cdecl; overload;
  function makeText(context: JContext; text: JCharSequence;
    duration: Integer): JToast; cdecl;
  {Properties}
  property LENGTH_LONG: Integer read _GetLENGTH_LONG;
  property LENGTH_SHORT: Integer read _GetLENGTH_SHORT;
end;


  • Inherited Methods
    • JToastClass = interface(JObjectClass)와 같이 안드로이드 API에 기술된대로(java.lang.Object) interface를 상속받아 사용합니다.
  • Constants(상수)
    • 안드로이드 API 상수는 Properties로 구성되며 read 절에 _Get을 추가하여 선언됩니다.
    • 만약, END, BEGIN과 같은 상수는 &END, &BEGIN과 같이 &를 앞에 추가하여 구성됩니다.
    • Property methods에 _Get이 포함된 read 함수가 선언되며 호출규칙은 cdecl으로 지정합니다.
  • Public Constructors(생성자)
    • 생성자는 init();로 선언되며, 안드로이드의 인자를 그대로 선언해 줍니다.
      (JContext 등의 클래스는 이미 엠바카데로에서 선언(Androidapi.JNI.GraphicsContentViewText)해 놓았으니 매번 구현할 필요없이 잘 찾아서 사용하면 될것 같네요.)
    • 생성자도 cdecl로 호출규칙을 지정하고, Init는 JObjectClass에서 이미 구현되었으므로 overload로 method를 분개합니다.
    • JavaInterface를 반환합니다.(그래서 JToast = interface;를 미리 선언해야 합니다.)
  • Public Methods(Static)
    • Public Methods에 나열된 메소드 중에서 static으로 선언된 메소드들은 JavaClass에 선언해야 합니다.
    • 저는 static으로 선언된 메소드 중 2번째인 CharSequence text가 2번째 인자로 들어간 메소드만 사용했습니다.
      (모든 메소드를 모두 구현해야 할 필요는 없습니다.)
JavaInterface 구현 할 항목
[JavaSignature('android/widget/Toast')]
JToast = interface(JObject)
['{FC9B3DFD-38CC-4693-9F11-7F3E3647683F}']
  {Methods}
  procedure cancel; cdecl;
  function getDuration: Integer; cdecl;
  function getGravity: Integer; cdecl;
  function getHorizontalMargin: Single; cdecl;
  function getVerticalMargin: Single; cdecl;
  function getView: JView; cdecl;
  function getXOffset: Integer; cdecl;
  function getYOffset: Integer; cdecl;
  procedure setDuration(value: Integer); cdecl;
  procedure setGravity(gravity, xOffset, yOffset: Integer); cdecl;
  procedure setMargin(horizontalMargin, verticalMargin: Single); cdecl;
  procedure setText(s: JCharSequence); cdecl;
  procedure setView(view: JView); cdecl;
  procedure show; cdecl;
end;
 
TJToast = class(TJavaGenericImport) end;

  • class path
    • 아래와 같이 API문서의 상단에서 class path를 확인하고 JavaSignature를 구성합니다.
      class_path.jpg
  • Inherited Methods
    • JavaInterface도 JObject를 상속받습니다.
  • Public methods
    • Public methods에서 static으로 선언된 항목을 제외하고 선언합니다.
    • 대부분의 자료형은 이미 Androidapi.JNI.JavaTypes에 선언되었으나 해당 Unit을 참고합니다.


마지막으로 JavaClass(JToastClass)와 JavaInterface(JToast)를 TJavaGernericImport 클래스를 이용해서 실제로 사용할 Delphi class를 선언할 수 있습니다.



| 사용법 및 샘플코드


var
  Toast: JToast;
begin
  CallInUiThread(procedure
  begin
    Toast := TJToast.JavaClass.makeText(SharedActivityContext, StrToJCharSequence(AMsg), TJToast.JavaClass.LENGTH_SHORT);
    Toast.show;
  end);
end;

위의 코드가 Toast 메시지를 화면에 출력하는 샘플코드입니다.

안드로이드 가이드 문서를 참고해서 만들었습니다.


안드로이드 API를 구현한 후에는

TJToast.JavaClass이후에 JavaClass에 선언된 메소드들을 호출하고 반환받은 객체에서 JavaInterface의 메소드를 사용할 수 있습니다.


그리고, CallInUiThread의 경우  UI와 관련된 경우 Thread 처리하지 않으면 화면이 얼어버리는 현상이 발생해서 추가했습니다.

(그냥 구현했더니 얼어버려서, 엠바카데로 소스를 참고했습니다.)


마치며

대부분의 안드로이드 API는 이미 엠바카데로에서 구현해 놓았습니다.

(C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\source\rtl\android 참고: 설치 기본경로 기준)


다만, 안드로이드에 특화된 기능등은 구현되지 않은 것이 있을 것입니다.

그럴경우 위에서 설명한 내용 참고하시면 충분히 포팅하여 사용할 수 있을것 같습니다.

(제 글이 도움이 되었으면 좋겠네요. 만약 어려운 부분이 있으시면 답글 주세요. 함께 고민해 보겠습니다.)


그럼 다음에는 iOS library 사용법이나 NDK 등의 글로 찾아뵙겠습니다.

감사합니다.


원글은 http://blog.hjf.pe.kr/102 입니다.

번호 제목 글쓴이 날짜 조회 수
공지 [DelphiCon 요약] 코드사이트 로깅 실전 활용 기법 (Real-world CodeSite Logging Techniques) 관리자 2021.01.19 12178
공지 [UX Summit 요약] 오른쪽 클릭은 옳다 (Right Click is Right) 관리자 2020.11.16 11777
공지 [10.4 시드니] What's NEW! 신기능 자세히 보기 관리자 2020.05.27 14192
공지 RAD스튜디오(델파이,C++빌더) - 고객 사례 목록 관리자 2018.10.23 19391
공지 [데브기어 컨설팅] 모바일 앱 & 업그레이드 마이그레이션 [1] 관리자 2017.02.06 20996
공지 [전체 목록] 이 달의 기술자료 & 기술레터 관리자 2017.02.06 16772
공지 RAD스튜디오(델파이, C++빌더) - 시작하기 [1] 관리자 2015.06.30 36446
공지 RAD스튜디오(델파이,C++빌더) - 모바일 앱 개발 사례 (2020년 11월 업데이트 됨) 험프리 2014.01.16 171790
7 QR 코드를 만들고 스캔(읽는) 방법 Humphery 2014.07.24 5136
6 [소식] Nokia X에서 델파이로 만든 앱도 등록가능합니다. [1] file Humphery 2014.03.11 4313
5 안드로이드 앱 서명 및 배포 file Humphery 2014.01.02 10234
4 파이어몽키에서 미디어 플레이어 개발 관련 Humphery 2013.12.18 6565
» 안드로이드 API를 파이어몽키에서 사용하기(Toast 메세지 구현) file Humphery 2013.12.17 6168
2 웹상의 이미지를 폼(TImage)에서 사용하는 방법 [3] file Humphery 2013.12.14 9921
1 Delphi XE2에서 맥 애플리케이션을 만들어 보자 박병일 2012.01.18 12909