정상에서 IT를 외치다

카메라 예제와 함께 보는 Scoped Storage (권한 가져오기) 본문

안드로이드

카메라 예제와 함께 보는 Scoped Storage (권한 가져오기)

Black-Jin 2019. 11. 15. 11:19
반응형

안녕하세요. 블랙진입니다. 


지난 포스팅 안드로이드Q 주요 이슈 사항 간략 정리에 이은 포스팅입니다. 안드로이드 Q 버전부터 많은 부분을 개발자가 대응해야합니다. 필자는 대응 사항 중 저장소 정책에 관한 내용을 카메라 예제와 함께 아래 순서로 살펴보겠습니다. 


<카메라 예제와 함께 보는 Scoped Storage>


권한 가져오기

저장소의 종류

이미지 가져오기

안드로이드 Q 대응



접근 권한 가져오기


카메라에 접근하기 위해서는 권한이 필요합니다. 런타임에서 사용자에게 권한을 요청 받아야 하므로 Activity에 추가적으로 코드를 만들어 주어야 됩니다. 만일 권한을 받지 않고 카메라에 접근한다면 permission denied 에러와 함께 앱이 종료됩니다.


1. AndroidManifest 상단에 권한을 추가해 줍니다.

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

<!-- camera 권한을 추가해 줍니다. -->
<uses-permission android:name="android.permission.CAMERA" />

<application
...
</application>

</manifest>



2. 런타임에서 권한을 받아오기 위한 코드를 작성해 줍니다.

class MainActivity : AppCompatActivity() {

private val permissionCheckCamera by lazy {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
)
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)


chkPermission()
}

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

Timber.d("requestCode : $requestCode , grantResults : ${grantResults.contentToString()}")
if (requestCode == REQUEST_PERMISSION) {
for (value in grantResults) {
if (value != PackageManager.PERMISSION_GRANTED) {
Timber.e("permission reject")
}
}
}
}

private fun chkPermission() {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

if (permissionCheckCamera == PackageManager.PERMISSION_DENIED) {

// 권한 없음
showRequestPermission()

} else {

// 권한 있음
Timber.e("---- already have permission ----")

}
}
}

private fun showRequestPermission() {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.CAMERA
),
REQUEST_PERMISSION
)
}


companion object {
private const val REQUEST_PERMISSION = 1000
}
}


위 전체 코드에 대해 내용을 하나하나 살펴볼까요?


private val permissionCheckCamera by lazy {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
)
}

앱이 카메라 권한을 가지고 있는지 확인하는 변수 입니다. 카메라 권한이 없다면 -1을 반환합니다.


private fun chkPermission() {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

if (permissionCheckCamera == PackageManager.PERMISSION_DENIED) {

// 권한 없음
showRequestPermission()

} else {

// 권한 있음
Timber.e("---- already have permission ----")

}
}
}

권한은 마시멜로우 이상 버전부터 요청해줘야 합니다. 따라서 OS 버전체크를 먼저 해주고 만일 마시멜로우 버전 이상이면 권한이 이미 획득되어 있는지를 확인해 줍니다.  permissionCheckCamera는 위에서 선언한 변수로 만일 권한이 없는 상태면 -1을 반환합니다.



PackageManager.java

/**
* Permission check result: this is returned by {@link #checkPermission}
* if the permission has been granted to the given package.
*/
public static final int PERMISSION_GRANTED = 0;

/**
* Permission check result: this is returned by {@link #checkPermission}
* if the permission has not been granted to the given package.
*/
public static final int PERMISSION_DENIED = -1;

PackageManager는 안드로이드에 내장된 클래스로 위와 같은 변수를 가지고 있습니다. 권한을 획득한 상태면 0 아니면 -1을 반환합니다.



private fun showRequestPermission() {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.CAMERA
),
REQUEST_PERMISSION
)
}

권한이 없다면 권한을 요청하는 함수를 실행해 줍니다. ActivityCompat에 있는 requestPrmissions 함수에 요청하고 싶은 권한과 함께 실행해 줍니다. 이때 배열을 통해 여러개의 권한을 함께 요청해 줄 수 있습니다. 저는 카메라 권한 1개만 요청하겠습니다.


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

if (requestCode == REQUEST_PERMISSION) {
for (value in grantResults) {
if (value != PackageManager.PERMISSION_GRANTED) {
Timber.e("permission reject")
}
}
}
}

권한 팝업이 나오고 사용자 액션 후 Activity의 override 함수인 onRequestPermissionsResult가 실행됩니다. 여기서 grantResults가 모두 PERMISSION_GRANTED 인지 확인 해주고 이에 맞게 필요한 코드를 실행해 주시면 됩니다.


카메라 예제에 들어가기에 앞서 권한을 받아오는 코드를 작성해 보았습니다. 다음 포스팅은 안드로이드 Q 저장소 정책을 살펴보는데 앞서 기존의 저장소가 어떻게 구성되어 있는지 카메라 예제와 함께 살펴보겠습니다.

반응형
Comments