마시멜로우(Marshmallow) 대응기 : Requesting Permissions at Run Time
안녕하세요. 망고플레이트의 신문규입니다. 이번 글은 안드로이드의 새버전인 마시멜로우를 대응했던 이야기를 적어보려고 합니다. 많은 기능들 중에서 Runtime Permission을 요청하는 것에 대한 이야기를 해보려고 합니다. 아마 많은 서비스에서 수정해야 하는 부분이라 공감하실 수 있을 거예요.
마시멜로우 어느정도 사용하고 있을까요?
들어가기 전에 한번 마시멜로우를 얼마나 사용하고 있는지 알아볼까요? 안드로이드 대시보드 사이트에 가면 버전별 일주일 동한 사용한 사람들의 비율이 나와있습니다. 마시멜로우는 어느정도나 될까요? 대략적으로 마시멜로우 버전을 사용하는 사람이 1%가 되었다네요! LG전자의 G4, G3는 이미 마시멜로우 업데이트가 가능한 상태입니다. 게다가 갤럭시 S6를 비롯한 삼성전자의 스마트폰들은 올해 1분기 내에 모두 업데이트를 제공할 계획이라고 합니다. 이정도면 얼른 서비스를 마시멜로우에 대응해야 겠다는 생각이 들지요? 이제 이야기를 시작하겠습니다.
Runtime Permission 이란?
마시멜로우 관련 자료들을 보면 많은 내용들이 Permission관련 내용들입니다. 그만큼 다양한 서비스들에 적용할 수 있는 부분이라는 것이겠죠?
기존에는 앱 설치시에 AndroidManifest 파일에 명시해 놓은 Permission을 허용하면 되었습니다. 달라진 부분은 확인 과정 없이 설치가 간편하게 진행이 되고, 관련 기능을 실행하려고 하면 Permission을 사용자에게 얻어야 합니다. 물론 모든 Permission 에 적용되는 것은 아니고, Protection level 이 Dangerous 라면 요청해야 합니다. 따라서 먼저 Permission을 확인하고 Permission을 획득한 후 진행 될 수 있도록 변경되어야 합니다. 그렇지 않으면 강제 종료될 수 있습니다.
망고플레이트에서 필요한 Permissions
어떤 기능이 Permission과 연관되어있는지 알아보도록 할께요. 이렇게 정리를 하고 시작하면 도움이 될 수 있을 거예요.
- 위치정보 : 망고플레이트에서 가장 중요한 기능은 맛있는 식당 정보를 알려주는 것이겠죠? 특히 내 주변에 있는 식당에 대해서 알아보려면 현재 위치정보가 필요합니다.
- 갤러리 : 리뷰를 적을려면 맛있게 먹은 요리사진을 업로드 하고 싶겠죠? 갤러리에 있는 사진 목록을 가져올 때면 알맞은 Permission을 요청해야 합니다.
처음에는 “어떻게 모두 대응하지?” 라고 할만큼 막막했었는데 정리하고 보니 깔끔해졌습니다. 이제 즐거운 기분으로 작업할 수 있을 것 같아요!
위치정보 (Location)
위치정보는 망고플레이트에서 매우 중요한 정보입니다. 일단 사용하는 경우를 알아볼까요?
- 주변 식당리스트 검색
- 검색 결과 거리순으로 정렬.
- ‘가고싶다’ 한 식당들 혹은 체크인, 리뷰들을 필터링.
- 식당 지도화면에서 현재 위치 표시.
주로 사용자들이 원하는 식당을 가기 위해 찾는 과정들이네요. 망고플레이트를 처음 켰을때 부터 접하는 기능이기도 하고요. 이 글을 읽으시면서 한번 망고플레이트를 사용해보시길 바랍니다. 좀 더 이해가 잘되실 거예요.
언제 Permission을 요청하는 것이 좋을까요?
Permission을 얻을때에는 어떤 것을 요청하는 것인지 다이얼로그로 보여지기 때문에 그 자체만으로 사용자들이 불편해 할 수 있습니다.
예를 들어 검색을 하고나서 나중에 ‘거리순 정렬’을 할 수도 있으니, 바로 Permission을 요청해보겠습니다. 그렇다면 유저는 뜬금 없다고 느낄 수 있습니다. 유저가 생각했을때 검색했는데 위치정보가 필요한지 이해를 못하기 때문입니다. 그러니 정말 ‘거리순 정렬하기’ 버튼을 눌렀을때 Permission 을 요청하는 것이 사용자들의 불편함을 최소화할 수 있는 방법임을 꼭 기억해주세요.
Permission에 대한 설명이 필요하다면 어떻게 할까요?
Permission 을 요청할때 어째서 필요한지 설명할 필요가 있을 수 있습니다. 이럴때를 대비해서 shouldShowRequestPermissionRationale() 메서드가 있습니다. 이 메서드는 Permission을 설명이 필요한 지를 반환합니다. 사용자가 이미 Permission 요청을 받았을때 거절하고 Don’t ask again 옵션을 선택했다면 false 가 반환되는 것이죠.
Activity 에서 Permission 요청하기
Activity에서 requestPermission()을 호출하는 방법은
- android.app.Activity 의 requestPermission()
- android.support.v4.app.ActivityCompat 의 requestPermission()
두가지 방법이 있습니다. 망고플레이트는 Minimum sdk version을 14까지 지원하고 있어서 하위버전 호환이 필요합니다. 따라서 support library 에 구현되어 있는 두번째 방법을 사용해야 겠습니다.
ActivityCompat의 메서드는 세가지 Argument를 가지고 있습니다.
- this : this는 코드가 실행되고 있는 Activity 입니다. 내부에서 현재 빌드 SDK 버전을 확인한 후에 그에 맞는 메서드를 실행할때 필요합니다.
- String Array : 요청할 Permission 들이 담긴 배열입니다.
- RequestCode : Callback 메서드에서 식별할 Activity 안에서 유일한 값입니다.
만약 최신 버전만 지원하도록 제작중이시라면 android.app.Activity의 requestPermissions() 를 바로 호출하셔도 됩니다.
Callback 메서드에서 어떤 것을 하는지 볼까요?
ACCESS_FINE_LOCATION 과 ACCESS_COARSE_LOCATION 이 허용되었다면 이후의 위치정보를 요청하는 시나리오를 진행하면 됩니다.
갤러리 (Gallery)
갤러리의 사진에는 MediaStore.Images.Media 의 EXTERNAL_CONTENT_URI 를 사용해서 접근할 수 있습니다. 결국 외부 저장공간을 이용해야 하기 때문에 READ_EXTERNAL_STORAGE permission이 필요합니다.
Fragment 에서 Permission 요청하기
Location 예시와는 다르게 이곳에서는 Argument 가 두개네요? Fragment 환경에서requestPermission()을 요청하는 방법은 다음과 같습니다.
- android.app.Fragment 의 requestPermission()
- android.support.v4.app.Fragment 의 requestPermission()
- android.support.v13.app.FragmentCompat 의 requestPermission()
만약 android.app.Fragment 를 사용해서 구현했는데, 호환이 필요하다면 3번을 사용해서 구현하는 것이 좋겠습니다. 이때 주의하실 점은 FragmentCompat.OnRequestPermissionsResult()를 꼭 구현해야 한다는 점입니다. 망고플레이트에서는 처음부터 support library v4를 사용해서 구현되어 있기 때문에 2번 방법을 사용했습니다.
도움이 되셨나요?
벌써 글을 마무리할 시간이네요. 이번 글은 망고플레이트의 개발 이야기 두번째 글이었습니다. 첫번째 글(Coming Home: Moving Servers from Tokyo to Seoul)과 다르게 좀 더 기술적인 이야기를 많이 해봤습니다. 특히나 Runtime Permission 을 대응하는 작업은 꼼꼼함이 요구되는 작업이었네요. 그래서 덕분에 망고플레이트에서 관련 시나리오가 어떤 것이 있는지 정리해보고, 또 어떻게 수정하는 것이 자연스러운지 고민도 해볼 수 있었던 것 같습니다.
더 해보고 싶은 것이 있다면…?
망고플레이트는 사실 많은 종류의 Permission을 다 대응하지는 않았지만, 코드를 작성하기 위해서 여러 레퍼런스를 읽어보고 주의할점 및 개념을 잡아 나갔었습니다. 현재 개발자 사이트에서 Working with System Permissions 가이드를 제공하지만 그것은 전체적인 작업 흐름에 대한 이야기고, 하나하나 개발하려다 보면 꼼꼼히 체크해야만 했습니다.
사실 이 글을 적는 것도 저희랑 비슷한 로컬기반 서비스를 개발하시는 분이시라면 같은 작업을 할 것이라는 생각에 적은 것이기 때문에, 좀 더 바로 써먹을 수 있는 예제를 제공하는 것이 목표였습니다. 목표만큼 좋은 글인가요? 더 나아가 모든 Permission들에 대해 정리하게 되면, 매우 유용하고 좋은 예제가 될 수 있을 것 같습니다.
여러분들의 Permission 대응 경험담도 들려주세요.
긴 글 읽어주셔서 고맙습니다. :)