(아래 내용은 델파이 10.2 도쿄 릴리즈 1과 릴리즈 2에서 작성된 내용으로 다른 버전에서는 일부 내용이 다를 수 있습니다.)

 

개발 컨설팅을 통해 의뢰한 작업 중 RFID 리더 연동한 내용 공유합니다.

(3일간의 개발 컨설팅으로 RFID 리더, TMAP 연동, 원격 데이터 연동 기술을 전파하는 작업을 진행했습니다.)

 

RFID 리더와 연동은 제조사에서 제공하는 라이브러리(안드로이드 JAR)를 이용했습니다.

이 과정을 통해 델파이에서 JAR 파일 연동하는 내용을 확인할 수 있습니다.

 

 

RFID 리더 연동

 

 

위 영상의 RFID 리더는 RFID 태그의 값을 읽고, 바코드의 값을 읽어 안드로이드 앱에 데이터를 전달합니다.

안드로이드 앱은 장비를 구동 및 설정하고, 장비가 읽은 데이터를 받아 화면에 표시합니다.

 

안드로이드 앱은 델파이(파이어몽키)를 이용해 개발했으며, 장비와 연동하는 부분은 제조사에서 제공한 JAR 형태의 라이브러리를 이용했습니다.

 

델파이에서 JAR 파일 연동 과정은 아래와 같습니다

1, 작업 준비

2, 델파이용 JAR 브릿지 파일 생성

3, 델파이 프로젝트에 JAR 파일 추가

4, 브릿지 파일로 JAR 연동 코드 작성

 

기타  참고사항

 - 안드로이드 연동 시 참고사항

 - 프레임을 이용해 재사용 가능한 화면 제작

샘플 프로젝트

 

 

작업 준비

대상 장비 - 한미IT RF Prisma

 

 

한미IT RF Prisma

제품 링크 : http://www.hanmiit.co.kr/hanmiit/handler/Main-Start

 

제품 문의

한미IT영업 임상기과장 skyoflsk@hanmi.co.kr

 

 

라이브러리 준비 및 분석

위 제품 링크 페이지에서 SDK Download 메뉴를 이용해 SDK 관련 파일을 제공합니다.

(안드로이드, iOS, 윈도우용 라이브러리를 제공합니다. 이글에서는 안드로이드 라이브러리만 다룹니다.)

 

다운로드 받은 압축파일에는 SDK 파일과 문서, 샘플이 포함되어 있습니다.

(앱스토어에서 RFPrisma로 검색 해 샘플 앱을 설치할 수 있습니다.)

문서와 샘플을 통해 제공하는 기능을 확인하고, 대략적인 사용법을 익히도록 합니다. 특히 라이브러리를 호출하는 부분은 정확히 숙지해야 합니다.

 

 

 

델파이용 JAR 브릿지 파일 생성

델파이에서 JAR 파일을 연동하기 위해 브릿지 파일(JAR 파일에 대한 델파이 인터페이스)을 생성해야 합니다.
 

브릿지 파일 생성

Java2OP.exe를 이용 델파이 브릿지 파일을 생성합니다. Java2OP는 JAR 파일 또는 Java 소스파일을 호출할 수 있는 델파이 코드를 생성합니다.(참고: 파이어몽키에서 외부 라이브러리 연동하기(jar. so, a))

 
아래 커맨드를 이용 브리지 파일(Androidapi.JNI.rfidreaderapi.pas)을 생성합니다.
1
2
3
set path=%PATH%;"c:\Program Files (x86)\Embarcadero\Studio\19.0\bin\converters\java2op"
 
java2op -jar ..\SDK\rfid.reader.api.jar -unit Androidapi.JNI.rfidreaderapi
위 코드를 명령 프롬프트에서 바로 입력 및 실행하거나, 배치파일(*.bat)로 실행할 수 있습니다.
(*.jar 파일의 경로를 상대경로로 입력 시 주의하시기 바랍니다. 절대경로를 이용해도 됩니다.)
 

델파이 프로젝트에 JAR 파일 추가

라이브러리 추가

멀티-디바이스 애플리케이션(파이어몽키) 프로젝트에서 타겟 플랫폼을 안드로이드로 설정 후 트리를 펼쳐 Libraries 항목에 JAR 파일을 추가해야 합니다.

 

델파이 브릿지 파일 추가

JAR와 연동하기 위해 델파이 브릿지 파일(Androidapi.JNI.rfidreaderapi.pas)을 프로젝트에 추가합니다.

브릿지 파일 확인을 위해 컴파일 후 오류를 조치합니다.

 

만약, 컴파일 시 E2029 오류 발생 시 다음을 참고해 조치합니다.

E2029 오류 조치방법

 

E2029 오류는 예약어를 용도와 다른 곳에서 사용할 경우 발생합니다.

오류가 발생하는 예약어 키워드 앞에 "&"을 추가해 해결합니다.

(예> type -> &type, in -> &in)

(참고: http://tech.devgear.co.kr/delphi_qna/420082)

 

브릿지 파일로 JAR 연동 코드 작성

JAR와 연동하는 코드는 아래와 같이 클래스를 이용해 작성했습니다.

 FMX.HanmiIT.RFIDReader.pas

 

구현한 내용 중 다음 내용을 살펴보겠습니다.

1, 인스턴스 메소드와 클래스 메소드 접근

2, 자바 이벤트 리스너 설정

인스턴스 메소드와 클래스 메소드 접근

RF Prisma JAR 라이브러리에는 독특하게 클래스 메소드를 많이 사용하도록 구현되어 있습니다.

 

연동 시 델파이 클래스(TJATRfidManager)는 클래스 인터페이스(JATRfidManagerClass)와 객체 인터페이스(JATRfidManager) 쌍으로 이뤄집니다. 

JATRfidManagerClass 인터페이스는 클래스 함수와 속성, 상수를 제공합니다.(객체 생성 전 사용)
JATRfidManager 인터페이스는 인스턴스 함수와 속성 상수를 제공합니다.(객체 생성 후 사용)
 
이 라이브러리에는 객체(JATRfidReader 등) 생성 시 아래와 클래스 메소드를 이용합니다. 해당 객체의 추가 기능은 인스턴스 메소드로 제공합니다.
1
2
3
4
5
6
7
8
9
var
  FReader: JATRfidReader;
...
  FReader := TJATRfidManager.JavaClass.getInstance;
 
  FReader.setEventListener(FEventListener);
  FReader.connectDevice(StringToJString(AAddress));
  FReader.setStoredMode(Value);
  FReader.setReportMode(Value);
 

자바 이벤트 리스너 설정

연동 시 가장 우려하던 부분입니다. RFID 태그를 읽거나 연결상태 가 변경되는 등 장비에서 동작해 발생하는 이벤트 정보를 리스너(JATRfidEventListener)를 통해 앱에서 받습니다.

 

리스너 구현시 메인 클래스(TRfidReader)에서 바로 리스너 인터페이스를 위임받아 구현해도 되지만, 복잡해 지기 때문에 별도의 클래스에서 이벤트 리스너를 구현하고 필요한 정보만 받도록  분리해 구현했습니다.

 

이벤트 리스너 구현 선언부

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type
  TRfidEventListner = class(TJavaLocal, JATRfidEventListener)
  private
    FHandler: IRfidEventHandler;
  public
    constructor Create(AHandler: IRfidEventHandler);
 
    { JATRfidEventListenerClass }
    procedure onAccessResult(P1: JATRfidReader; P2: Jtype_ResultCode; P3: JActionState; P4: JString; P5: JString; P6: Single; P7: Single); cdecl;
    procedure onActionChanged(P1: JATRfidReader; P2: JActionState); cdecl;
    procedure onCommandComplete(P1: JATRfidReader; P2: JCommandType); cdecl;
    procedure onDebugMessage(P1: JATRfidReader; P2: JString); cdecl;
    procedure onDetactBarcode(P1: JATRfidReader; P2: JBarcodeType; P3: JString; P4: JString); cdecl;
    procedure onLoadTag(P1: JATRfidReader; P2: JString); cdecl;
    procedure onReadedTag(P1: JATRfidReader; P2: JActionState; P3: JString; P4: Single; P5: Single); cdecl;
    procedure onRemoteKeyStateChanged(P1: JATRfidReader; P2: JRemoteKeyState); cdecl;
    procedure onStateChanged(P1: JATRfidReader; P2: JConnectionState); cdecl;
  end;

 

위와 같이 JTARfidEventListener 인터페이스를 위임받고, 해당 인터페이스의 함수를 정의합니다.

 

주의할 사항은 Create 메소드의 파라메터로 IRfidEventHandler 인터페이스를 받아 FHandler에 저장하도록 구현합니다.

 

델파이 이벤트 인터페이스 선언부

IRfidEventHandler는 아래와 같이 필요한 메소드만 정의했습니다. 특히 파라메터는 사용하기 편하도록 델파이 자료형으로 재정의 했습니다.

 

1
2
3
4
5
6
7
8
9
10
11
type
  IRfidEventHandler = interface
  ['{FFEB910C-3BB8-48CA-BE11-B09CC07E53AC}']
    // Rfid Reader
    procedure ReadedTag(AReader: JATRfidReader; ATag: string);
    procedure StateChagned(AReader: JATRfidReader; AState: TConnectionState);
 
    // Barcode
    procedure ActionChagned(AReader: JATRfidReader; AState: TActionState);
    procedure DetactBarcode(AReader: JATRfidReader; ABarcodeType, ACodeId, ABarcode: string);
  end;<p></p>
 
메인 클래스에서 델파이 이벤트 인터페이스 위임
위 인터페이스는 메인 클래스에서 위임받았고, 이벤트 핸들러 생성 시 파라메터로 전달합니다.
그리고, FReader 객체에 이벤트 리스너를 설정(setEventListener)합니다.
1
2
3
4
5
6
7
8
9
10
11
type
  TRFIDReader = class(TInterfacedObject, IRfidEventHandler)
...
procedure TRFIDReader.InitReader;
begin
...
  FEventListener := TRfidEventListner.Create(Self);
...
  FReader := TJATRfidManager.JavaClass.getInstance;
  FReader.setEventListener(FEventListener);
end;
 
이벤트 발생 시 델파이 이벤트 인터페스를 통해 전달
JATRfidEventListener에서 이벤트 발생 시 IRfidEventHandler에 이벤트를 전달하도록 구현했습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
procedure TRfidEventListner.onStateChanged(P1: JATRfidReader;
  P2: JConnectionState);
var
  State: TConnectionState;
begin
  if Assigned(FHandler) then
  begin
    State := TConnectionState.Disconnected;
    if P2.getState = TJConnectionState.JavaClass.Connected.getState then
      State := TConnectionState.Connected
    else if P2.getState = TJConnectionState.JavaClass.Connecting.getState then
      State := TConnectionState.Connecting
    else if P2.getState = TJConnectionState.JavaClass.Listen.getState then
      State := TConnectionState.Listen
    ;
 
    FHandler.StateChagned(P1, State);
  end;
end;
 
이후 이벤트 정보를 받은 메인 클래스에서 비지니스 로직을 수행하도록 구현합니다.

기타 참고사항

안드로이드 연동 시 참고사항

가장 좋은 참고자료는 파이어몽키에 구현된 안드로이드 연동한 내용을 참고하는 것입니다.

(델파이 정품 설치 시 설치경로 하위의 source 디렉토리에는 파이어몽키 라이브러리 소스코들이 포함되어 있습니다.)

 

그중 다음 소스코드들을 참고하면 아주 좋습니다.

 

안드로이드 SDK 브릿지 파일

기본 안드로이드 SDK 델파이 브릿지 파일이 아래 경로에 포함되어 있습니다.
  • C:\Program Files (x86)\Embarcadero\Studio\19.0\source\rtl\android - 10.2 도쿄 기준

파이어몽키 라이브러리

파이어몽키 컴포넌트와 라이브러리 등을 어떻게 구현했는지 아래 경로의 파일들에서 살펴볼 수 있습니다.

  • C:\Program Files (x86)\Embarcadero\Studio\19.0\source\fmx - 10.2 도쿄 기준

 

 

프레임을 이용해 재사용 가능한 화면 제작

일부 기능적인 화면들이 필요한데 다른 프로젝트에서도 활용할 만한 기능들이어서 재사용 가능하도록 구현해봤습니다.

libs 디렉토리에 포함된 3개의 프레임입니다.

  • FMX.UI.OverflowMenu.pas - 메인 화면의 우측 상단의 연결 팝업 메뉴 구현
  • FMX.UI.SelectBluetoothDeviceDialog.pas - 블루투스 장비를 탐색 후 장비 선택 정보 제공하도록 구현
  • FMX.UI.WaitDialog.pas - 비동기로 진행하는 블루투스 장비 연결을 기다리는 화면
프레임을 사용한 이유는 화면의 일부 영역을 표현하기 위함입니다.
프레임은 화면을 포함한 객체입니다.(Create, Destroy, Show, Hide 이벤트 등을 제공하지 않아 필요한 경우 직접 구현해야 합니다.)
화면등에서 객채 생성하는 코드를 줄이기 위해 클래스 메소드로 기능 호출하도록 구현했습니다.
 
클래스 메소드로 기능화면 호출
위 유닛 파일을 유즈절(uses)에 추가 후 아래와 같이 기능을 호출할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
TWaitDialog.Show('블루투스를 활성화 합니다.', 2000);
 
TOverflowMenu.Settings.Top := ToolBar1.Height + 1;
TOverflowMenu.Settings.Width := Width * 0.9;
TOverflowMenu.Settings.RightPadding := 10;
TOverflowMenu.ShowMenu([
    'Connect to last bluetooth device',
    'Connect to new bluetooth device'],
  procedure(AIndex: Integer; AText: string)
  begin
    case AIndex of
      0: ConnectToLastDevice;
      1: ConnectToNewDevice;
    end;
  end);
 
자세한 별도의 글을 통해 소개하도록 하겠습니다.(그 전에는 직접 소스코드를 통해 내용을 확인하시기 바랍니다.)

기타 궁금한 내용은 댓글 또는 http://blog.hjf.pe.kr/482의 댓글을 참고하거나 등록해 주세요.

번호 제목 글쓴이 날짜 조회 수
공지 [DelphiCon 요약] 코드사이트 로깅 실전 활용 기법 (Real-world CodeSite Logging Techniques) 관리자 2021.01.19 25115
공지 [UX Summit 요약] 오른쪽 클릭은 옳다 (Right Click is Right) 관리자 2020.11.16 23412
공지 [10.4 시드니] What's NEW! 신기능 자세히 보기 관리자 2020.05.27 25406
공지 RAD스튜디오(델파이,C++빌더) - 고객 사례 목록 관리자 2018.10.23 31315
공지 [데브기어 컨설팅] 모바일 앱 & 업그레이드 마이그레이션 [1] 관리자 2017.02.06 32307
공지 [전체 목록] 이 달의 기술자료 & 기술레터 관리자 2017.02.06 27730
공지 RAD스튜디오(델파이, C++빌더) - 시작하기 [1] 관리자 2015.06.30 48786
공지 RAD스튜디오(델파이,C++빌더) - 모바일 앱 개발 사례 (2020년 11월 업데이트 됨) 험프리 2014.01.16 185752
823 [업데이트][10.2 도쿄][릴리즈 3] 10.2 도쿄 - 릴리즈 3 출시 & 설치방법 안내 관리자 2018.03.14 1244
822 이 달의 기술자료 - 2018년 03월 file 험프리 2018.02.23 841
821 [발표자료] 2018022 마이크로서비스 아키텍처 구현과 활용 with RAD서버 file 관리자 2018.02.23 499
820 [업데이트][핫픽스][10.2.2] RTL 호환성패치 및 안드로이드 애니메이션 문제 해결 - 2018년 2월 패치 file 험프리 2018.02.20 626
819 개발자가 고민하는 마이그레이션 논쟁 해소를 위한 7가지 핵심 방안 관리자 2018.02.19 1449
818 [고객사례-UI컴포넌트 개발도구, 델파이] 페트라 (Petra) 관리자 2018.02.01 1303
817 이 달의 기술자료 - 2018년 02월 file 험프리 2018.01.25 571
816 [업데이트][핫픽스][10.2.2] 웰컴 페이지 패치 험프리 2018.01.25 550
815 2017년 가장 많이 클릭된 기술자료 TOP 7 관리자 2018.01.23 1306
814 [발표자료] 2018011 What's NEW! RAD스튜디오 10.2.2 관리자 2018.01.18 478
813 이 달의 기술자료 - 2018년 01월 험프리 2017.12.28 640
» RFID 리더(한미IT RF Prisma) 연동하기 - 델파이에서 JAR 이용 [1] 험프리 2017.12.19 1753
811 TFrame의 생성 및 해제를 편하게 해주는 TFrame 관리 클래스입니다.. file 푸른솔 2017.12.15 2029
810 [10.2 도쿄][릴리즈2] 기타 10.2.2에서 추가 강화된 내용 file 험프리 2017.12.13 802
809 [10.2 도쿄][릴리즈2] RAD 서버 싱글 사이트 라이선스 제공 험프리 2017.12.13 730
808 [10.2 도쿄][릴리즈2] 새로운 VCL 컨트롤 4종을 사용할 수 있습니다. file 험프리 2017.12.13 933
807 [10.2 도쿄][릴리즈2] FireMonkey 퀵에디트로 주요 속성을 시각적으로 빠르게 설정할 수 있습니다. file 험프리 2017.12.13 471
806 [10.2 도쿄][릴리즈2] IDE 룩앤필이 새로워졌습니다. - 다크테마 지원, 컴포넌트 아이콘 변경 file 험프리 2017.12.13 883
805 [업데이트][10.2 도쿄][릴리즈 2] 10.2 도쿄 - 릴리즈 2 출시 & 설치방법 안내 file 험프리 2017.12.13 1858
804 [고객사례-설치도구, 델파이] RAD 안드로이드 관리자 2017.12.06 606