(아래 내용은 델파이 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 브릿지 파일 생성
브릿지 파일 생성
Java2OP.exe를 이용 델파이 브릿지 파일을 생성합니다. Java2OP는 JAR 파일 또는 Java 소스파일을 호출할 수 있는 델파이 코드를 생성합니다.(참고: 파이어몽키에서 외부 라이브러리 연동하기(jar. so, a))
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
델파이 프로젝트에 JAR 파일 추가
라이브러리 추가
델파이 브릿지 파일 추가
JAR와 연동하기 위해 델파이 브릿지 파일(Androidapi.JNI.rfidreaderapi.pas)을 프로젝트에 추가합니다.
브릿지 파일 확인을 위해 컴파일 후 오류를 조치합니다.
만약, 컴파일 시 E2029 오류 발생 시 다음을 참고해 조치합니다.
E2029 오류 조치방법
E2029 오류는 예약어를 용도와 다른 곳에서 사용할 경우 발생합니다.
오류가 발생하는 예약어 키워드 앞에 "&"을 추가해 해결합니다.
(예> type -> &type, in -> &in)
브릿지 파일로 JAR 연동 코드 작성
인스턴스 메소드와 클래스 메소드 접근
연동 시 델파이 클래스(TJATRfidManager)는 클래스 인터페이스(JATRfidManagerClass)와 인스턴스 인터페이스(JATRfidManager) 쌍으로 이뤄집니다.
클래스 인터페이스(JATRfidManagerClass)는 객체를 생성하기 전의 클래스를 통해 접근하는 함수, 속성, 상수를 제공합니다. 자바코드를 사용하는 경우 "델파이클래스명.JavaClass.클래스메소드" 형식으로 JavaClass 속성을 통해 자바 클래스에 접근해야 합니다.
var FReader: JATRfidReader; ... FReader := TJATRfidManager.JavaClass.getInstance; FReader.setEventListener(FEventListener); FReader.connectDevice(StringToJString(AAddress)); FReader.setStoredMode(Value); FReader.setReportMode(Value);
자바 이벤트 리스너 설정
연동 시 가장 우려하던 부분입니다. RFID 태그를 읽거나 연결상태 가 변경되는 등 장비에서 동작해 발생하는 이벤트 정보를 리스너(JATRfidEventListener)를 통해 앱에서 받습니다.
리스너 구현시 메인 클래스(TRfidReader)에서 바로 리스너 인터페이스를 위임받아 구현해도 되지만, 복잡해 지기 때문에 별도의 클래스에서 이벤트 리스너를 구현하고 필요한 정보만 받도록 분리해 구현했습니다.
이벤트 리스너 구현 선언부
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는 아래와 같이 필요한 메소드만 정의했습니다. 특히 파라메터는 사용하기 편하도록 델파이 자료형으로 재정의 했습니다.
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;
type TRFIDReader = class(TInterfacedObject, IRfidEventHandler) ... procedure TRFIDReader.InitReader; begin ... FEventListener := TRfidEventListner.Create(Self); ... FReader := TJATRfidManager.JavaClass.getInstance; FReader.setEventListener(FEventListener); end;
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 브릿지 파일
- 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 - 비동기로 진행하는 블루투스 장비 연결을 기다리는 화면
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의 댓글을 참고하거나 등록해 주세요.