경험의 기록

2021.06.25 - [Android/기본] - [Android] 안드로이드 권한 (Permission) 체크하기 - 위치정보 사용하기

 

[Android] 안드로이드 권한 (Permission) 체크하기 - 위치정보 사용하기

안드로이드에서는 특정 동작을 위하여 권한이 필요하다. 마시멜로 버전 이전에는 앱 설치시 모든 권한이 요청되었지만 이후 버전에서는 권한이 크게 일반 권한과 위험 권한으로 나뉘었다. 일반

hanyeop.tistory.com

기존 안드로이드에서 권한을 체크, 요청하기 위해서

위의 방식 또는 테드 퍼미션 같은 유용한 라이브러리들을 사용했다.

 

이번엔 제트팩 컴포즈에서 권한을 체크하고, 요청하여 사용하는 방법에 대해 알아보고자 한다.

예제는 위치 권한을 기반으로 작성할 것이다.


1️⃣ 권한 추가

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

Manifest에 사용하고자 하는 권한을 추가해준다.

여기서는 위치 권한을 추가해주었다.

 

2️⃣ 권한 확인하기

fun checkAndRequestPermissions(
    context: Context,
    permissions: Array<String>,
    launcher: ManagedActivityResultLauncher<Array<String>, Map<String, Boolean>>,
) {

    /** 권한이 이미 있는 경우 **/
    if (permissions.all {
            ContextCompat.checkSelfPermission(
                context,
                it
            ) == PackageManager.PERMISSION_GRANTED
        }) {
        Log.d("test5", "권한이 이미 존재합니다.")
    }

    /** 권한이 없는 경우 **/
    else {
        launcher.launch(permissions)
        Log.d("test5", "권한을 요청하였습니다.")
    }
}

권한을 체크하기 위한 checkAndRequestPermissions 함수를 정의해준다.

현재 컨텍스트, 확인할 권한 배열, 권한이 없는 경우 실행할 launcher를 생성자로 받아준다.

 

함수 내부에서 권한 배열이 전부 동의되어 있는지 checkSelfPermission을 통해 체크할 수 있다.

만약 권한이 없다면 launcher를 실행한다.

 

 

3️⃣ 권한 요청하기

이제 위에서 작성한 checkAndRequestPermissions 에 권한을 요청한다.

생성자로 넘기기 위해 필요한 context는

val context = LocalContext.current

최상위 컴포저블에서 LocalContext.current를 호출하여 받아와 넣어준다.

 

/** 요청할 권한 **/
val permissions = arrayOf(
    Manifest.permission.ACCESS_COARSE_LOCATION,
    Manifest.permission.ACCESS_FINE_LOCATION
)

또한 요청할 권한들을 배열에 담아주고

 

val launcherMultiplePermissions = rememberLauncherForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissionsMap ->
        val areGranted = permissionsMap.values.reduce { acc, next -> acc && next }
        /** 권한 요청시 동의 했을 경우 **/
        if (areGranted) {
            Log.d("test5", "권한이 동의되었습니다.")
        }
        /** 권한 요청시 거부 했을 경우 **/
        else {
            Log.d("test5", "권한이 거부되었습니다.")
        }
    }

권한이 없는 경우 실행할 launcher를 정의해준다.

RequestMultiplePermissions 를 통해 배열에 담긴 권한을 요청하고

 

reduce를 통해 전부 동의했는지 확인한다.

 

Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colors.background
    ) {
        Button(onClick = {
            checkAndRequestPermissions(
                context,
                permissions,
                launcherMultiplePermissions
            )
        }) {
            Text(text = "권한 요청하기")
        }
    }

이제 checkAndRequestPermissions 를 위치 권한을 체크하고 요청할 곳에서 호출해준다.

 

최종적으로 버튼 클릭 시 권한을 체크하고 요청하는 것을 확인할 수 있다.

1. 버튼 클릭 시 위치 권한이 있는지 체크, 없기 때문에 권한을 요청

2. 권한 거부 시 권한 거부 호출

3. 다시 버튼 클릭 시 위치 권한이 있는지 체크, 없기 때문에 권한을 요청

4. 권한 동의 시 권한 동의 호출

5. 다시 버튼 클릭 시 위치 권한이 있는지 체크, 이미 있으므로 이미 존재 호출

 

의 과정을 거친 결과이다.

 

 

4️⃣ 전체 코드

package com.hanyeop.permissionex

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.core.content.ContextCompat
import com.hanyeop.permissionex.ui.theme.PermissionExTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            PermissionExTheme {
                MyApp()
            }
        }
    }
}

@Composable
fun MyApp(){
    val context = LocalContext.current

    /** 요청할 권한 **/
    val permissions = arrayOf(
        Manifest.permission.ACCESS_COARSE_LOCATION,
        Manifest.permission.ACCESS_FINE_LOCATION
    )

    val launcherMultiplePermissions = rememberLauncherForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissionsMap ->
        val areGranted = permissionsMap.values.reduce { acc, next -> acc && next }
        /** 권한 요청시 동의 했을 경우 **/
        if (areGranted) {
            Log.d("test5", "권한이 동의되었습니다.")
        }
        /** 권한 요청시 거부 했을 경우 **/
        else {
            Log.d("test5", "권한이 거부되었습니다.")
        }
    }


    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colors.background
    ) {
        Button(onClick = {
            checkAndRequestPermissions(
                context,
                permissions,
                launcherMultiplePermissions
            )
        }) {
            Text(text = "권한 요청하기")
        }
    }
}

fun checkAndRequestPermissions(
    context: Context,
    permissions: Array<String>,
    launcher: ManagedActivityResultLauncher<Array<String>, Map<String, Boolean>>,
) {

    /** 권한이 이미 있는 경우 **/
    if (permissions.all {
            ContextCompat.checkSelfPermission(
                context,
                it
            ) == PackageManager.PERMISSION_GRANTED
        }) {
        Log.d("test5", "권한이 이미 존재합니다.")
    }

    /** 권한이 없는 경우 **/
    else {
        launcher.launch(permissions)
        Log.d("test5", "권한을 요청하였습니다.")
    }
}

 

https://github.com/HanYeop/Jetpack-Compose/tree/master/PermissionEx

 

GitHub - HanYeop/Jetpack-Compose: Jetpack Compose 사용해보기

Jetpack Compose 사용해보기. Contribute to HanYeop/Jetpack-Compose development by creating an account on GitHub.

github.com

 

 

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading