Android App/Kotlin

앱 권한(Permission)-위험권한 처리, registerForActivityResult()사용(런처, 컨트랙트)

AppJinny 2022. 11. 17. 04:38

*앱 권한(Permission)-위험권한 처리, registerForActivityResult() 사용(런처, 컨트랙트)

-위험권한(Dangerous Permission)

-앱이 사용자 개인정보와 관련된 데이터나 기능을 액세스 또는 다른 앱 및 기기 작동에 영향을 줄 우려가 있는 권한

-Gradle Scripts - build.gradle(Module:) - targetSdk 버전이 23 이상 설정돼야 정상 동작됨

-안드로이드 6.0(API 23)부터 위험권한 사용 : 설정파일 (AndroidManifest.xml)에 권한명세 하고 소스코드에 권한 요청 및 처리 로직 작성 필요

--설정파일 권한 명세 : 일반권한과 똑같이 명세, <permission android:name="" /> 태그 사용

--소스코드 처리 : 결과값 처리를 위한 registerForActivityResult() 메서드 사용

 

*위험권한 처리의 소스코드 처리-registerForActivityResult()사용

-결과값 처리를 위한 registerForActivityResult() 사용

-registerForActivityResult : 액티비티 이외에도 컨트랙트 종류에 따라 안드로이드의 기본기능(카메라, 갤러리) 사용가능

-권한을 다루는 컨트랙트 사용 시 권한 요청 팝업을 띄우고 승인 여부에 대한 결과 처리 가능

-registerForActivityResult() 메서드로 ActivityResultLauncher 런처를 생성하여 사용

 

*registerForActivityResult()메서드 사용하기

*ActivityResultLauncher(런처), ActivityResultContracts(컨트랙트)

-registerForActivityResult() 에 정해진 컨트랙트(ActivityResultContracts)를 담아 호출 시 런처(ActivityResultLauncher) 생성됨

-registerForActivityResult() 에 입력된 컨트랙트 종류에 따라 런처의 제네릭 타입 결정됨

-생성과 동시에 변수에 저장할 때는 타입 자동 결정

-전역변수로 미리 선언시에는 컨트랙트 종류에 따라 변수 타입의 제네릭 또한 변경되어 용도에 맞는 제네릭선언 해야함

 

*ActivityResultContracts(컨트랙트)

-사용되는 컨트랙트 종류에 따라 미리선언하는 변수 제네릭 뿐만 아니라 launch()에 입력되는 파라미터 타입도 결정

-권한 처리 컨트랙트(RequestPermission(), 타입 : String)

--승인 처리를 위해 1개의 파라미터를 문자열로 런처에 입력

--RequestMutiplePermission() 사용 시 배열로 입력함

--결과값 isGranted : 별칭으로 바꿔서 사용함, 기본변수명 it

권한 처리 컨트랙트, 타입

-카메라 호출 컨트랙트(TakePicture() , 타입 : Uri)

-이미지 갤러리 호출 컨트랙트(GetContent(), 타입 : "image/*")

-PDF문서 목록 호출 컨트랙트(GetContent(), 타입 : "application/pdf")

-ActivityResultContracts(컨트랙트)의 종류

 

 

*권한 요청이 필요한 앱 개발할 경우 권한 요청 처리 흐름

-사용할 권한 정의

-설치한 앱이 사용하는 권한의 보호수준확인

-위험권한일 때

-앱 실행시간에 사용자에게 권한 승인 요청

-승인되었을 경우에만 코드 실행

 

 

*registerForActivityResult()을 사용하여 카메라 권한 퍼미션 받아오기

 

-build.gradle

-- android{} 에 뷰바인딩 추가

--dependencies {} 확인

//뷰바인딩
buildFeatures{
    viewBinding true
}
	//registerForActivityResult 관련 의존성 - 업데이트 되면서 추가가 필요하지 않게됨
//    def dependency_version = "1.3.1"
//    implementation "androidx.activity:activity-ktx:$dependency_version"
//    implementation "androidx.fragment:fragment-ktx:$dependency_version"

 

-MainActivity.kt

class MainActivity : AppCompatActivity() {

    //뷰바인딩
    val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }

    //3
    //권한요청런처 만들기
    //3-1
    //권한을 처리하는 프로퍼티 선언 : onCreate 바깥 전역변수로 만듦
    //권한처리 컨트랙트(RequestPermission())는 파라미터로 하나의 문자열 사용하므로 런처의 제네릭은 String 정의
    lateinit var activityResult: ActivityResultLauncher<String>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //뷰바인딩
        setContentView(binding.root)

        //3-2
        //registerForActivityResult()를 런처로 만들어 미리선언한 전역변수 activityResult에 저장
        activityResult = registerForActivityResult(ActivityResultContracts.RequestPermission()){ isGranted ->

            //3-3
            //결과값의 승인 결과(it -> isGranted(별칭으로 변경))의 타입은 Boolean 이므로 결과는 true, false로 반환
            //카메라 권한이 승인(true)라면 startProcess() 호출하여 카메라 실행 (startProcess()메서드는 따로 만들것임)
            //미승인(false)라면 finish() 호출하여 앱 종료
            if (isGranted){
                startProcess()
            }else{
                finish()
            }

        }

        //4
        //사용자에게 승인 요청
        //카메라 버튼을 클릭하면 승인요청의 런처를 실행하는 코드 작성
        //4-1
        //런처의 속성 launch()의 파라미터에는
        //앞에서 작성한 설정파일(AndroidManifest.xml)에 명세했던 카메라 권한 1개만 넘겨주면 됨
        binding.btnCamera.setOnClickListener {
            activityResult.launch(android.Manifest.permission.CAMERA)
        }

        //FIN.
        //카메라 버튼을 클릭하면 권한요청 팝업창이 생성되고 승인 시 토스트 메시지 출력

        //1
        //위험권한 처리하기 : 카메라 권한 사용 시
        //설정파일(AndroidManifest.xml)을 수정한 다음 소스코드에도 추가로 처리함

        //1-1
        //buid.gradle에서 뷰바인딩 설정하고 사용할 registerForActivityResult의 의존성 확인
        //설정파일(AndroidManifest.xml) 명세하기
        //app - manifests 디렉터리 밑 - AndroidManifest.xml - 카메라 권한 추가

        //2
        //위험권한 처리의 소스코드 처리
        //결과값 처리를 위해 registerForActivityResult 사용
        //registerForActivityResult : 액티비티 이외에도 컨트랙트 종류에 따라 안드로이드의 기본기능 사용가능(카메라, 갤러리)
        //또한 권한을 다루는 컨트랙트 사용 시 권한 요청 팝업을 띄우고 승인 여부에 대한 결과 처리 가능
        //기본 사용 방법 : registerForActivityResult() 메서드 파라미터에
        //ActivityResultContracts.컨트랙트 종류를 사용하여 컨트랙트에 맞는 타입의 ActivityResultLauncher 런처 생성
        //런처 실행 시 메서드에 작성한 코드 블록이 실행되는 구조

    }//onCreate

    //3-4
    //카메라 실행을 승인 했을 때 실행할
    //startProcess()메서드 생성
    fun startProcess(){
        //3-5
        //승인이면 프로그램을 진행한다는 메시지를 띄움
        Toast.makeText(this, "카메라를 실행합니다.", Toast.LENGTH_SHORT).show()
    }

}//MainActivity

 

-AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

<!--  카메라 권한 추가  -->
<!--  <uses-permission /> 태그 사용!!***  -->
    <uses-permission android:name="android.permission.CAMERA"/>

<!--  카메라 권한 추가 후 권한 요청버튼 생성 : activity_main.xml  -->

 

-activity_main.xml 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

<!--  텍스트 뷰 텍스트 수정, 버튼 추가  -->
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="144dp"
        android:text="위험 권한"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnCamera"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="카메라"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

<!--  소스코드에서 위험권한 처리 : MainActivity.kt  -->

</androidx.constraintlayout.widget.ConstraintLayout>

 

-결과

 

 

 

*참고

-앱 권한 선언

https://developer.android.com/training/permissions/declaring?hl=ko

 

앱 권한 선언  |  Android 개발자  |  Android Developers

앱 권한 선언 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 권한 사용 워크플로에서 언급된 대로 앱에서 앱 권한을 요청하는 경우 앱의 매니페스트 파일에

developer.android.com

 

-활동에서 결과 가져오기 : registerForActivityResult

https://developer.android.com/training/basics/intents/result?hl=ko 

 

활동에서 결과 가져오기  |  Android 개발자  |  Android Developers

활동에서 결과 가져오기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 개발자 앱 내의 활동이든 다른 앱의 활동이든 다른 활동을 시작하는 것이 단방향 작

developer.android.com

 

 


이 포스팅에 작성한 내용은 고돈호, ⌜이것이 안드로이드다⌟, 한빛미디어(주), 2022 에서 발췌하였습니다.