Permission 설정 모듈화

우왕이·2022년 8월 5일
0

Module.kt

목록 보기
3/4
post-thumbnail

Reason For Usage

 Android Permission 정책이 계속해서 바뀌기 때문에 조금이라도 쉽게 권한 설정 할 수 있도록 모듈화 했다.

 ps. 원래 권한 설정이 길고, 할게 많다

Module & Usage

/* Utile.kt */

fun showSnackBar(view: View, message: String, navigation: () -> Unit) {
    Snackbar.make(
        view,
        message,
        Snackbar.LENGTH_INDEFINITE
    ).apply {
        setAction(content.getString("확인")) {
            navigation.invoke()
        }
        show()
    }
}

/* Config.kt */
object Config {
	// 어떤 권한 설정 요청인지 판단하기 위한 변수
	const val REQUEST_CODE_BLUETOOTH = 111
	const val REQUEST_CODE_ACCESS = 222
	const val REQUEST_CODE_STORAGE = 333
    }
}

/* SampleActivity.kt */

// 처음 권한 요청을 시작할 권한의 판단 변수
private var permissionCheckNow = REQUEST_CODE_BLUETOOTH

private fun accessPermission() { ... }

private fun storagePermission() { ... }

// 예시로 bluetoothPermission
private fun bluetoothPermission() {
    with(Build.VERSION.SDK_INT) {
        when {
        	// 권한마다 AOS 버전별로 추가로 선언 해야 하는 권한이 있다.
        	this >= Build.VERSION_CODES.S -> {
            	if (checkSelfPermission(BLUETOOTH_CONNECT) != PERMISSION_GRANTED ||
                	checkSelfPermission(BLUETOOTH_SCAN) != PERMISSION_GRANTED ||
                	checkSelfPermission(BLUETOOTH_ADVERTISE) != PERMISSION_GRANTED ||
                ) {
                	// onRequestPermissionsResult로 이동
                    ActivityCompat.requestPermission(
                    	this@SampleActivity,
                        arrayOf(
                        	BLUETOOTH_CONNECT,
                            BLUETOOTH_SCAN,
                            BLUETOOTH_ADVERTISE
                        ),
                        REQUEST_CODE_BLUETOOTH
                    )
            	} else {
                	// 권한 설정 성공시
                    
                    // 저자는 사용시 다른 권한 요청으로 넘어가게 했었음
                    // accessPermission()
                }
            }
            
            this >= Build.VERSION_CODES.M -> {
                if (checkSelfPermission(BLUETOOTH) != PERMISSION_GRANTED ||
                    checkSelfPermission(BLUETOOTH_ADMIN) != PERMISSION_GRANTED
                ) {
                    ActivityCompat.requestPermissions(
                        this@SplashActivity,
                        arrayOf(
                            BLUETOOTH,
                            BLUETOOTH_ADMIN
                        ),
                        REQUEST_CODE_BLUETOOTH
                    )
                } else {
                	// 권한 설정 성공시
                    
                    // 저자는 사용시 다른 권한 요청으로 넘어가게 했었음
                    // accessPermission()
                }
            }
            // this >= Build.VERSION_CODES.* 버전 별 permission 추가로 설정 가능
        }
    }
}


override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)

    grantResults
        .contains(PERMISSION_GRANTED)
        .let {
            if (it) {
        	// 권한 수락시
                // 해당 권한 Accept -> 다른 권한 설정 or 다른 페이지로 이동
                when (requestCode) {
                    REQUEST_CODE_BLUETOOTH -> {
                        permissionCheckNow = REQUEST_CODE_ACCESS
                        accessPermission()
                    }
                /*
                    REQUEST_CODE_ACCESS -> {
                        permissionCheckNow = REQUEST_CODE_STORAGE
                        storagePermission()
                    }
                    REQUEST_CODE_STORAGE -> {
                        permissionCheckNow = REQUEST_CODE_BLUETOOTH
                        // Intent() 모든 권한 수락 시 다른 페이지로 이동
                    }
                */
                }
                
            } else permissions.all {
            // 권한 거절시
                // 1. 사용자가 권한 요청을 명시적으로 거부한 경우 true를 반환한다.
                // 2. 사용자가 권한 요청을 처음 보거나, 다시 묻지 않음 선택한 경우, 권한을 허용한 경우 false를 반환한다.
                // 이곳에는 2.의 두 번 거절, 다시 묻지 않음과 1.번만 들어온다. (처음 권한 요청, 권한 허용의 경우 위에서 걸러짐)
            	ActivityCompat.shouldShowRequestPermissionRationale(this@SplashActivity, it)
            }.let {
                // 권한 요청 재시도
                if (it) {
                // 두 번째에 권한 수락시
                    when (requestCode) {
                        REQUEST_CODE_BLUETOOTH -> bluetoothAndAccessPermission()
                        // REQUEST_CODE_ACCESS -> accessPermission()
                        // REQUEST_CODE_STORAGE -> storagePermission()
                    }
                }
                else {
                // 다시 묻지 않음을 선택하거나, 두 번 거절한 경우
                
                // device의 설정창으로 이동하는 모듈
                // snackBar Module
                    showSnackBar(binding.root, getString(message)) {
                        startActivity(Intent().apply {
                            when (requestCode) {
                            // Android Developers Setting에서 원하는 것을 찾아서 써도 된다.
                                REQUEST_CODE_BLUETOOTH -> action =
                                    ACTION_APPLICATION_DETAILS_SETTINGS
                                // REQUEST_CODE_ACCESS -> action =
                                //    ACTION_APPLICATION_DETAILS_SETTINGS
                                // REQUEST_CODE_STORAGE -> action =
                                //    ACTION_APPLICATION_DETAILS_SETTINGS
                            }
                            data = Uri.fromParts("package", packageName, null)
                        })
                    }
                }
            }
        }
}

// device의 설정창에서 permission 수락하지 않고, 취소나 뒤로가기로 앱으로 돌아온 경우
// 권한이 거부 된 경우 수락할 때까지 반복 
override fun onRestart() {
    super.onRestart()
    when(permissionCheckNow) {
        REQUEST_CODE_BLUETOOTH -> bluetoothPermission()
        REQUEST_CODE_ACCESS -> accessPermission()
        REQUEST_CODE_STORAGE -> storagePermission()
    }
}

Android Developers

Permission List
Setting List

Permission
SnackBar

profile
우왕~

0개의 댓글