파이어몽키로 안드로이드 앱 개발 시 장치에 접근하는 기능(예, 카메라 이용, 블루투스 이용 등) 개발 시 권한 설정이 필요합니다.

 

기존에는 Project > Options > Uses Permissions에서 필요한 권한을 설정하는 방식이었지만, 

안드로이드 API 최신버전은 런타임 시 권한을 요청하는 매커니즘으로 변경되었습니다.

 

기존의 권한 모델은 설치 시 전체 권한을 승인하는 방식이었습니다. 새로운 권한 모델은 기능 사용 시 개별 권한을 묻는 방식으로, 사용자는 기능 별 허용 및 거부가 가능해졌습니다.

기존 권한 요청 방식 새로운 권한 요청 방식

새로운 권한 요청 방식은 RAD 스튜디오 10.3 부터 적용되며, 

기존에 작성했던 안드로이드 프로젝트는 권한 요청하는 로직을 추가하도록 업데이트 해야 합니다.

 

안드로이드의 권한 요청 로직

안드로이드 권한 요청은 System.Permissions.pas에 구현된 PermissionsService.RequestPermissions 메소드를 호출하는 것으로 시작합니다.

 

다음 코드는 델파이 샘플 중 Location(Object Pascal/Mobile Snippets/Location)의 일부입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedure TLocationForm.swLocationSensorActiveSwitch(Sender: TObject);
begin
{$IFDEF ANDROID}
  if swLocationSensorActive.IsChecked then
    PermissionsService.RequestPermissions([JStringToString(TJManifest_permission.JavaClass.ACCESS_FINE_LOCATION)],
      procedure(const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>)
      begin
        if (Length(AGrantResults) = 1) and (AGrantResults[0] = TPermissionStatus.Granted) then
          { activate or deactivate the location sensor }
          LocationSensor1.Active := True
        else
        begin
          swLocationSensorActive.IsChecked := False;
          TDialogService.ShowMessage('Location permission not granted');
        end;
      end)
  else
{$ENDIF}
    LocationSensor1.Active := False;
end;

위코드에서는 TLocationsSensor 즉, GPS 연동하는 코드 전에 안드로이드인 경우({$IFDEF ANDROD}) 위치 권한(TJManifest_permission.JavaClass.ACCESS_FINE_LOCATION)을 요청하는 코드가 추가되었습니다.

 

RequestPermissions 메소드의 파라메터는 다음과 같습니다.

1
2
3
procedure RequestPermissions(const APermissions: TArray<string>;
  const AOnRequestPermissionsResult: TRequestPermissionsResultEvent;
  AOnDisplayRationale: TDisplayRationaleEvent = nil); overload; virtual;

첫번째 파라메터는 요청하는 권한 문자열 배열, 두번째는 권한 요청 결과를 받아볼 수 있는 메소드, 세번째는 사용자에게 권한에 대한 안내를 할 수 있는 메소드입니다.

 

델파이 샘플의 AccessCameraApp의 코드에는 권한요청하는 로직이 다음과 같이 구현되어 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
procedure TAccessCameraAppForm.btnTakePhotoClick(Sender: TObject);
begin
  PermissionsService.RequestPermissions(
    [FPermissionCamera, FPermissionReadExternalStorage, FPermissionWriteExternalStorage],
    TakePicturePermissionRequestResult,
    DisplayRationale
  )
end;
 
// Optional rationale display routine to display permission requirement rationale to the user
procedure TAccessCameraAppForm.DisplayRationale(Sender: TObject; const APermissions: TArray<string>; const APostRationaleProc: TProc);
var
  I: Integer;
  RationaleMsg: string;
begin
  for I := 0 to High(APermissions) do
  begin
    if APermissions[I] = FPermissionCamera then
      RationaleMsg := RationaleMsg + 'The app needs to access the camera to take a photo' + SLineBreak + SLineBreak
    else if APermissions[I] = FPermissionReadExternalStorage then
      RationaleMsg := RationaleMsg + 'The app needs to read a photo file from your device';
  end;
 
  // Show an explanation to the user *asynchronously* - don't block this thread waiting for the user's response!
  // After the user sees the explanation, invoke the post-rationale routine to request the permissions
  TDialogService.ShowMessage(RationaleMsg,
    procedure(const AResult: TModalResult)
    begin
      APostRationaleProc;
    end)
end;
 
procedure TAccessCameraAppForm.TakePicturePermissionRequestResult(Sender: TObject; const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>);
begin
  // 3 permissions involved: CAMERA, READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE
  if (Length(AGrantResults) = 3)
      and (AGrantResults[0] = TPermissionStatus.Granted)
      and (AGrantResults[1] = TPermissionStatus.Granted)
      and (AGrantResults[2] = TPermissionStatus.Granted) then
    TakePhotoFromCameraAction1.Execute
  else
    TDialogService.ShowMessage('Cannot take a photo because the required permissions are not all granted')
end;

1) 3가지 권한을 요청합니다.

2) DisplayRationale 메소드에서 필요한 권한에 대해 설명합니다.

3) 요청결과 메소드에서 권한일 모두 허용한 경우 기능을 실행합니다.

 

위에서 주의할 점은, 

권한에 대한 설명 시(DisplayRationale 메소드) 메시지 호출 후 비동기로 APostRationaleProc 메소드를 호출해야 합니다.

그리고, 권한에 대한 설명 메소드는 옵션으로 생략할 수 있습니다.

 

위 내용을 참고해 권한이 필요한 기능을 개발하는 경우 해당 기능 호출 전 권한을 요청하도록 추가 및 기존 코드를 변경하시기 바랍니다.

해당 기능은 안드로이드 앱 개발 시 적용해야 하는 기능으로, 다른 플랫폼 앱 개발 시 생략할 수 있습니다.

 

엠바카데로에서 제공하는 내용과 이미 적용된 샘플 앱의 목록은 다음 링크에서 확인할 수 있습니다.

 

다음 글들이 안드로이드 권한 모델 적용 내용이 업데이트 되었습니다.

번호 제목 글쓴이 날짜 조회 수
공지 [DelphiCon 요약] 코드사이트 로깅 실전 활용 기법 (Real-world CodeSite Logging Techniques) 관리자 2021.01.19 18053
공지 [UX Summit 요약] 오른쪽 클릭은 옳다 (Right Click is Right) 관리자 2020.11.16 16385
공지 [10.4 시드니] What's NEW! 신기능 자세히 보기 관리자 2020.05.27 19012
공지 RAD스튜디오(델파이,C++빌더) - 고객 사례 목록 관리자 2018.10.23 24632
공지 [데브기어 컨설팅] 모바일 앱 & 업그레이드 마이그레이션 [1] 관리자 2017.02.06 25993
공지 [전체 목록] 이 달의 기술자료 & 기술레터 관리자 2017.02.06 21371
공지 RAD스튜디오(델파이, C++빌더) - 시작하기 [1] 관리자 2015.06.30 41961
공지 RAD스튜디오(델파이,C++빌더) - 모바일 앱 개발 사례 (2020년 11월 업데이트 됨) 험프리 2014.01.16 177254
963 브레이크 포인트를 설정해도 디버깅이 안되는 경우 살펴볼 항목 file 험프리 2016.05.13 2865
962 [도서/PDF/소스코드] 시작하는 사람들을 위한 델파이 프로그래밍-모듈 21. 2차원 배열들 관리자 2019.03.29 2853
961 델파이, 25년의 혁신 - 버전 1부터 10.3까지 버전별 핵심 기능 [2] 관리자 2020.05.12 2837
960 [다음 버전 정보] 비콘(Beacon)으로 접근감지하기 Humphery 2015.03.26 2802
959 모바일 앱 개발 시 툴 선택 file Humphery 2014.04.29 2798
958 코드사이트(CodeSite)로 로그를 기록하며 프로그램의 문제를 파악할 수 있습니다. file 험프리 2016.05.26 2751
957 [델파이7 이후 새로운 기능] 코딩 생산성을 높여주는 코드에디터 기능들 Humphery 2015.04.21 2743
956 엔터프라이즈 데이터 기반의 모바일 앱 과정(2일) 우선 등록 안내 관리자 2013.11.21 2725
955 [10.3 리오] 델파이 언어의 새로운 변화: 인라인 변수 선언 관리자 2018.11.12 2715
954 GPS좌표 이용 날씨정보앱 런칭. file c2design 2014.07.15 2703
953 블루투스 바코드 스캐너(BI-07) 안드로이드 라이브러리를 델파이에서 연동하는 방법 [1] file 험프리 2017.03.24 2698
952 암호화 라이브러리 LockBox 컴포넌트 사용하기 [3] file 험프리 2019.02.18 2689
951 FM(파이어몽키) 애플리케이션에서 StyledSettings 활용하기 관리자 2013.12.27 2687
950 [마이그레이션][팁] 배치파일(커맨드 명령어)을 이용해 손쉽게 소스파일 갯수를 파악할 수 있습니다. file 험프리 2015.11.12 2664
949 델파이 문법을 익힐 수 있는 문서모음 [2] Humphery 2014.11.03 2664
948 [업데이트][hotifx] RAD Studio XE5 Update 2 Hotfix 6(iOS SDK 7.1 and XCode 5.1 대응) [1] Humphery 2014.05.08 2650
947 델파이를 이용해 구글크롬캐스트와 연결 Humphery 2014.07.22 2636
946 C++ Builder에서 64 비트 Windows 용 패키지를 지원 Humphery 2014.07.04 2633
945 COM 오브젝트 연동 유닛 생성하기: Import a Type Library file 험프리 2016.09.30 2625
944 [REST API] MAC(Message Authentication Code)/HMAC 델파이로 구현하기 험프리 2019.01.14 2623