Side Projects - Electronics Photo Frames
사진 앱에서 사진을 선택해 추가하고, 가로 화면으로 액자처럼 사진이 하나씩 넘어가는 기능을 구현한 간단한 프로젝트
- GitHub Repository-> https://github.com/hwayeon351/Electronic-Picture-Frames
학습 회고
오늘은 전자액자 앱이라는 새로운 프로젝트를 시작했다.
전자액자 앱에서 사용자가 사진 앱에서 선택한 사진을 받아와서 액자처럼 가로 화면에서 하나씩 사진이 천천히 넘어가는 기능을 구현할 것이다.
레이아웃을 설정해서 사진 추가하기 버튼과 전자액자 실행하기 버튼을 추가하고, 두 개의 LinearLayout을 이용해 6개의 ImageView를 격자 형식으로 보여주도록 설정하였다.
또한, 사진을 가져오기 위한 권한을 설정해서 전자액자 앱에서 사용자의 사진 앱으로 연결하여 사진을 불러오는 기능까지 구현하였다.
오늘 공부한 내용
- 앱 권한 요청
전자 액자 앱을 사용하기 위해서 사용자의 사진 앱에 접근해서 사진을 가져와야 하고, 이 경우 android.permission.READ_EXTERNAL_STORAGE 권한이 필요하다.
1. Menifest 파일에 <uses-permission> 요소를 넣어 앱에서 필요한 권한을 선언한다.
2. 사용자가 권한이 필요한 데이터에 접근해야 하는 앱의 작업을 호출할 때까지 기다렸다가 호출된 경우 런타임 권한을 부여했는지를 확인한다.
앱에 이미 권한이 부여되었는지를 ContextCompat.checkSelfPermission() 매서드를 통해 확인한다.
매개변수로는 Context와 확인하고자 하는 권한을 String형으로 받는다.
권한이 있는 경우에는 PERMISSION_GRANTED, 없는 경우에는 PERMISSION_DENIED를 반환한다.
3. 2.에서 PERMISSION_DENIED를 반환한 경우, 즉, 권한이 부여되어 있지 않은 경우, shouldShowRequestPermissionRationale()를 호출하여 true를 반환하면 사용자에게 교육용 팝업을 띄운다.
여기에서 사용자에게 특정 런타임 권한을 요청하는 이유를 설명해야 한다.
어떤 이유로 앱이 권한이 필요한 데이터에 액세스하려고 하는지, 런타임 권한을 부여하면 앱이 사용자에게 제공할 수 있는 것이 무엇인지를 UI 요소로 명확하게 설명한다.
전자액자 앱에서는 외부 저장소를 읽어 사진 앱에 접근하여 사용자 기기에 저장된 사진을 불러와서 액자 기능을 제공할 것이기 때문에 이를을 나타내주기 위해 AlertDialog를 사용해서 표현하였다.
4. 앱에서 비공개 사용자 데이터에 접근하기 위해 필요한 런타임 권한을 요청한다.
requestPermissions() 매서드를 호출해서 권한을 요청할 수 있다.
이때, 매개변수에 요청하고자 하는 권한과 요청코드를 입력한다.
요청에 관한 결과를 콜백하는 onRequestPermissionsResult()에서 해당 코드로 어떤 요청인지를 구별할 수 있다.
5. 권한 요청에 관한 사용자의 응답을 확인한다.
사용자가 시스템 권한 대화상자에 응답을 하면 시스탬은 앱의 onRequestPermissionsResult()를 호출한다.
이때, 시스템은 사용자 응답과 이전에 정의한 요청 코드를 전달한다.
요청코드에 대한 권한을 사용자가 응답한 경우, 사진 데이터를 불러오는 navigatePhotos() 함수를 호출한다.
https://developer.android.com/training/permissions/requesting?hl=ko#request-permission
- Intent를 사용해서 사진 데이터 가져오기
전자액자 앱에서 사진 앱에 있는 사진을 가져오기 위해서는 Intent 객체를 이용해 사진 앱을 실행시키고 onActivityResult() 콜백 메서드를 통해 결과를 받아올 수 있다.
1. Intent
Intent는 메시징 객체로, 다른 앱 구성 요소로부터 작업을 요청할 때 사용할 수 있다. Intent 객체에는 안드로이드 시스템이 어떤 구성 요소를 시작할지를 판별하는 데에 사용하는 정보가 담겨있다.
인텐트로 구성 요소 사이의 통신을 하는 목적에는 여러가지가 있지만 기본적으로 크게 3가지로 나눌 수 있다.
- 액티비티 시작
Activity는 앱의 단일 화면이다. 새로운 Activity를 시작하기 위해서는 Intent를 startActivity()로 담아서 전달하면 된다.
Intent는 시작할 액티비티를 설명하고 모든 필수 데이터를 담는 역할을 한다.
액티비티가 완료되고 결과를 수신하려면 startActvityForResult()를 호출하면 되고, 액티비티는 그 결과를 onActivityResult() 콜백에서 Intent 객체로 수신할 수 있다.
- 서비스 시작
Service는 사용자 인터페이스 없이 백그라운드에서 작업을 수행하는 구성 요소이다. 서비스를 시작하고 작업을 수행하도록 하기 위해서 Intent를 startService()에 전달하면 된다. 이때 Intent에는 시작할 서비스를 설명하며 모든 필수 데이터들을 담고 있다.
- 브로드캐스트 전달
Broadcast는 모든 앱이 수신할 수 있는 메세지이다. 시스템은 시스템이 부팅될 때나 충전을 할 때와 같은 다양한 시스템 이벤트에 대해 브로드케스트를 전달한다. 이때 Intent를 sendBroadcast()나 sendOrderedBroadcast()에 전달하면 다른 앱에 브로트캐스트를 전달할 수 있다.
Intent의 유형에는 두 가지가 있다.
- 명시적 인텐트
명시적 인텐트는 일반적으로 앱 내의 구성 요소를 시작할 때 사용한다. 시작하고자 하는 액티비티나 서비스의 클래스 이름을 알고 있기 때문이다.
- 암시적 인텐트
암시적 인텐트는 수행해야하는 작업을 선언해서 다른 앱의 구성 요소가 작업을 수행할 수 있도록 한다. 예를 들어, 지도에 위치를 표시하고자 하는 경우에 암시적 인텐트를 사용해서 해당 기능을 갖춘 다른 앱이 위치를 지도에 표시하도록 요청할 수 있다.
암시적 인텐트를 startActivity()에 전달하면 Android 시스템에서 이를 시작할 적절한 구성 요소를 찾는다.
이때 인텐트의 내용을 기기에 있는 다른 여러 앱의 매니페스트 파일에 선언되어 있는 인텐트 필터와 비교하는 방법으로 찾게 된다.
해당 인텐트와 일치하는 인텐트 필터가 존재하면 시스템에서 해당 구성 요소를 시작하고 Intent 객체를 전달한다.
만약, 호환되는 인텐트 필터가 여러 개인 경우에는 시스템에서 대화상자를 표시해서 사용자가 어느 앱을 사용할 것인지 직접 선택할 수 있도록 한다.
* 인텐트 필터는 앱의 매니페스트 파일에 들어있는 표현이고, 해당 구성 요소가 수신하고자 하는 인텐트의 유형을 나타낸다.
Intent는 다른 앱에서 액티비티를 시작할 수 있도록 해준다. startActivity()나 startActivityForResult()를 호출해서 암시적 인텐트를 전달하면 시스템은 이를 처리할 수 있는 앱을 찾아서 실행시킨다.
만약, Intent를 처리할 수 있는 앱이 하나 이상인 경우에는 시스템에서 앱을 선택할 수 있는 대화상자를 사용자에게 표시하기도 한다.
https://developer.android.com/guide/components/intents-filters?hl=ko
전자액자 앱에서 사진 앱을 실행시켜 사진 데이터를 가져오는 작업을 암시적 인텐트에 지정해서 해당 작업을 수행할 수 있는 앱에 전달해서 사진 데이터를 가져오도록 할 수 있다.
이때, 사용자에게 문서나 사진 등의 파일을 선택해서 앱으로 반환하도록 요청하기 위해 ACTION_GET_CONTENT 작업을 사용하고 원하는 MIME 유형을 지정해야 한다.
onActivityResult() 메서드에 전달된 결과 인텐트를 통해 사용자가 선택한 파일을 가리키는 URI를 받을 수 있다.
https://developer.android.com/guide/components/intents-common?hl=ko
'Android > Side Projects' 카테고리의 다른 글
Pomodoro Timer 앱 개발하기 (0) | 2022.01.29 |
---|---|
전자 액자 앱 개발하기 (0) | 2022.01.28 |
계산기 앱 개발하기 (0) | 2022.01.26 |
계산기 앱 개발하기 (0) | 2022.01.25 |
계산기 앱 개발하기 (0) | 2022.01.24 |