Search results for '파이어몽키'

  1. 2014.12.01 -- 파이어몽키 iOS 네이티브 컴포넌트(오픈소스) - DPF
  2. 2014.12.01 -- 엔터프라이즈 DBMS에 직접 접속할 수 있는 방법(컴포넌트 소개)
  3. 2014.11.25 -- 구글 매터리얼 아이콘 753종
  4. 2014.11.21 -- 안드로이드 라이브러리(jar 파일) 활용 사례(안드로이드 열기 대화상자 구현)
  5. 2014.11.10 -- [앱테더링] VCL앱을 모바일앱으로 쉽게 확장할 수 있는 앱테더링 자세히 살펴보기! (7)
  6. 2014.11.05 -- 여러분의 앱에서 클라우드 서비스에 연결하세요.(REST Client이용)
  7. 2014.11.05 -- 동영상강좌) 코드아카데미: 앱개발에 집중하고, 백엔드는 클라우드에 맡기세요!
  8. 2014.11.05 -- 블루투스 LE와 클라우드를 이용한 수화물 무게 기록 앱 샘플
  9. 2014.11.04 -- 안드로이드 기기에 설치된 앱 목록표시와 실행하기
  10. 2014.11.04 -- RAD Studio XE7에서 추가된 안드로이드 기능 익히기(동영상)
  11. 2014.11.04 -- RAD Studio XE7의 TListView에서 당겨서 새로고침 구현 샘플 (1)
  12. 2014.11.03 -- 파이어몽키 커스텀 스타일 제작 따라하기 (1)
  13. 2014.11.03 -- [XE7] 안드로이드 브릿지 파일을 생성할 수 있는 Java2OP.exe을 다운로드 하세요.
  14. 2014.10.24 -- 웹브라우저를 지원하지 않는 플랫폼(윈도우, OS X)에서 웹브라우저 지원하기
  15. 2014.10.22 -- FMX 리스트박스를 정렬하고 필터링하는 내용 설명
  16. 2014.10.21 -- 내가 원하는 이름으로 모바일 앱의 이름 변경하기
  17. 2014.10.20 -- "나의 도서관 앱" 개발 따라하기 - (2) 데이터베이스 만들기, 실제 데이터 연결 (9)
  18. 2014.10.17 -- 재사용 가능한 프레임으로 UI 구현하기(사진, 웹페이지)
  19. 2014.10.16 -- "나의 도서관 앱" 개발 따라하기 - (1) 사용자화면 만들기와 기능 구현하기
  20. 2014.10.15 -- [XE7] 안드로이드에서 MessagDlg 사용방법(주의 점) (1)

파이어몽키 iOS 네이티브 컴포넌트(오픈소스) - DPF

2014.12.01 10:35

파이어몽키 멀티-디바이스 앱 개발의 장점은 하나의 소스코드로 여러개의 플랫폼을 개발할 수 있다는 것입니다.

그리고, 또다른 장점은 필요한 경우 네이티브 API와 SDK를 사용할 수 있다는 장점도 있습니다.


위 장점을 최대한 활용한 오픈소스 프로젝트를 소개합니다.

이 오픈소스 프로젝트에서는 iOS 네이트브 기능(SDK, API)를 이용해 네이티브 UI와 기능을 갖는 컴포넌트를 제공합니다.

만약, 안드로이드 전용 앱을 만드는 경우 해당 오픈소스를 활용한다면, 기본 컴포넌트 외에도 더 풍부한 컴포넌트를 이용해 앱을 만들 수 있습니다.


Some Wrapped Frameworks:
* AddressBookUI.framework
* AddressBook.framework
* iAd.framework
* EventKit.framework
* GameKit.framework
* MapKit.framework
* MessageUI.framework
* MobileCoreServices.framework
* QuickLook.framework
* SystemConfiguration.framework
* Social.framework
* StoreKit.framework
* WebKit.framework

그리고, XE5 부터 꾸준히 업그레이드를 제공하고 있는 것도 큰 장점으로 꼽을 수 있습니다.

저작자 표시 비영리 동일 조건 변경 허락
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

험프리.김현수 험프리.김현수 파이어몽키 dpf, ios, 네이티브, 컴포넌트

엔터프라이즈 DBMS에 직접 접속할 수 있는 방법(컴포넌트 소개)

2014.12.01 10:13

모바일 앱에서 엔터프라이즈 DBMS(SQL Server, Oracle, Interbase Server 등)에 접속하기 위해서는 멀티티어 기술을 이용하는 것이 효과적입니다.


모바일 앱은 모바일 특성상 작은 하드웨어 자원을 사용하고, 연결이 보장되지 않은 네트워크를 이용합니다.

그래서 앱에서는 필요한 최소한의 데이터만 받아 처리하는 것이 효과적이고, 언제 끊어 질지 모르는 네트워크 상에서 트랜젝션을 처리하기 위해서는 예외처리에 많은 노력이 들어갈 것입니다.


위의 이유로 모바일에서 엔터프라이즈 데이터 이용을 위해서는 멀티티어 환경으로 서버에서 모바일을 관리하는 것이 효과적입니다. 

델파이를 이용한 모바일 앱에서는 데이터 스냅 또는 REST 클라이언트 기술을 이용해 멀티티어를 이용할 수 있습니다.


하지만, 

네트워크 연결이 보장된 일부 환경에서는 2티어 방식으로 모바일 앱에서 직접 DBMS에 접속할 수는 몇가지 방안이 있습니다.


첫째, FireDAC 컴포넌트를 이용해 InterBase Server에 접속 할 수 있습니다.

둘째, ODAC, SDAC 등의 외부 컴포넌트를 이용해 TCP/IP 기반으로 각 서버 컴포넌트를 이용할 수 있습니다.

저작자 표시 비영리 동일 조건 변경 허락
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

험프리.김현수 험프리.김현수 파이어몽키

구글 매터리얼 아이콘 753종

2014.11.25 22:24

구글에서 공개한 753종의 매터리얼 아이콘입니다. 모바일 앱 개발 시 유용하게 사용할 수 있습니다.



저작자 표시 비영리 동일 조건 변경 허락
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

험프리.김현수 험프리.김현수 파이어몽키 아이콘

안드로이드 라이브러리(jar 파일) 활용 사례(안드로이드 열기 대화상자 구현)

2014.11.21 10:35

파란크리스마스 블로그를 운영하시는 파란산타님께서 안드로이드 라이브러리를 활용해 열기 대화상자를 구현한 내용이 있어 공유합니다.(안드로이드 라이브러리 사용하는 내용을 아주 쉽게 정리해 주셨습니다.)


본문에서는 

파이어몽키의 안드로이드 플랫폼에서는 열기 대화상자(TOpenDialog)를 제공하지 않기 때문에 오픈소스인 android-file-dialog의 라이브러리(*.jar)를 이용해 열기 대화상자를 구현한 내용입니다.

(아래 내용을 참고하시면 직접 만든 안드로이드 라이브러리를 델파이에서 사용하는 방안을 익힐 수 있습니다.)


저작자 표시 비영리 동일 조건 변경 허락
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

험프리.김현수 험프리.김현수 파이어몽키

[앱테더링] VCL앱을 모바일앱으로 쉽게 확장할 수 있는 앱테더링 자세히 살펴보기!

2014.11.10 18:35

앱테더링(App Tethering)?

앱 테더링은 2개의 개별적인 앱을 서로 연결(테더링)해서 데이터를 주고 받을 수 있는 기술입니다.

앱테더링 기술을 이용해 VCL어플리케이션에서 모바일로 데이터를 제공하면 모바일에서 뷰어만 빠르게 만들어 아주 빠르고 쉽게 모바일앱을 개발할 수 있습니다.

(모바일 앱의 동작을 다시 VCL 앱으로 전송해 사용자의 액션과 모바일 이미지등을 VCL 앱에서 사용하면 더 강력한 시스템으로 탈바꿈할 수 있습니다.)

❑ 앱테더링 컴포넌트

앱 테더링은 TTetheringManager, TTetheringAppProfile 두개의 컴포넌트를 통해 구현할 수 있습니다. 이번글에서는 각 컴포넌트의 자세한 속성과 이벤트에 대해서는 다루지 않습니다. 하지만 아래의 "앱테더링 데모를 통해 기능 살펴보기" 단계를 보시면 주요한 대부분의 속성과 이벤트를 다루고 있기 때문에 충분히 기능을 익힐 수 있습니다.

더 자세히 알고 싶은 기능(속성, 이벤트)는 엠바카데로 기술 도움말(영문)을 통해서 익혀보시기 바랍니다.

아래는 앱테더링 기술이 제공하는 대표적인 속성입니다.

앱테더링의 대표 기능

  • 동일한 서브넷에서 동반자앱 자동탐색 기능(P2P기반으로 별도의 서버 구성이 필요하지 않습니다.)
  • 지정한 IP / 지정한 서브넷(192.168.1.0: 192.168.1.1 ~ 192.168.1.255)에서 탐색 시도
  • 블루투스 기반 앱테더링
  • String / Stream 기반 데이터 전송 기능 제공(Stream이므로 사실상 모든 데이터 전송 가능)
  • 동반자앱에 공개된 Action(명령)을 원격에서 호출하는 Remote Action 기능제공
  • VCL / FMX 2개의 프레임워크 지원
    • VCL 앱을 모바일과 연결해 쉽게 모바일로 전환/확장 할 수 있는 가능성 제공
    • 모바일에서 센서를 연결하면 VCL앱을 IoT로 바로 확장 가능
아래 데모영상을 통해 여러분들의 가능성을 만들어 보시기 바랍니다.

앱테더링 데모를 통해 기능 살펴보기

아래 데모영상은 VCL 어플리케이션을 모바일 앱으로 확장하기 위해 앱테더링 기술의 가장 기본적인 부분을 설명합니다. 

데모영상을 보시고 기능을 익히신 후 앱테더링 기능을 여러분의 프로젝트에 도입하면 어떤 기능을 확장할 수 있을지 생각해 보시고 여러분의 제품에 적용해보시기 바랍니다.


위 데모는 총 9개의 (최소한의 기능의)단계를 통해 진행합니다.

  • 탐색과 접속
    • 1단계, 동일 서브넷에서 접속대상 탐색시도
    • 2단계, 탐색된 테더링 매니저 표시
    • 3단계, 선택 매니저와 연결(페어링), 비밀번호 인증
    • 4단계, 탐색된 테더링 프로필 표시
    • 5단계, 선택 페어링과 연결(페어링)
  • 데이터 송수신
    • 6단계, 문자열 데이터 전송
    • 7단계, 데이터 수신하기(문자열, 스트림)
    • 8단계, 이미지(스트림) 데이터 전송
    • 9단계, 원격지에 정의된 액션(명령) 호출

1, 동일 서브넷에서 접속대상 탐색시도하기

테더링매니저의 DiscoverManagers 메소드를 통해 주변(동일 서브넷)의 동반자 앱을 탐색합니다.

procedure TForm2.btnDiscoverManagerClick(Sender: TObject);
begin
  InitControls;

  LogAndInfo('동일 서브넷에서 접속대상을 찾습니다.');
  // (#1) 주변에서 TetheringManager 발견명령
  TetheringManager.DiscoverManagers;

  // (#2) TetheringAppProfile의 Group 기반으로 자동 연결
//  TetheringManager.AutoConnect(3000);

  //  (#3) 대상을 지정해 접속할 수 있습니다.
//  TetheringManager.DiscoverManagers(3000, 127.0.0.1);
end;

AutoConnect(#2, TetheringAppProfile의 Group이 동일한 대상으로 자동 접속), 접속 대상을 지정(#3)등 다양한 접속 방식을 제공합니다.

2, 발견된 테더링 매니저 정보표시

탐색(DiscoverManagers)이 완료되면 TetheringManager의 OnEndManagersDiscovery 이벤트가 발생하고, ARemoteManagers 파라메터를 통해 탐색된 매니저정보를 제공합니다.

procedure TForm2.TetheringManagerEndManagersDiscovery(const Sender: TObject;
  const ARemoteManagers: TTetheringManagerInfoList);
var
  Info: TTetheringManagerInfo;
begin
  cbxRemoteManagers.Items.Clear;
  for Info in ARemoteManagers do
  begin
    Log(Format('[검색된 매니저]'#13#10#9'%s'#13#10#9'%s'#13#10#9'%s'#13#10#9'%s', [
      Info.ManagerIdentifier,
      Info.ManagerName,
      Info.ManagerText,
      Info.ConnectionString
    ]));
    cbxRemoteManagers.Items.Add(Format('%s(%s)', [Info.ManagerText, Info.ConnectionString]));
  end;
  if cbxRemoteManagers.Items.Count > 0 then
  begin
    cbxRemoteManagers.ItemIndex := 0;
    btnPairManager.Enabled := True;
  end;
  LogAndInfo(Format('접속 대상이 [%d]건 발견되었습니다.', [ARemoteManagers.Count]));
end;

3, 선택한 매니저와 연결(페어링)

접속할 대상 매니저를 선택 후 페어링(PairManager)을 시도합니다.

// 선택한 매니저와 연결
procedure TForm2.btnPairManagerClick(Sender: TObject);
var
  N: Integer;
begin
  if cbxRemoteManagers.ItemIndex < 0 then
    Exit;

  N := cbxRemoteManagers.ItemIndex;
  LogAndInfo(TetheringManager.RemoteManagers[N].ManagerText + ' - 매니저와 페어링 시도');
  TetheringManager.PairManager(TetheringManager.RemoteManagers[N]);
end;

// 매니저 비밀번호 설정
procedure TForm2.TetheringManagerRequestManagerPassword(const Sender: TObject;
  const ARemoteIdentifier: string; var Password: string);
begin
  Password := edtPassword.Text;

  TThread.Synchronize(TThread.CurrentThread,
    procedure begin
      LogAndInfo('[비밀번호 요청] - ' + edtPassword.Text);
    end);
end;

매니저간 페어링 시도 시 서로의 비밀번호를 통해 연결을 허용합니다. 만약 매니저간의 비밀번호가 맞지 않다면, TetheringManager 컴포넌트에서 인증오류(OnAuthErrorFromLocal, OnAuthErrorFromRemote) 이벤트가 발생하고 페어링은 실패합니다.

비밀번호는 TetheringManager.Password 속성을 통해서도 설정할 수 있습니다.

4, 발견된 테더링 프로필 정보표시

매니저간 연결(페어링)되면 TetheringManager의 OnEndProfilesDiscovery 이벤트가 발생되며 ARemoteprofiles 파라메터를 통해 탐색된 프로필 정보를 제공합니다.

// 프로필 발견완료 이벤트
procedure TForm2.TetheringManagerEndProfilesDiscovery(const Sender: TObject;
  const ARemoteProfiles: TTetheringProfileInfoList);
var
  Info: TTetheringProfileInfo;
begin
//  Log('TetheringManagerEndProfilesDiscovery');
  cbxRemoteProfiles.Items.Clear;
  for Info in ARemoteProfiles do
  begin
    Log(Format('[앱 프로필]'#13#10#9'%s'#13#10#9'%s'#13#10#9'%s'#13#10#9'%s'#13#10#9'%s', [
      Info.ManagerIdentifier,
      Info.ProfileIdentifier,
      info.ProfileText,
      Info.ProfileGroup,
      Info.ProfileType

    ]));
    cbxRemoteProfiles.Items.Add(Format('%s(%s)', [Info.ProfileText, Info.ProfileType]));
  end;
  if cbxRemoteProfiles.Items.Count > 0 then
  begin
    cbxRemoteProfiles.ItemIndex := 0;
    btnPairProfile.Enabled := True;
  end;
  LogAndInfo(Format('대상 프로필 [%d]건 발견되었습니다.', [ARemoteProfiles.Count]));
end;

5, 선택한 프로필과 연결

접속할 대상 프로필을 선택(TetheringAppProfile.Connect)하여 페어링 시도합니다.

// 선택한 프로필과 연결
procedure TForm2.btnPairProfileClick(Sender: TObject);
var
  N: Integer;
begin
  if cbxRemoteProfiles.ItemIndex < 0 then
    Exit;

  N := cbxRemoteProfiles.ItemIndex;
  LogAndInfo(TetheringManager.RemoteProfiles[N].ProfileText + ' - 프로필과 페어링 시도');
  if TetheringAppProfile.Connect(TetheringManager.RemoteProfiles[N]) then
  begin
    LogAndInfo('페어링 성공!!');
    InitControls;
  end;
end;

페어링이 완료되면 데이터 전송, 데이터 수신, 원격 액션 호출등의 작업이 가능해 집니다.

6, 문자열 전달

TetheringAppProfile.SendString 메소드를 통해 명령어, 데이터등의 문자열 데이터를 전달할 수 있습니다.

procedure TForm2.btnSendStrHelloClick(Sender: TObject);
begin
  LogAndInfo('문자열 전달 - 동반자 모바일앱에 Hello 전달');
  TetheringAppProfile.SendString(
    TetheringAppProfile.ConnectedProfiles.First,
    'HELLO',
    '안녕? App Tethering!!!');
end;

procedure TForm2.btnSendStrRSClick(Sender: TObject);
begin
  LogAndInfo('문자열 전달 - 동반자 모바일앱에 ReverseString 전달');
  TetheringAppProfile.SendString(
    TetheringAppProfile.ConnectedProfiles.First,
    'ReverseString',
    '반갑습니다.');
end;

SendString 메소드는 3개의 파라메터를 전달합니다.

  1. 전송할 앱 프로필 객체
  2. 수신 시 리소스의 힌트로 받을 수 있는 설명(Description)
  3. 문자열 데이터 값
ReverseString 문자열 데이터는 상대방(모바일 앱)에서 수신 시 글자를 뒤집어(반갑습니다. > .다니습갑반) 다시 전송하도록 구현되었습니다.

7, 데이터 수신

상대방 동반자앱에서 데이터를 보내면 TetheringAppProfile의 OnResourceReceived 이벤트를 통해 데이터를 수신할 수 있습니다. 문자열 데이터, 이미지 데이터(Stream)등이 모두 OnResourceReceived 이벤트를 통해 수신합니다.

procedure TForm2.TetheringAppProfileResourceReceived(const Sender: TObject; const AResource: TRemoteResource); begin case AResource.ResType of // 데이터(SendString) TRemoteResourceType.Data: begin // ReverseString을 받은 모바일에서 전송한 응답 if AResource.Hint = 'EchoString' then LogAndInfo('EchoString : ' + AResource.Value.AsString) end; // 스트림(SendStream) TRemoteResourceType.Stream: begin // 모바일에서 전송한 이미지 if AResource.Hint = 'FMXIMG' then begin LogAndInfo('이미지 수신'); LoadImage(AResource.Value.AsStream); end; end; end; end;

AResource 파라메터 주요 속성

  • AResource.ResType
    • SendString으로 전송 시 TRemoteResourceType.Data로 SendStream으로 전송 시 TRemoteResourceType.Stream으로 수신
  • AResource.Hint
    • SendString과 SendStream의 Description 파라메터에 입력한 값을 담고 있습니다.
  • AResource.Value
    • SendString과 SendStream의 Value(AString, AStream)에 입력한 값을 담고 있습니다.

8, 데이터 전달 - 이미지전송

이미지, 파일 등의 데이터를 TStream으로 변환해 동반자 앱으로 전달 할 수있습니다.(TStream은 TMemoryStream, TFileStream, TStringStream 등의 부모클래스이므로  다양한 데이터를 전달할 수 있습니다.)

procedure TForm2.btnSendStreamImageClick(Sender: TObject);
var
  Stream: TMemoryStream;
begin
  LogAndInfo('데이터 전달 - 이미지 데이터를 TStream으로 동반자 모바일앱에 전달');
  Stream := TMemoryStream.Create;
  try
    Image1.Picture.Graphic.SaveToStream(Stream);
      TetheringAppProfile.SendStream(TetheringManager.RemoteProfiles.First,
      'VCLIMG',
      Stream
    );
  finally
    Stream.Free;
  end;
  PageControl1.TabIndex := 2;
//  TetheringAppProfile.SendStream()
end;

9, 원격지의 명령 호출(이미지 전송 요청) 

TetheringAppProfile.RunRemoteAction 메소드를 통해 원격지에 공개된 Action을 실행 할 수 있습니다.

// 원격지의 액션 호출
procedure TForm2.btnRunRemoteActionClick(Sender: TObject);
begin
  LogAndInfo('원격 명령 호출 - 원격지(동방자 모바일 앱)의 ActionSendImg 액션 호출');
  TetheringAppProfile.RunRemoteAction(
    TetheringManager.RemoteProfiles.First,
    'ActionSendImg'
  );
  PageControl1.TabIndex := 3;
end;

모바일 앱의 TetheringAppProfile에는 Actions 속성에 아래와 같이 Action이 등록되어 있습니다.

TetheringAppProfile의 Actions에 등록된 Action(명령)은 외부로 공개(IsPublic)할 수 있어 외부에서 RunRemoteAction 메소드를 통해 호출할 수 있습니다.

❑ 위 데모 소스코드 받기

앱테더링 데모 더 살펴보기...

RAD Studio XE7의 샘플 프로젝트에는 아래의 다양한 앱테더링 데모가 있습니다.

  • 앱테더링 샘플 프로젝트 경로

    • C:\Users\Public\Documents\Embarcadero\Studio\15.0\Samples\Object Pascal\RTL\Tethering

❑ BDShoppingList

  • 앱테더링 기술을 이용해 데스크탑의 쇼핑 데이터를 모바일에 제공합니다.

  • 모바일 화면에서 쇼핑항목의 구매를 선택하면 구매명령을 데스크탑으로 전달해 구매처리를 완료합니다.

  • 데스크탑과 모바일은 변경된 데이터를 수시로 동기화합니다.

  • http://docwiki.embarcadero.com/CodeExamples/XE7/en/RTL.BDShoppingList_Sample

❑ DesktopCast

❑ MediaPlayer

❑ PhotoWall


참고 글




    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 파이어몽키 app tethering, Rad Studio, XE7, 앱테더링

    1. Blog Icon
      좋은남자

      이건 다른 질문인데요.. VCL 폼의 디자인이 깔끔한데.. 어디서 바꾸신 건가요? 데모 소스를 받아서 보니 Project - Option - Application - Appearance 에서 바꾸신 것 같지 않은데요..궁금합니다.

    2. VCL 스타일을 바꾼 것입니다. 해당 스타일은 프리미엄 스타일로 XE7 사용자들은 무료로 다운로드 및 사용할 수 있습니다.
      http://blog.hjf.pe.kr/253

    3. Blog Icon
      황영일

      안녕하세요. 반갑습니다. 앱테더링 데모에서 블루투스 아답터 설정하고 하면 접속대상를 찾지못합니다. 어떻게 하는지 알려주시면 감사 감사

    4. 혹시 페어링 하셨나요? 블루투스틑 페어링 된 상태에서 데이터를 주고 받을 수 있습니다.

    5. Blog Icon
      황영일

      블루투스 페어링도 해보았습니다. 안됩니다.
      network 테더링 하면 잘됩니다.
      아래것이 대한 것이 더궁금해서 몇자적습니다.
      클래식 블루투스및 블루투스 샘플을 테스트 하는데 페어링도 되고 서비스도 맞추었는데 소켓에 send하고 read할때 8바이트 보내면 read시 8바이트 길이가 나오는데 실제 데이터는 null입니다. xe7 샘플소스 그대로라 잘되야 될것 같은데 제가 뭘잘못했는지 이해가 되지 않습니다. 환경적인 요인인지 맨붕입니다. 도와주세요 ㅠㅠ

    6. Blog Icon
      푸름

      안녕하세요?
      항상 좋은 글 감사드립니다
      다름이 아니오라 앱테더링이라는게
      예제에서는 모바일과 윈도우인데
      모바일(안드로이드)-모바일(안드로이드)도 가능한가요?
      기본적으로 하고 싶은것은 다른 모바일의 특정폴더에서 이미지나 동영상을 가져오는걸 하고 싶습니다.

    7. 네 모바일과 모바일간에도 사용 가능합니다.

    여러분의 앱에서 클라우드 서비스에 연결하세요.(REST Client이용)

    2014.11.05 11:33

    최근 다양한 웹서비스와 클라우드에서 JSON 기반의 RESTFul 인터페이스를 제공합니다.


    오늘은 짐매키트가 발표한 동영상을 통해 REST 클라이언트로 클라우드 서비스에 연결하는 내용을 소개합니다.

    짐은 대표적인 클라우드 서비스인 드랍박스에 REST 클라이언트 라이브러리를 통해 모바일앱에서 연결하는 데모를 진행합니다.

    이 글에서는 아래 내용을 포함합니다.

    • 레스트 디버거(RESTFul 사이트 분석 도구)를 통한 웹사이트 분석
    • 클라우드 서비스(드랍박스) 연동
      • TOAuth1Authenticator 컴포넌트를 이용한 OAuth 1.0 인증과정 소개

    아래의 동영상을 통해 여러분의 앱에서 클라우드 서비스(드랍박스)에 연결하는 방법을 익혀 보시기 바랍니다.


    관련글


    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 파이어몽키

    동영상강좌) 코드아카데미: 앱개발에 집중하고, 백엔드는 클라우드에 맡기세요!

    2014.11.05 11:18

    지난 2014년 7월에 제가 진행했던 코드아카데미 동영상입니다.


    모바일 백엔드 서비스(BaaS)에 대한 개념과 사용하는 방법을 데모와 함께 진행합니다.

    여러분의 앱에 클라우드를 연결해 백엔드 개발에 대한 부담을 덜어보세요.


    총 4편으로 구성되었습니다.

    • BaaS와 Kinvey 자세히 알아보기
    • 사용자관리-사용자 인증과 관리방법
    • 클라우드 기반 스토리지
    • 푸쉬알림 사용하기




    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 파이어몽키 BAAS

    블루투스 LE와 클라우드를 이용한 수화물 무게 기록 앱 샘플

    2014.11.05 11:13

    여행을 할때 짐을 챙기는 것도 중요하지만 정해진 수화물 무게를 맞추는 것도 중요합니다.^^

    어떤 물품이 얼마나 나가는지 기록하면 수화물 무게를 계산할때 아주 유용하겠네요.


    이번 글에서는 블루투스 LE를 지원하는 저울(Wahoo Balace scale)과 연동해 수화물 무게를 얻어와 클라우드에 저장하는 모바일 앱을 RAD Studio XE7으로 만드는 샘플을 소개합니다.



    이 앱은 총 3개의 탭으로 구성되었습니다.

    • Weight Scale - 수화물 무게를 표시하고 수화물의 내용을 저장
    • Logged Data - 기존의 수화물 데이터를 검색하고 목록을 표시
    • Settings - 블루투스 데이터를 표시

    다양한 UI 구성요소와 TBluetoothLE 컴포넌트, BaaS 컴포넌트가 포함되었고 TStyleBook(custom jet style)을 이용해 스타일을 구성했습니다.

    • TKinveyProvider (AppKey, AppSecret, MasterSecret는 Kinvey.com의 계정과 연결) 
    • TBackendQuery (TKinveyProvider 연결) 
    • TBackendStorage (TKinveyProvider 연결) 
    • TRestResponseDataSetAdapter 
    • TFDMemTable



    이후의 화면 구성과 소스코드는 아래의 원문을 통해 확인하시기 바랍니다.


    클라우드 서비스(BaaS) 사용하는 방법은 아래 관련글의 동영상강좌를 들어보시면 많은 도움이 됩니다.


    관련글



    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 파이어몽키 샘플

    안드로이드 기기에 설치된 앱 목록표시와 실행하기

    2014.11.04 11:53

    파이어몽키 개발자 커뮤니티 네이버 카페(http://cafe.naver.com/delphifmx)에서 가을이다 님이 올려주신 내용입니다.

    (RAD Studio 모바일(멀티-디바이스) 개발에 관심이 있으시면 반드시 가입해야 하는 까페입니다. 가입하세요.)


    안드로이드 기기에 설치된 앱의 목록을 표시하고 앱을 실행하는 예제입니다.


    uses
      Androidapi.JNI.GraphicsContentViewText,
      Androidapi.JNI.JavaTypes,
      FMX.Helpers.Android,
      AndroidApi.Helpers,
      Androidapi.JNIBridge;
    
    // 중략
    
    var
      PM: JPackageManager;
      mainIntent: JIntent;
      LaunchIntent: JIntent;
      pkgAppsList: JList;
      ri: JResolveInfo;
      iter: JIterator;
      midlist : TStringList;
    begin
      PM := SharedActivityContext.getPackageManager;
      mainIntent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_MAIN, nil);
      mainIntent.addCategory(TJIntent.JavaClass.CATEGORY_LAUNCHER);
      pkgAppsList := PM.queryIntentActivities(mainIntent, 0);
      midlist := TStringList.Create;
      iter := pkgAppsList.iterator;
      while iter.hasNext do
      begin
        ri := TJResolveInfo.Wrap((iter.next as ILocalObject).GetObjectID);
        mIdList.Add(JStringToString(ri.activityInfo.applicationInfo.packageName));
      end;
      LaunchIntent := PM.getLaunchIntentForPackage(StringToJString(mIdList[2]));
    
    // 해당을 실행하려면 아래처럼,..,
    // SharedActivityContext.startActivity( LaunchIntent )
    
      showmessage(  mIdList.Text );
    end;

    댓글에서 수달님 께서 안드로이드 2.3.4 버전에서 정상동작을 확인하셨고, uses 절을 알려주셔서 포함했습니다.


    참고






    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 파이어몽키

    RAD Studio XE7에서 추가된 안드로이드 기능 익히기(동영상)

    2014.11.04 11:32

    RAD Studio XE7에서 다양한 안드로이드 기능 추가/개선 되었습니다.

    아래 동영상을 통해서 개선된 내용에 대한 소개와 몇가지 기능은 데모로 자세히 설명합니다.

    • 안드로이드 스플래쉬 스크린
    • 안드로이드 몰입모드(전체화면)
    • 안드로이드 라이브러리(JAR, Java class)를 RAD Studio에서 사용하는 Java2OP.exe 사용방법



    RAD Studio XE7에서 추가된 대표적인 안드로이드 기능은 아래와 같습니다.

    • 구글 모바일 광고 SDK(XE6에서도 Hotfix로 변경)
    • 몰입모드-전체화면(안드로이드 KitKat 4.4 이상)
    • 안드로이드에서 스플래쉬 스크린 지원
    • 푸시알림과 광고 프로젝트 옵션
    • 프로젝트 매니저에서 자바 라이브러리 추가
    • Java2OP tool: 자바 안드로이드 클래스를 오브젝트 파스칼 인터페이스로 생성


    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 파이어몽키

    RAD Studio XE7의 TListView에서 당겨서 새로고침 구현 샘플

    2014.11.04 09:37

    RAD Studio XE7에서 TListView의 당겨서 새로고침 기능이 추가되었습니다.(이전버전에서는 코드로 직접 구현이 필요했습니다.)

    TListView에서 제공하는 기능은 목록을 당기면 UI 요소에서 새로고침 UI를 표시하고 이벤트를 발생하는 UI 요소에 대한 새로고침 기능입니다. 실제 데이터를 조회하는 기능은 이벤트 내에서 직접 구현해야 합니다.


    엠바카데로의 사리나 듀폰의 블로그에서 TListView의 당겨서 새로고침(OnPullRefresh) 이벤트에서 데이터 처리하는 기능에 대한 샘플을 제공합니다.


    아래와 같이 UI를 구성하고 BaaS(Backend as a Service: Cloud Service)에서 데이터를 조회하는 내용의 샘플입니다.


    자세한 내용은 하단의 링크를 통해 따라해 보시기 바랍니다.



    사용되는 구성요소

    User Interface:

    • TListView, aligned to the client
      • populated with data using LiveBindings Designer
    • TToolbar, aligned to the top
      • TLabel, parented to TToolbar, aligned to contents; TextSettings->HorzAlign: Center
    • TToolbar, aligned to the bottom
      • TLabel, parented to TToolbar, aligned to contents; TextSettings->HorzAlign: Center; TextSettings->FontColor: Dodgerblue;
    BaaS:
    • TKinveyProvider
      • AppKey, AppSecret and MasterSecret have been set; you can also use TApp42Provider and TParseProvider
    • TBackendQuery for querying existing data that lives in the cloud and was added via the BaaS web interface
      • connected to KinveyProvider; BackendService = Storage; BackendClassName = Recipes (this was defined inside my Kinvey account))
    • TRESTResponseDataSetAdapter
      • DataSet = FDMemTable1
      • ResponseJSON = BackendQuery1
      • Active = True
    • TFDMemTable


    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 파이어몽키

    1. 링크가 깨진것 같습니다. 아래 링크에서 내용을 확인할 수 있습니다.
      http://community.embarcadero.com/index.php/blogs/blogger/listall/sarina-dupont-embarcadero-com?start=10

    파이어몽키 커스텀 스타일 제작 따라하기

    2014.11.03 14:56

    파이어몽키에서는 스타일 기반으로 아주 유연하고 다양한 외관의 앱을 개발할 수 있습니다.


    오늘은 엠바카데로의 블로그에 소개된 파이어몽키 커스텀 스타일을 제작하는 방법을 소개합니다.

    총 9단계에 걸처 파이어몽키 스타일을 수정(제작)할 수 있습니다. 




    관련글



    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 파이어몽키

    1. Blog Icon
      궁금이

      저 궁금한게 있는데요 윈도에서 스타일 적용했을때 잔상이 남던데 어떻게 해결하시나요

    [XE7] 안드로이드 브릿지 파일을 생성할 수 있는 Java2OP.exe을 다운로드 하세요.

    2014.11.03 14:20

    RAD Studio XE7(델파이, C++빌더) 구입 하신 분들은 Java2OP 커맨드라인 유틸리티를 다운로드 할 수 있습니다.

    Java2OP(Java to Object Pascal) 커맨드라인 툴은 델파이 안드로이드 어플리케이션에서 자바 라이브러리를 사용할 수 있도록 자바 클래스 파일을 이용해 오브젝트 파스칼(델파이)용 브릿지 파일을 생성할 수 있는 도구입니다.

    이 툴을 이용하면 JAR 파일 또는 자바 클래스 파일을 연동할 수 있는 Object Pascal 브릿지 파일을 생성해 델파이에서 이용할 수 있습니다.


    자세한 사용법은 다음 글의 동영상으로 익힐 수 있습니다.


    참고





    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 파이어몽키 Delphi, Java2OP, RAD Studio XE7, XE7

    웹브라우저를 지원하지 않는 플랫폼(윈도우, OS X)에서 웹브라우저 지원하기

    2014.10.24 09:25

    RAD Studio와 AppMethod에서 멀티플랫폼으로 개발할 수 있지만, 아쉽게도 몇개의 컨트롤은 제한적인 플랫폼에서만 사용할 수 있습니다.

    웹브라우저가 그 중하나인데요. 일본의 엠바카데로 MVP 개발자인 Hosokawa Jun가 윈도우와 OS X에서 사용할 수 있도록 소스코드와 설명을 공개했습니다.


    일본어로 되어 있으므로 번역기를 통해 내용을 확인하시기 바랍니다.


    그리고 웹브라우저의 소스코드는 Github에 있습니다.

    TWebBrowser 뿐 아니라 다양한 소스코드가 공개되어 있으니 살펴보면 많은 도움이 될것입니다.


    참고



    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 파이어몽키 TWebBrowser

    FMX 리스트박스를 정렬하고 필터링하는 내용 설명

    2014.10.22 10:10



    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 파이어몽키

    내가 원하는 이름으로 모바일 앱의 이름 변경하기

    2014.10.21 11:30

    배포 전 프로젝트 옵션을 변경해 앱의 정보를 설정할 수 있습니다.

    이름을 변경하려하는 경우 아래 정보를 참고하세요.

    안드로이드

    Project > Option > Version Info > label



    iOS

    Project > Option > Version Info > CFBundleDisplayName





    참고



    저작자 표시 비영리 동일 조건 변경 허락
    신고
    크리에이티브 커먼즈 라이선스
    Creative Commons License

    험프리.김현수 험프리.김현수 파이어몽키 android, CFBundleDisplayName, Display, ios

    "나의 도서관 앱" 개발 따라하기 - (2) 데이터베이스 만들기, 실제 데이터 연결

    2014.10.20 15:07

    업데이트

    • 2015-02-25 : "2. 프로젝트 소스에서 데이터베이스와 연결"에서 Fields를 생성해 자동증가 속성을 주도록 변경


    이번 글에서는 감명깊게 읽은 도서 정보, 리뷰를 기록할 수 있는 "나의 도서관 앱" 개발과정의 두번째 따라하기를 진행합니다.

    첫번째 사용자화면 만들기와 기능 구현하기를 먼저 진행하시기 바랍니다.

    따라하기 2 - 데이터베이스 만들기, 실제 데이터 연결

    1. "나의 도서관"앱에서 사용할 데이터베이스 만들기 
    2. 프로젝트 소스에서 데이터베이스와 연결 
    3. 데이터와 화면요소 연결하기 
    4. 데이터 입력, 수정, 삭제 기능 구현하기 
    5. 데이터베이스 파일과 라이선스파일 배포 등록하기 
    6. 원하는 모바일 디바이스에 배포하고 실행! 끝~

    1, "나의 도서관"앱에서 사용할 데이터베이스 만들기

    앱에서 사용할 데이터베이스를 생성합니다. 데이터베이스는 엠바카데로 제품 중 무료로 사용할 수 있는 IBLite 기반으로 진행합니다.

    1. IB Console을 실행(시작 > 프로그램 > Embarcadero InterBase XE3)합니다.
    2. Database > Create Database 메뉴 선택 후 아래 정보를 입력 후 OK 버튼을 눌러 데이터베이스 생성합니다.
      • File Name : 프로젝트 파일 하위에 "DB" 폴더 생성 후 지정(파일명은 반드시 "BOOKLOG.GDB"(확장자 입력)로 지정)
      • Default Character Set :UTF8(한글입력 시 필수)
      • Password of user : masterkey
    3. 데이터베이스 접속 창이 표시되면 위에서 입력한 "masterkey" 비밀번호를 입력 후 Connect 버튼을 눌러 접속합니다.
      (Display Character Set은 UTF8로 설정되었는지 확인)
    4. Tool > Interactive SQL 메뉴를 선택 하고 아래의 쿼리 입력 후 실행(Query > Execute, F5)하여 테이블과 트리거를 생성합니다.

      /* 테이블 생성 */
      CREATE TABLE "BOOK_LOG" (
        "BOOK_SEQ"		INTEGER NOT NULL,
        "BOOK_TITLE"		VARCHAR(50) NOT NULL,
        "BOOK_AUTHOR"		VARCHAR(30) NOT NULL,
        "BOOK_PUBLISHER"	VARCHAR(30),
        "BOOK_PHONE"		VARCHAR(20),
        "BOOK_WEBSITE"	VARChAR(100),
        "BOOK_COMMENT"	VARCHAR(1000),
        "BOOK_THUMB"		BLOB SUB_TYPE 0 SEGMENT SIZE 80,
        "BOOK_IMAGE"		BLOB SUB_TYPE 0 SEGMENT SIZE 80,
        CONSTRAINT "BOOK_SEQ_PK" PRIMARY KEY ("BOOK_SEQ")
      );
      
      /* BOOK_SEQ 자동증가 */
      CREATE GENERATOR "BOOK_SEQ_GEN";
      CREATE TRIGGER "SET_BOOK_SEQ" FOR "BOOK_LOG"
      ACTIVE BEFORE INSERT POSITION 0 AS
      BEGIN
          new.BOOK_SEQ = gen_id(BOOK_SEQ_GEN, 1);
      END;
    create_script.sql

    2, 프로젝트 소스에서 데이터베이스와 연결

    데이터 연결 컴포넌트를 이용해 프로젝트에서 앞에서 만든 BOOKLOG.GDB와 연결합니다

    데이터 연결 작업은 DataAccessModule.pas에서 진행합니다.

    데이터 연결 컴포넌트 설정

    1. 데이터 모듈에 TFDConnection을 추가합니다.
    2. 추가된 FDConnection1을 더블클릭 해 FireDAC Connection Editor를 표시하고 아래와 같이 설정합니다.
      • Drive ID : IB
      • Database : 앞에서 생성한 BOOKLOG.GDB 선택택
      • User_Name : sysdba
      • Password : masterkey
      • CharacterSet : UTF8
    3. Test 버튼을 눌러 연결을 확인하고 OK 버튼을 눌러 창을 닫습니다.
    4. FDConnection1LoginPrompt 속성을 False로 설정합니다.
    5. Connected 속성을 True로 설정합니다.

    데이터 질의(Query) 컴포넌트 설정

    1. 데이터 모듈에 TFDQuery 컴포넌트를 추가합니다.
    2. FDQuery1의 Connection속성을 FDConnection1으로 설정(확인)합니다.
    3. CachedUpdates 속성을 True로 설정합니다.
    4. FDQuery1 컴포넌트를 더블클릭 후 아래 쿼리문을 설정합니다.
      • SQL Command : SELECT * FROM BOOK_LOG
      • Execute 버튼 클릭 해 쿼리문 확인
      • OK 버튼 클릭
    5. Active 속성을 True로 변경합니다.

      데이터 질의(Query) 컴포넌트 필드 추가 / 자동증가 필드 설정

      1. FDQuery1 선택 후 오른쪽 마우스 메뉴에서 Fields Editor... 메뉴를 실행합니다.
      2. Fields Editor 창의 오른쪽 마우스 메뉴에서 Add all fields 메뉴를 실행 해 모든 필드를 추가합니다.
      3. BOOK_SEQ(FDQuery1BOOK_SEQ)항목 선택 후 AutoGenerateValue 속성을 arAutoInc로 선택합니다.

      화면 구성시 샘플데이터로 사용했던 PrototypeBindSource1을 데이터 모듈에서 삭제(선택 후 Delete 키)합니다.


      3, 데이터와 화면요소 연결하기

      View > LiveBindings Designer 메뉴를 통해 라이브 바인딩 디자이너를 표시하고, 아래 그림을 참고해 화면요소에 데이터를 연결합니다. (지금은 데이터베이스에 데이터가 없으므로 연결을 해도 화면의 변화가 없습니다.)

      도서목록

      도서 상세보기

      새로운 도서추가

      4, 데이터 입력, 수정, 삭제 기능 구현하기

      화면에서 입력받은 데이터를 입력, 수정, 삭제하는 기능을 구현합니다.


      데이터 모듈에 데이터 처리 메소드 추가

      1. DataAccessModule.pas으로 이동 후 FDConnection1 컴포넌트의 BeforeConnect 이벤트에 아래의 코드를 입력합니다.
        procedure TDataModule1.FDConnection1BeforeConnect(Sender: TObject);
        begin
        // 윈도우가 아닌 경우 데이터베이스 경로를 배포경로로 조정
        {$IFNDEF MSWINDOWS}
          FDConnection1.Params.Values['Database'] := TPath.Combine(TPath.GetDocumentsPath, 'BOOKLOG.GDB');
        {$ENDIF}
        end;
      2. DataAccessModule.pas의 코드 에디터 창을 표시합니다.(폼 디자이너에서 F12)
      3. 상단 uses절에 FMX.Graphics, System.IOUtils를 추가합니다.
      4. 선언부 public 영역에 아래의 코드를 입력합니다.
          public
            { Public declarations }
            procedure Connect; // 데이터베이스 연결
            procedure AppendMode; // 입력 모드로 변경
            procedure EditMode; // 수정 모드로 변경
            procedure SetImage(ABitmap: TBitmap); // 이미지저장(본문, 목록의 썸네일 이미지)
            procedure SaveItem; // 항목 저장(입력/수정)
            procedure CancelItem; // 입력/수정 모드 취소
            procedure DeleteItem; // 선택항목 삭제
          end;
      5. 구현부(선언부에 입력 후 Ctrl + Shift + C 누르면 구현부 자동 생성)에 아래의 코드를 입력합니다.
        // 입력/수정 모드 취소
        procedure TDataModule1.CancelItem;
        begin
          if FDQuery1.UpdateStatus = TUpdateStatus.usInserted then
            FDQuery1.Cancel;
        end;
        
        // 데이터베이스 연결
        procedure TDataModule1.Connect;
        begin
        {$IFNDEF MSWINDOWS}
          FDConnection1.Params.Values['Database'] := TPath.Combine(TPath.GetDocumentsPath, 'BOOKLOG.GDB');
        {$ENDIF}
          FDConnection1.Connected := True;
          FDQuery1.Active := True;
        end;
        
        // 현재항목 삭제
        procedure TDataModule1.DeleteItem;
        begin
          FDQuery1.Delete;
          FDQuery1.ApplyUpdates(0);
          FDQuery1.CommitUpdates;
          FDQuery1.Refresh;
        end;
        
        // 수정모드
        procedure TDataModule1.EditMode;
        begin
          FDQuery1.Edit;
        end;
        
        // 입력모드
        procedure TDataModule1.AppendMode;
        begin
          FDQuery1.Insert;
        end;
        
        // 항목 저장
        procedure TDataModule1.SaveItem;
        begin
          FDQuery1.Post;
          FDQuery1.ApplyUpdates(0);
          FDQuery1.CommitUpdates;
          FDQuery1.Refresh;
        end;
        
        // 이미지 저장(본문이미지와 목록에 표시할 썸네일)
        procedure TDataModule1.SetImage(ABitmap: TBitmap);
        var
          Thumbnail: TBitmap;
          ImgStream, ThumbStream: TMemoryStream;
        begin
          if FDQuery1.UpdateStatus = TUpdateStatus.usUnmodified then
            FDQuery1.Edit;
        
          ImgStream := TMemoryStream.Create;
          ThumbStream := TMemoryStream.Create;
          try
            ABitmap.SaveToStream(ImgStream);
            Thumbnail := ABitmap.CreateThumbnail(100, 100);
            Thumbnail.SaveToStream(ThumbStream);
        
            (FDQuery1.FieldByName('BOOK_IMAGE') as TBlobField).LoadFromStream(ImgStream);
            (FDQuery1.FieldByName('BOOK_THUMB') as TBlobField).LoadFromStream(ThumbStream);
          finally
            ImgStream.Free;
            ThumbStream.Free;
          end;
        end;

      화면 기능과 데이터 처리 메소드 연결

      1. 폼 디자이너로 돌아와 아래의 코드를 참고해 데이터 처리기능을 추가합니다.

        procedure TForm1.FormCreate(Sender: TObject);
        begin
          TabControl1.TabPosition := TTabPosition.None;
          TabControl1.TabIndex := 0;
        
          OverflowMenu.Visible := False;
        
          vsbEditFocus.OnCalcContentBounds := CalcContentBoundsProc;
        
          DataModule1.Connect; // 데이터베이스 연결
        end;
        
        procedure TForm1.btnNewItemClick(Sender: TObject);
        begin
          DataModule1.AppendMode; // 입력 모드로 변경
          GotoNew;
        end;
        
        // 수정
        procedure TForm1.lstItemModifyClick(Sender: TObject);
        begin
          OverflowMenu.Visible := False;
          DataModule1.EditMode; // 수정 모드로 변경
          GotoNew;
        end;
        
        // 삭제
        procedure TForm1.lstItemDeleteClick(Sender: TObject);
        begin
          OverflowMenu.Visible := False;
        
          MessageDlg('해당 정보를 삭제하시겠습니까?', TMsgDlgType.mtWarning,
            [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 0, procedure(const AResult: TModalResult)
            begin
              if AResult = mrYes then
              begin
                DataModule1.DeleteItem; // 선택항목 삭제
                GotoList;
              end;
            end);
        end;
        
        procedure TForm1.btnCancelClick(Sender: TObject);
        begin
          DataModule1.CancelItem; // 입력/수정 모드 취소
          GotoList;
        end;
        
        procedure TForm1.btnSaveItemClick(Sender: TObject);
        begin
          DataModule1.SaveItem; // 현재항목 저장
          GotoList;
        end;
        
        procedure TForm1.ChangeImageEvent(Image: TBitmap);
        begin
          imgNewItem.Bitmap.Assign(Image);
          DataModule1.SetImage(Image); // 이미지 저장
        end;

      5, 데이터베이스 파일과 라이선스파일 배포 등록하기

      이제 모든 개발이 완료되었습니다. IBLite 데이터베이스를 이용한 경우에는 IBLite 데이터베이스 파일과 IBLite 라이선스 파일과 라이브러리를 앱 배포시 함께 배포해야 합니다.


      IBLite 데이터베이스 파일 배포 등록하기

      1. Project > Deployment 메뉴를 선택해 배포 관리자 화면을 표시합니다.
      2. Add files 버튼을 누르고 1단계에서 만든 BOOKLOG.GDB 파일을 선택해 추가합니다.
      3. 설정선택 콤보박스를 Android platform과 iOS Device platform으로 선택하고 각각 아래를 참고해 Remote Path를 수정합니다.
        • Android platform - assets\internal\
        • iOS Device platform - StartUp\Documents\

      IBLite 라이선스 파일과 라이브러리 배포 등록하기

      1. IBLite, IBTOGO 테스트 라이선스 배포방법 페이지를 참고해 reg_iblite.txt 파일을 다운로드 합니다.
        1. https://reg.codegear.com/srs6/activation.do 페이지 이동
        2. 제품구매(또는 트라이얼 다운로드) 시 받은 라이선스 메일을 참고해 Serial Number와 Registration Code 입력 후 Next 버튼 클릭
        3. 하단에서 파일 다운로드 기능을 이용해 C:\Users\Public\Documents\Embarcadero\InterBase\redist\InterBaseXE3 경로에 파일 다운로드
        4. 다운로드된 텍스트파일(reg_XXXXXXX.txt)를 "reg_iblite.txt"로 이름 변경
      2. 배포 관리자 화면에서 Add Featured Files 버튼 클릭 후 Interbase TOGO 라이브러리 선택
        1. InterBase ToGo > iOSDevice 항목 선택 > reg_ibtogo.txt 선택해제
        2. InterBase ToGo > Android 항목 선택 > reg_ibtogo.txt 선택해제

      (옵션)앱 이름을 바꾸고 아이콘으로 단장하기

      앱의 이름 바꾸기

      1. Project > Option 메뉴 선택 후 Version Info 메뉴 선택 합니다.
      2. 상단의 타겟 플랫폼을 선택 후 플랫폼에 맞는 항목을 입력합니다.
        • 안드로이드 : label
        • iOS(아이폰) : CFBundleDisplayName
      3. 각각 '나의 도서관' 입력 후 OK 버튼으로 저장합니다.

      앱의 아이콘/스플래쉬 이미지 바꾸기

      1. Project > Option  메뉴 선택 후 Application 항목을 선택합니다.
      2. 상단의 Target에서 플랫폼을 선택 후 목록에 있는 아이콘과 스플래쉬 이미지를 지정합니다.
        (목록의 이미지 크기에 맞는 이미지를 준비해야 합니다. 샘플아이콘 다운로드)

      6, 원하는 모바일 디바이스에 배포하고 실행! 끝~

      • 배포를 원하는 플랫폼을 선택하고 Run > Run Without Debugging 메뉴를 통해 배포 및 실행합니다.
        (안드로이드 개발환경 설정은 앱메소드 튜토리얼 동영상을 통해 확인할 수 있습니다.)

      개발도구

      참고








      저작자 표시 비영리 동일 조건 변경 허락
      신고
      크리에이티브 커먼즈 라이선스
      Creative Commons License

      험프리.김현수 험프리.김현수 파이어몽키

      1. Blog Icon
        더스틴

        안녕하세요. 좋은 내용 올려주셔서 감사합니다.
        소스중에 아래 부분은 C++빌더로는 어떻게 표현되는 것인지요?
        (FDQuery1.FieldByName('BOOK_IMAGE') as TBlobField).LoadFromStream(ImgStream);

      2. 아래 링크를 참고하시면 도움이 되실것 같네요.^^(제가 C++ 문법이 짧아서요^^)
        http://codeback.net/cbuilder/using-tblobfield-and-tblobstream-in-cbuilder
        해결되시면 해결하신 내용 좀 남겨주세요. 제가 C++빌더로 컨버전해보고 싶네요.(가능하시면 소스코드 보내주시면 감사하겠습니다^^)

      3. Blog Icon
        더스틴

        위에 제가 질문 드린 내용은 해결되었습니다. 아래와 같이 하면 잘되더군요. ^^
        dynamic_cast<TBlobField*>(FDQuery1->FieldByName("BOOK_IMAGE"))->LoadFromStream(ImgStream);
        아무튼 빠른 피드백 감사합니다.
        김현수님의 블로그 내용이 많은 도움 됩니다. 정말 감사드려요.

      4. 네 도움이 되셨다고하니 기쁘네요.
        앞으로도 좋은 내용으로 보답하겠습니다.^^

      5. Blog Icon
        아이리스

        죄송한데 계속 ibconsol애서요. Bad parameters on attach or create database
        CHARACTER SET UTF8 is not defined 이런문구가 뜨면서 데이터베이스 생성이 안됩니다. 캐릭터셋을 none
        하면 만들어지기는 하는데 이번에 델파이에서는 type mismatch for field ' BOOK_TITLE', expecting: WideString actual:String. 이런 에러 문구가 떠서 엑티브를 할수가 없군요. 문자형셋이 안맞아서 그런거 같은데 해결법좀요

      6. Blog Icon
        하이길동

        안녕하세요 다름이 아니오라 db관련으로 궁금한것이 있어 이렇게 문의드립니다
        interbase 나 firebird로 된 sql문을 sqlite로 바꾸려면
        어떻게 해야 되는지 알고 싶어 문의드립니다
        sqlite에 없는 것 같은 generator 같은것(????)
        sqlite로 작성하니 여기서부터 에러가 계속 나서 ~
        "BOOK_THUMB" BLOB SUB_TYPE 0 SEGMENT SIZE 80,
        "BOOK_IMAGE" BLOB SUB_TYPE 0 SEGMENT SIZE 80,
        CONSTRAINT "BOOK_SEQ_PK" PRIMARY KEY ("BOOK_SEQ")
        );

        /* BOOK_SEQ 자동증가 */
        CREATE GENERATOR "BOOK_SEQ_GEN";
        CREATE TRIGGER "SET_BOOK_SEQ" FOR "BOOK_LOG"
        ACTIVE BEFORE INSERT POSITION 0 AS
        BEGIN
        new.BOOK_SEQ = gen_id(BOOK_SEQ_GEN, 1);
        END;

      7. 자동증가 필드를 지원하는 방식은 DB마다 다른데요.
        구글에서 "sqlite 자동증가"로 검색해 보시면 첫번째 링크인 볼랜드 포럼에서 다음 내용을 참고할 수 있네요.
        http://interbase.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=835

      8. Blog Icon
        이성열

        너무나 많은 도움 받고 갑니다.
        나도 모르게 북마크에 추가하게 되네요.

      9. 응원에 힘이납니다^^ 더 좋은 자료로 보답하겠습니다.

      재사용 가능한 프레임으로 UI 구현하기(사진, 웹페이지)

      2014.10.17 16:14

      사진 찍기와 웹페이지 표시와 같은 기능은 앱에서 많이 사용됩니다.

      이렇게 빈번히 사용하는 기능을 매번 구현하지 않고 프레임으로 구현 후 재사용하는 방법을 소개합니다.


      모바일 앱에서는 위와 같은 UI를 많이 사용합니다. 매번 해당 UI를 구현하려면 상당히 번거롭습니다.

      아래와 같이 짧은 코드로 위의 2가지 기능을 쉽게 사용할 수 있습니다.

      uses PhotoFrame, WebBrowserFrame;
      
      procedure TForm1.Button1Click(Sender: TObject);
      begin
        TfrPhoto.CreateAndShow(Self, ChangeImageEvent, nil);
      end;
      
      procedure TForm1.ChangeImageEvent(Image: TBitmap);
      begin
        Image1.Bitmap.Assign(Image);
      end;
      
      procedure TForm1.Button2Click(Sender: TObject);
      begin
        TfrWebBrowser.CreateAndShow(Self, Edit1.Text);
      end;
      
      procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
        Shift: TShiftState);
      begin
        if Key = vkHardwareBack then
        begin
          if Assigned(frPhoto) then
          begin
            frPhoto.CloseFrame;
            Key := 0;
          end;
      
          if Assigned(frWebBrowser) then
          begin
            frWebBrowser.CloseFrame;
            Key := 0;
          end;
        end;
      end;

      위 소스코드에서는 TfrPhoto와 TfrWebBrowser를 이용해 사진기능과 웹브라우저 기능을 모두이용하고, 

      안드로이드 백버튼에 대한 처리까지 되어있습니다.

      (PhotoFrame에서 iOS와 안드로이드의 버튼 위치와 스타일도 플랫폼에 맞도록 지정했습니다.)


      사진기능과 웹브라우저 기능을 포함한 프레임등의 전체 소스코드는 제 Github 페이지를 참고하세요.


      보강할 기능이나 이런식의 프레임으로 처리할 기술이 있다면 댓글이나 메일로 말씀해 주시면 적극 반영하겠습니다.


      저작자 표시 비영리 동일 조건 변경 허락
      신고
      크리에이티브 커먼즈 라이선스
      Creative Commons License

      험프리.김현수 험프리.김현수 파이어몽키

      "나의 도서관 앱" 개발 따라하기 - (1) 사용자화면 만들기와 기능 구현하기

      2014.10.16 16:25

      "나의 도서관" 앱 개발 따라하기

      ❑ 앱 소개

      • 감명깊게 읽은 도서 정보를 기록하는 앱입니다.
      • 세미나 발표와 샘플소스 제공을 위해 다소 주제와 맞지 않은 기능이 포함되어 있습니다.
      • 해당 앱은 RAD Studio XE7(또는 AppMethod 1.15)로 개발 후 하나의 소스코드로 안드로이드와 iOS 앱을 동시에 개발하였습니다.

      따라하기를 통해 습득할 수 있는 기술

      • 앱 개발의 전반적인 흐름을 따라하며 익혀 볼 수 있습니다.
      • 기본적인 UI 컨트롤 사용법과 속성 사용법
      • 화면 구성에 도움이 되는 샘플데이터 생성(프로토타입 데이터 소스)
      • 화면요소와 데이터를 (소스코드 없이)시각적으로 연결하는 기술(라이브바인딩)
      • 이미 구현된 기능을 재활용할 수 있는 프래임 활용방법(TFrame)
      • 앱에 포함하여 배포할 수 있는 임베디드 데이터베이스 사용법(IBLite)
      • 앱에서 데이터 연결 후 입력/수정/삭제 과정
      총 2번의 따라하기로 "나의 도서관" 앱이 완성됩니다.
      1. 사용자화면 만드기, 기능 구현하기
      2. 실제 데이터베이스 연결, 배포
      이 따라하기는 따라하기 과정 중 나오는 기술에 대한 이해 없이 일단(무조건) 따라하며 완성하는 것을 목적으로 작성되었습니다. 따라하는 도중 잘 이해가 되지 않더라도 끝까지 따라해보시길 권장합니다.

      기술에 대한 설명은 글의 하단에 링크를 통해 제공하고 있습니다. 기타 궁금한 점은 댓글로 남겨주시기 바랍니다.
      ※ 해당 따라하기는 AppMethod를 통해 진행할 수 있습니다. 하단의 AppMethod 설치를 참고해 설치 후 진행하시기 바랍니다.

      따라하기 1 - 사용자 화면 만들기와 기능 구현하기

      1. 빈 멀티-디바이스 앱 하나를 선택합니다. 
      2. 사용자들에게 보여질 화면을 만듭니다. 
      3. 샘플 데이터 추가 후 화면요소와 연결해 화면 표시 후 테스트하기
      4. 사용자의 조작에 동작하는 기능코드를 작성합니다. 
      5. 전화걸기, 사진, 웹페이지 표시 기능 추가 
      6. 사용자화면 완성! 테스트 하기

      1, 빈 멀티-디바이스 앱 하나를 선택합니다.

      1. File > New > Multi-Device Application - Delphi 메뉴를 선택 하고, Blank Application을 선택해 프로젝트를 생성합니다.
      2. File > Save all 메뉴를 선택하고 유닛이름은 "MainForm.pas"로 프로젝트 이름은 'BookLogFMX"로 저장합니다.


      2, 사용자들에게 보여질 화면을 만듭니다.

      모바일 앱 스타일로 화면 구성을 위해 폼디자이너 스타일을 Android(또는 iOS)로 변경합니다.


      총 3개의 화면을 구성해야 합니다. 

      탭컨트롤

      여러화면을 구성하기 위해 탭컨트롤을 아래 표를 참고해 추가합니다.

       상위 오브젝트

      오브젝트 

      속성 

      값(또는 설명) 

       

       Form1

       Width / Height

       380 / 530(폼의 가장자리를 마우스로 적당한 크기로 조정)

       Form1

       TabControl1

       Align

       Client

       TabPosition

       Bottom
       (개발 시 탭이동 편의를 위해, 실행 시 탭은 표시하지 않음)

       TabControl1

       TabItem1(추가방법[각주:1])

       Text

       도서 목록

       Tabitem2

       Text

       도서 상세보기

       TabItem3

       Text

       새로운 도서 추가

      도서 목록

      "도서 목록"탭에서 아래 그림과 표를 참고해 화면 구성합니다.




       상위 오브젝트

      오브젝트 

      속성 

      값(또는 설명) 

       TabItem1

       ToolBar1

       

       

       ToolBar1 Label1  Align Contents
       StyleLookup

       toollabel 

       Text 나의 도서관
       TextSettings.HorzAlign Center

       btnNewItem

       (TButton)

       Name btnNewItem
       Align  Right
       StyleLookup additemButton

       Tabitem1

      ListView1AlignClient
       ItemApperance.ItemAppearance  ImageListItemBottomDetail

       ItemApperance.ItemHeight

       88

       ItemApperance.ItemObjects

      .Image.Width / Height

       60 / 80
        ItemApperance.ItemObjects

      .Text.WordWrap

       True


      도서 상세보기

      "도서 상세보기"탭에서 아래 그림과 표를 참고해 화면 구성합니다.


       상위 오브젝트

      오브젝트 

      속성 

      값(또는 설명) 

       TabItem2

       ToolBar2

       

       

       ToolBar2

       Label2

       Align Contents
       StyleLookup toollabel 
       Text 제목
       TextSettings.HorzAlign Center
       TextSettings.WordWrap False

       btnBackList
       (TButton)

       Name btnBackList
       Align  Left
       StyleLookup arrowlefttoolbutton

       btnDetail

       (TButton)

       Name btnDetail
       Align

       Right

       StyleLookup detailstoolbutton

       TabItem2

       Layout1

       Align

       Client

       Layout1 Panel1 Align Top
       Height 116
       Margins 8, 8, 8, 8
       Panel1

       ShadowEffect1

       Distance 2
       ShadowColor Gray

       Rectangle1

       Image1 Align Left
       Margins 8, 8, 8, 8

       Width

       75
       Rectangle1 Layout2 Align Client
       Layout2

       lblTitle(TLabel)

       Name

       lblTitle

       Align MostTop
       AutoSize

       True

       Margins 0, 8, 3, 16

       StyledSettings.Style

       False
       TextSettings.Font.Size

       16

       TextSettings.Font.Style.fsBold

       True
       lblAuthor(TLabel) Name

       lblAuthor

       Align Top
       Margins 3, 12, 3, 10

       Layout1

       ListBox1 Align Client
       ListBox1 

       ListBoxItem1[각주:2]
       ListBoxItem2
       ListBoxItem3
       ListBoxItem4

       StyleLookup
       Text
       listboxitemnodetail
       출판사, 연락처, 사이트, 감상평

       ListBoxitem4

       Height 150
       ListBoxItem1 lblPublisher(TLabel) Align
      Margins.Left
      (4개 공통)

       Client
      80
      (4개 공통)

       ListBoxItem2 lblPhone(TLabel)
       ListBoxItem3 lblWebSite(TLabel)
       ListBoxItem4 lblComment(TLabel)
       ListBoxItem2 lblPhone HitTest Ture
       ListBoxItem3 lblWebSite

       HitTest

       True
       ListBoxItem4 lblComment TextSettings.VertAlign Leading
       Tabitem2 OverflowMenu(TListBox) Name OverflowMenu
       Position.X / Position.Y

       Button3 아래로 이동

       Width / Height 88 / 96
       OverflowMenu

       lstItemModify,

       lstItemDelete

       (TListBoxItem)

       Name

       lstItemModify /  lstItemDelete

       StyleLookup listboxitemstyle
       Text

       수정 / 삭제

       TextSettings.HorzAlign Center
       ShadowEffect2  

      새로운 도서 추가

      "새로운 도서 추가"탭에서 아래 그림과 표를 참고해 화면 구성합니다.



       상위 오브젝트

      오브젝트 

      속성 

      값(또는 설명) 

       TabItem3

       ToolBar3

       

       

       ToolBar3

       Label3 

       Align Contents
       StyleLookup toolbutton 
       Text 도서 추가
       TextSettings.HorzAlign Center

       btnCancel

       (TButton)

       Name btnCancel
       Align  Left
       StyleLookup backtoolbutton
       Text 취소

       btnSaveitem

       (TButton)

       Name btnSaveItem
       Align

       Right

       StyleLookup

       donetoolbutton

       Text 

       저장

       TabItem3

       vsbEditForcus

       (TVertScrollBox)

       Name

       vsbEditFocus

       Align Client
       vsbEditForcus lytContentsNew(TLayout) Name lytContentsNew
       Align Client
       Layout3 Layout4 Align Top
       Height 113
       Layout4 Rectangle2 Align Center

       Fill.Kind

       None

       Width / Height

       100 / 100
       Rectangle2 imgNewItem(TImage) Name imgNewItem
       Align Client
       Margins 2, 2, 2, 2
       Layout3 ListBox2 Align Client
       ListBox2

       ListBoxItem7 ~ 12

       (6개 추가)

       StyleLookUp
       Text


       listboxitemnodetail
       제목, 저자, 출판사, 연락처, 사이트, 감상평

       ListBoxitem12

       Height 100

       ListBoxitem7

       edtTitle(TEdit)

       Align
       Margins
       Client
       7, 80, 5, 7

       ListBoxitem8

       edtAuthor(TEdit)

       ListBoxitem9

       edtPublisher(TEdit)

       ListBoxitem10

       edtPhone(TEdit)

       ListBoxitem11

       edtWebSite(TEdit)

       ListBoxitem12

       mmoComment(TMemo)
       mmoComment

       TextSettings.WordWrap

       True


      3, 샘플 데이터 추가 후 화면요소와 연결해 화면 표시 후 테스트하기

      화면 테스트를 위해 샘플(프로토타입) 데이터를 데이터 모듈에 추가합니다. 뒤에서 샘플 데이터를 실제 데이터베이스로 변경합니다.

      데이터 엑세스 기능을 구현하기 위해 데이터모듈 추가

      1. File > New > Other 메뉴를 선택 해 "New Items" 대화상자를 표시합니다.
      2. 왼쪽 트리메뉴에서 Object Pascal Projects > Object Pascal Files를 선택합니다.
      3. Data Module을 선택 하고 OK 버튼을 누릅니다.
      4. 데이터 모듈이 추가되면 File > Save 메뉴를 누르고 "DataAccessModule.pas"로 저장합니다.
      5. Object Inspect(속성창)에서 Name 속성을 dmDataAccess로 변경합니다.

      테스트용 샘플 데이터 추가

      1. 데이터모듈에 TPrototypeDataSource를 추가합니다.
      2. PrototypeDataSource1의 RecordCount30으로 변경합니다.
      3. PrototypeDataSource1을 더블클릭 후 Add New 버튼으로 위 그림을 참고해 항목 5개를 추가합니다.

      샘플데이터와 화면요소 연결하기

      1. MainForm으로 돌아와 위에서 추가한 데이터 모듈 사용하기 위해 File > Use unit 메뉴를 선택하고 "DataAccessModule.pas" 파일을 선택 후 OK 버튼을 누릅니다.
      2. View > LiveBindings Designer 메뉴를 통해 라이브 바인딩 디자이너를 표시하고, 아래 그림을 참고해 화면요소에 데이터를 연결합니다.(두 항목간 마우스로 드래그해 연결)

      도서 목록

      도서 상세보기

      새로운 도서 추가


      연결을 마치면 Live Bindings Designer를 닫습니다.(창 우측 상단 X 버튼)


      4, 사용자의 조작에 동작하는 기능코드를 작성합니다.

      사용자가 목록을 누르고 버튼을 누를때 동작하는 기능을 구현 합니다.

      화면(탭)이동 기능 구현

      1. 폼에 TActionList(ActionList1) 컴포넌트를 추가합니다.
      2. ActionList1을 더블클릭 후 Add Action > New Standard Action 메뉴를 선택 합니다.
      3. Tab > TChangeTabAction 항목 선택 후 OK 버튼을 눌러 추가합니다.
      4. 코드 에디터를 열고(폼 디자이너에서 F12 버튼) 선언부(코드 상단) private 영역에 아래 코드를 입력합니다.

          private
            { Private declarations }
            procedure GotoList;
            procedure GotoDetail;
            procedure GotoNew;
          public
            { Public declarations }
          end;
      5. 구현부(선언부 입력 후 Ctrl + Shift + C 단축키를 누르면 구현부의 구조가 자동 완성됩니다.)에 아래의 코드를 입력합니다.
        procedure TForm1.GotoDetail;
        begin
          ChangeTabAction1.Tab := TabItem2;
          ChangeTabAction1.ExecuteTarget(nil);
        end;
        
        procedure TForm1.GotoList;
        begin
          ChangeTabAction1.Tab := TabItem1;
          ChangeTabAction1.ExecuteTarget(nil);
        end;
        
        procedure TForm1.GotoNew;
        begin
          ChangeTabAction1.Tab := TabItem3;
          ChangeTabAction1.ExecuteTarget(nil);
        end;
      6. 도서 목록 탭에서 ListView1의 OnItemClick 이벤트에 아래의 코드를 입력[각주:3]합니다.

        procedure TForm1.ListView1ItemClick(const Sender: TObject;
          const AItem: TListViewItem);
        begin
          GotoDetail;
        end;
      7. 위 방식과 같이 아래의 표를 참고해 이벤트 핸들러 코드를 입력합니다.

        오브젝트 

        이벤트 

        소스코드 

         btnNewItem

         OnClick 

         GotoNew;

         btnBackList

         OnClick

         GotoList;
         btnCancel

         OnClick

         GotoList;

         btnSaveItem 

         OnClick

         GotoList;

      8. 폼을 선택하고 OnCreate 이벤트에 아래 코드를 입력합니다.(실행 시 탭을 감추고 첫번째 탭을 표시하는 코드입니다.)

        procedure TForm1.FormCreate(Sender: TObject);
        begin
          TabControl1.TabPosition := TTabPosition.None;
          TabControl1.TabIndex := 0;
        end;


      도서 상세정보 수정/삭제 팝업메뉴 구현

      1. 도서 상세정보 탭의 추가정보 버튼(btnDetail)과, 수정(lstItemModify), 삭제(lstItemDelete) 항목의 OnClick 이벤트에 아래를 참고해 코드를 추가합니다.

        procedure TForm1.btnDetailClick(Sender: TObject);
        begin
          OverflowMenu.Visible := not OverflowMenu.Visible;
          if OverflowMenu.Visible then
          begin
            OverflowMenu.ItemIndex := -1;
            OverflowMenu.BringToFront;
            OverflowMenu.ApplyStyleLookup;
            OverflowMenu.RealignContent;
            OverflowMenu.Position.X := Width - OverflowMenu.Width - 5;
            OverflowMenu.Position.Y := Toolbar2.Height;
          end;
        end;
        
        // 수정
        procedure TForm1.lstItemModifyClick(Sender: TObject);
        begin
          OverflowMenu.Visible := False;
          GotoNew;
        end;
        
        // 삭제
        procedure TForm1.lstItemDeleteClick(Sender: TObject);
        begin
          OverflowMenu.Visible := False;
        
          MessageDlg('해당 정보를 삭제하시겠습니까?', TMsgDlgType.mtWarning,
            [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 0, procedure(const AResult: TModalResult)
            begin
              if AResult = mrYes then
              begin
                ShowMessage('삭제');
              end;
            end);
        end;
      2. 폼을 선택하고 OnCreate 이벤트에 아래 코드를 추가합니다.

        procedure TForm1.FormCreate(Sender: TObject);
        begin
          TabControl1.TabPosition := TTabPosition.None;
          TabControl1.TabIndex := 0;
        
          OverflowMenu.Visible := False; // 시작 시 팝업메뉴 감추기
        end;

      입력 시 키보드가 가려지지 않도록 입력박스 위치조정 기능 구현

      하단의 입력박스에 입력 시 키보드가 입력박스를 가리는 경우 키보드 위로 입력박스 위치를 조정하는 기능을 구현합니다.

      1. 선언부 private 영역에 아래 코드를 입력합니다.
          private
            { Private declarations }
            FKBBounds: TRectF;
            FNeedOffset: Boolean;
        
            procedure CalcContentBoundsProc(Sender: TObject; var ContentBounds: TRectF);
            procedure RestorePosition;
            procedure UpdateKBBounds;
      2. 구현부에 아래의 코드를 입력합니다.
        procedure TForm1.CalcContentBoundsProc(Sender: TObject;
          var ContentBounds: TRectF);
        begin
          if FNeedOffset and (FKBBounds.Top > 0) then
          begin
            ContentBounds.Bottom := Max(
                  ContentBounds.Bottom, 2 * ClientHeight - FKBBounds.Top);
          end;
        end;
        
        procedure TForm1.RestorePosition;
        begin
          vsbEditFocus.ViewportPosition := PointF(vsbEditFocus.ViewportPosition.X, 0);
          lytContentsNew.Align := TAlignLayout.Client;
          vsbEditFocus.RealignContent;
        end;
        
        procedure TForm1.UpdateKBBounds;
        var
          LFocused : TControl;
          LFocusRect: TRectF;
        begin
          FNeedOffset := False;
          if Assigned(Focused) then
          begin
            LFocused := TControl(Focused.GetObject);
        
            LFocusRect := LFocused.AbsoluteRect;
            LFocusRect.Offset(vsbEditFocus.ViewportPosition);
            if (LFocusRect.IntersectsWith(TRectF.Create(FKBBounds))) and
               (LFocusRect.Bottom > FKBBounds.Top) then
            begin
              FNeedOffset := True;
              lytContentsNew.Align := TAlignLayout.Horizontal;
              vsbEditFocus.RealignContent;
              Application.ProcessMessages;
              vsbEditFocus.ViewportPosition := PointF(vsbEditFocus.ViewportPosition.X,
                                                      LFocusRect.Bottom - FKBBounds.Top);
            end;
          end;
          if not FNeedOffset then
            RestorePosition;
        end;
      3. 코드에서 수학함수(Max)를 사용하기 위해 구현부(implementation) uses 절에 System.math 유닛을 추가합니다.

        implementation
        
        {$R *.fmx}
        
        uses DataAccessModule, System.Math;
      4. 폼(Form1)의 OnFocusChanged, OnVirtualKeyboardShown, OnVirtualKeyboardHidden 이벤트에 아래 코드를 참고해 코드를 추가합니다.
        procedure TForm1.FormFocusChanged(Sender: TObject);
        begin
          UpdateKBBounds;
        end;
        
        procedure TForm1.FormVirtualKeyboardHidden(Sender: TObject;
          KeyboardVisible: Boolean; const Bounds: TRect);
        begin
          FKBBounds.Create(0, 0, 0, 0);
          FNeedOffset := False;
          RestorePosition;
        end;
        
        procedure TForm1.FormVirtualKeyboardShown(Sender: TObject;
          KeyboardVisible: Boolean; const Bounds: TRect);
        begin
          FKBBounds := TRectF.Create(Bounds);
          FKBBounds.TopLeft := ScreenToClient(FKBBounds.TopLeft);
          FKBBounds.BottomRight := ScreenToClient(FKBBounds.BottomRight);
          UpdateKBBounds;
        end;
      5. 폼의 OnCreate 이벤트에 아래 코드를 추가합니다.

        procedure TForm1.FormCreate(Sender: TObject);
        begin
          TabControl1.TabPosition := TTabPosition.None;
          TabControl1.TabIndex := 0;
        
          OverflowMenu.Visible := False;
        
          vsbEditFocus.OnCalcContentBounds := CalcContentBoundsProc; // 추가
        end;


      5, 전화걸기, 사진, 웹페이지 표시 기능 추가

      전화걸기, 사진 촬영, 불러오기, 웹페이지 표시 기능을 추가합니다.


      전화걸기 기능 추가하기

      1. 전화걸기 기능 사용을 위해 FMX.Platform과 FMX.PhoneDialer 유닛을 구현부(implementation) 유즈절에 추가합니다.

        implementation
        
        {$R *.fmx}
        
        uses DataAccessModule, System.Math, FMX.Platform, FMX.PhoneDialer;

      2. 도서 상세보기 탭의 lblPhone(연락처 항목)의 OnClick 이벤트 핸들러에 아래의 코드를 입력합니다.

        procedure TForm1.lblPhoneClick(Sender: TObject);
        var
          PhoneDlrSvc: IFMXPhoneDialerService;
        begin
          if TPlatformServices.Current.SupportsPlatformService(IFMXPhoneDialerService, IInterface(PhoneDlrSvc)) then
            PhoneDlrSvc.Call(lblPhone.Text);
        end;


      웹페이지 표시 기능, 사진 기능 추가하기

      웹페이지 기능과 사진 기능은 이미 구현된 소스코드를 다운받아 구현합니다.

      1. 카메라 기능, 웹브라우저 기능이 구현된 프레임 소스코드 를 다운로드 받고 압축 해제 후 프로젝트 파일(BookLogFMX.dpr) 저장경로의 하위에 Frames 폴더를 추가 후 Frames 폴더 안으로 복사합니다.

      2. Project Manager 윈도우에서 프로젝트 이름(BookLogFmx)에 마우스 오른쪽 팝업메뉴를 표시하고 Add... 메뉴를 선택 후 위 1번에서 복사한 "PhotoFrame.pas"를 선택 해 추가합니다.

      3. PhotoFrame 사용을 위해 구현부 uses절에 WebBrowserFrame, PhotoFrame을 추가합니다.

      4. "도서 상세보기" 탭의 lblWebSite(사이트 항목)의 OnClick 이벤트 핸들러에 아래의 코드를 입력합니다.

        procedure TForm1.lblWebSiteClick(Sender: TObject);
        begin
          TfrWebBrowser.CreateAndShow(Self, lblWebSite.Text);
        end;

      5. 선언부 private  영역에 아래의 메소드를 선언하는 코드를 추가합니다.

            procedure ChangeImageEvent(Image: TBitmap);

      6. 구현부에 아래의 코드를 추가합니다.

        procedure TForm1.ChangeImageEvent(Image: TBitmap);
        begin
          imgNewItem.Bitmap.Assign(Image);
        end;

      7. "새로운 도서 추가" 탭의 imgNewItem(사진)의 OnClick 이벤트 핸들러에 아래 코드를 입력합니다.

        procedure TForm1.imgNewItemClick(Sender: TObject);
        begin
          TfrPhoto.CreateAndShow(Self, ChangeImageEvent, nil);
        end;

      8. 안드로이드 백버튼을 누를때 기능이 닫히게 하기위해 폼(Form1)의 OnKeyUp 이벤트에 아래 코드를 입력합니다.
        procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
          Shift: TShiftState);
        begin
          if Key = vkHardwareBack then
          begin
            if Assigned(frPhoto) then
            begin
              frPhoto.CloseFrame;
              Key := 0;
            end;
        
            if Assigned(frWebBrowser) then
            begin
              frWebBrowser.CloseFrame;
              Key := 0;
            end;
          end;
        end;


      6, 사용자화면 완성! 테스트 하기

      1차 사용자화면 개발완료되었습니다. 

      • 배포를 원하는 플랫폼을 선택하고 Run > Run Without Debugging 메뉴를 통해 배포 및 실행합니다.
        (안드로이드 개발환경 설정은 앱메소드 튜토리얼 동영상을 통해 확인할 수 있습니다.)

      2차 따라하기에서는 실제 사용할 데이터베이스를 만들고 앱에서 데이터 연결하는 내용을 진행합니다.

      관련글


      1. TabItem 추가는 TabControl 더블클릭 후 나오는 Items Designer 대화상자에서 TTabItem 선택 후 [Add Item] 버튼을 눌러 추가 가능 [본문으로]
      2. ListBoxItem 추가는 ListBox컴포넌트 더블클릭 후 나타나는 Items Designer 대화상자에서 TListBoxItem을 선택 후 [Add Item] 버튼을 눌러 추가 가능 [본문으로]
      3. Object Inspector 창의 Event 탭으로 이동 후 OnItemClick 글자 옆의 공백을 더블클릭하면 이벤트 핸들러 코드가 자동추가 [본문으로]
      저작자 표시 비영리 동일 조건 변경 허락
      신고
      크리에이티브 커먼즈 라이선스
      Creative Commons License

      험프리.김현수 험프리.김현수 파이어몽키

      [XE7] 안드로이드에서 MessagDlg 사용방법(주의 점)

      2014.10.15 16:52

      사용자 의견을 묻기 위해 MessageDlg 함수를 많이 사용하는데요. 안드로이드에서 MessageDlg 사용 시 아래와 같인 메시지가 표시되어 해결방법 공유합니다.

      Blockin dialogs not implemented on this platform.

      ❑ 원인

      • 안드로이드에서는 블로킹 대화상자를 지원하지 않습니다.
      • 하지만 컴파일 시 오류가 나지 않기 때문에 구현 시 주의가 필요합니다.

      ❑ 해결방안

      • ACloseDialogProc 파라메터가 있는 MessageDlg 함수를 이용해야 합니다.
      • ACloseDialogProc은 MessageDlg에서 버튼을 누른 이후의 동작을 가진 익명메소드 입니다.
      • 아래 예제를 참고하세요.

      MessageDlg('Choose a button:', System.UITypes.TMsgDlgType.mtInformation,
          [
            System.UITypes.TMsgDlgBtn.mbYes,
            System.UITypes.TMsgDlgBtn.mbNo,
            System.UITypes.TMsgDlgBtn.mbCancel
          ], 0,
            procedure(const AResult: TModalResult)
            begin
              case AResult
                of
                { Detect which button was pushed and show a different message }
                mrYES:
                  ShowMessage('You chose Yes');
                mrNo:
                  ShowMessage('You chose No');
                mrCancel:
                  ShowMessage('You chose Cancel');
              end;
      
            end
      
          );

      • 해당 이슈는 블로킹 형태의 대화상자(InputBox, InputQuery, MessageDlg, ShowMessage) 모두가 해당 됩니다.


      참고



      저작자 표시 비영리 동일 조건 변경 허락
      신고
      크리에이티브 커먼즈 라이선스
      Creative Commons License

      험프리.김현수 험프리.김현수 파이어몽키

      1. Blog Icon
        정상언

        MessageDlg 함수의 버튼의 캡션 "Yes", "No", "Cancel" 을
        한글로 "예", "아니오", "취소" 로 나타낼 방법이 있나요?