안드로이드 스튜디오 권한 요청 - andeuloideu seutyudio gwonhan yocheong

안녕하세요! 

안드로이드에서 위치나 카메라, 저장공간 등 앱 외부에 있는 리소스에 접근하기 위해서는
Android 6.0 마시멜로(API 23) 이상의 휴대폰인 경우
사용자에게 접근 허용을 위한 권한 요청을 해야합니다. 

권한(permission) 요청을 하는 코드를 작성해 보았어요 🤗

AndroidManifest.xml 와 activity_permission.xml 는 동일하고 Activity 코드를 Kotlin, Java 두가지 버전을 준비했답니다! 

작성한 파일 목록 입니다.

1. AndroidManifest.xml
2. activity_permission.xml
3. PermissionActivity.kt / PermissionJavaActivity.java

1. AndroidManifest.xml

카메라, 위치 권한 을 추가해야 합니다.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
를 추가해주세요!

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="//schemas.android.com/apk/res/android" package="com.eun.mytmapkotlin"> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.CAMERA" /> <application android:allowBackup="false" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyTmapKotlin"> <activity android:name=".PermissionActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- <activity--> <!-- android:name=".PermissionJavaActivity"--> <!-- android:exported="true">--> <!-- <intent-filter>--> <!-- <action android:name="android.intent.action.MAIN" />--> <!-- <category android:name="android.intent.category.LAUNCHER" />--> <!-- </intent-filter>--> <!-- </activity>--> </application> </manifest>

2. activity_permission.xml

PermissionActivity 에 대한 레이아웃입니다.

<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="//schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="//schemas.android.com/apk/res-auto" android:background="@color/light_green_200"> <TextView android:id="@+id/tv_title" android:layout_width="0dp" android:layout_height="60dp" android:background="@color/amber_200" android:elevation="10dp" android:gravity="center" android:text="권한 체크" android:textColor="@color/black" android:textSize="20sp" android:textStyle="bold" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> <ImageView android:id="@+id/iv_camera" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:layout_marginBottom="15dp" android:layout_marginHorizontal="30dp" app:layout_constraintTop_toBottomOf="@id/tv_title" app:layout_constraintBottom_toTopOf="@id/iv_location" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toStartOf="@id/tv_camera" app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintHorizontal_bias="0" app:layout_constraintVertical_chainStyle="packed" app:layout_constraintVertical_bias="0" android:src="@drawable/icon_permission_camera"/> <TextView android:id="@+id/tv_camera" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="30dp" android:gravity="center_vertical" app:layout_constraintTop_toBottomOf="@id/tv_title" app:layout_constraintBottom_toTopOf="@id/iv_location" app:layout_constraintStart_toEndOf="@id/iv_camera" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintVertical_bias="0.5" android:text="카메라 권한" android:textColor="@color/grey_800" android:textSize="16sp" /> <ImageView android:id="@+id/iv_location" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="15dp" android:layout_marginBottom="30dp" android:layout_marginHorizontal="30dp" app:layout_constraintTop_toBottomOf="@id/iv_camera" app:layout_constraintBottom_toTopOf="@id/btn_confirm" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toStartOf="@id/tv_location" app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintHorizontal_bias="0" app:layout_constraintVertical_chainStyle="packed" app:layout_constraintVertical_bias="0" android:src="@drawable/icon_permission_location"/> <TextView android:id="@+id/tv_location" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="30dp" app:layout_constraintTop_toBottomOf="@id/iv_camera" app:layout_constraintBottom_toTopOf="@id/btn_confirm" app:layout_constraintStart_toEndOf="@id/iv_location" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintVertical_bias="0.1" android:text="위치 권한" android:textColor="@color/grey_800" android:textSize="16sp" /> <androidx.appcompat.widget.AppCompatButton android:id="@+id/btn_confirm" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginVertical="50dp" android:layout_marginHorizontal="30dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:background="@drawable/custom_btn" android:text="확인" /> </androidx.constraintlayout.widget.ConstraintLayout>

3.  PermissionActivity.kt / PermissionJavaActivity.java

Kotlin 코드에서 PermissionActivity 의 화면을 ActivityPermissionBinding 을 통해 activity_permission.xml 의 view 를 표시합니다.

Kotlin, Java 두가지 코드 입니다.

Kotlin 코드 - PermissionActivity.kt

package com.eun.mytmapkotlin import android.Manifest import android.content.pm.PackageManager import android.os.Build import android.os.Bundle import android.util.Log import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import com.eun.mytmapkotlin.databinding.ActivityPermissionBinding class PermissionActivity: AppCompatActivity() { companion object { const val TAG = "PermissionActivity" const val PERMISSION_REQUEST_CODE = 1 } private lateinit var binding: ActivityPermissionBinding //viewBinding 이용하여 activity_permission 바인딩 private val requiredPermissionList = arrayOf( //필요한 권한들 Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.CAMERA ) private lateinit var neededPermissionList: ArrayList<String> //권한 요청이 필요한 리스트 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityPermissionBinding.inflate(layoutInflater) setContentView(binding.root) //setContentView(R.layout.activity_permission) checkPermission() //권한 요청 체크 } /* 권한 요청 체크 */ private fun checkPermission() { neededPermissionList = ArrayList<String>() //초기화 //안드로이드 OS 버전이 23 이상일 경우 - 권한 허용 필요 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { for(permission in requiredPermissionList) { if(ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { //허용되지 않은 권한이라면 deniedPermissionList 에 추가 neededPermissionList.add(permission) } } if(neededPermissionList.isNotEmpty()) { //deniedPermissionList 가 존재하는 경우 권한허용 팝업 표시 initView() //View 설정 메소드로 이동 (확인 버튼) } else { //deniedPermissionList 가 Empty 인 경우(모든 권한이 허용된 경우) goNext(true, null) } } else { //안드로이드 OS 버전이 23 이상이 아닐 경우 - 권한 허용 불필요 goNext(true, "안드로이드 OS 버전이 23 미만인 경우 권한요청 안함 ") } } /* View 설정 */ private fun initView() = with(binding) { btnConfirm.setOnClickListener { if(onRequestPermissionsCheck()) { goNext(true, null) } } } /* 권한 요청 코드 -> ~ 권한 허용하시겠습니까? 팝업 표시 */ private fun onRequestPermissionsCheck(): Boolean { if(neededPermissionList.isNotEmpty()) { val array = arrayOfNulls<String>(neededPermissionList.size) ActivityCompat.requestPermissions(this, neededPermissionList.toArray(array), PERMISSION_REQUEST_CODE) //권한 요청 return false } return true } /* 권한 요청에 대한 팝업 결과(허용/거부) 처리 */ override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) var deniedPermissionList: ArrayList<String> = ArrayList<String>() //권한 요청이 거부된 리스트 when (requestCode) { PERMISSION_REQUEST_CODE -> { var flag = true //거부된 권한이 있는 경우 false 로 if (grantResults.isNotEmpty()) { for ((i, permission) in permissions.withIndex()) { if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { Log.d(TAG, "permission denied : [$i] $permission") deniedPermissionList.add(permission) flag = false } } goNext(flag, null)//flag 가 true 이면 goNext(true), false 이면 goNext(false) 으로 이동 } } } } /* 권한 요청에 따른 결과 Toast 표시 */ private fun goNext(successFlag: Boolean, msg: String?) { if(successFlag) { Toast.makeText(this, msg ?: "모든 권한을 허용했네요!", Toast.LENGTH_SHORT).show() } else { Toast.makeText(this, msg ?: "모든 권한을 허용해야합니다.", Toast.LENGTH_SHORT).show() } } }

Java 코드 - PermissionJavaActivity.Java

package com.eun.mytmapkotlin; import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import java.util.ArrayList; public class PermissionJavaActivity extends AppCompatActivity { private String TAG = PermissionActivity.class.getSimpleName(); private Context context = PermissionJavaActivity.this; final int PERMISSION_REQUEST_CODE = 1; public static String[] requiredPermissionList = new String[]{ //필요한 권한들 Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.CAMERA }; ArrayList<String> neededPermissionList = new ArrayList<>(); //권한 요청이 필요한 리스트 @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); checkPermission(); //권한 요청 체크 } /* 권한 요청 체크 */ public void checkPermission() { //안드로이드 OS 버전이 23 이상일 경우 - 권한 허용 필요 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { for (String thisPermission : requiredPermissionList) { //해당 권한이 있는지 확인 if (ContextCompat.checkSelfPermission(context, thisPermission) != PackageManager.PERMISSION_GRANTED) { neededPermissionList.add(thisPermission); //권한허용이 필요한 경우 neededPermissionList 리스트에 추가해준다 } } if(neededPermissionList.size() > 0) { initView(); //권한허용이 필요한 경우 initView() 에서 권한 요청 팝업을 띄워준다 } else { goNext(true); } } else { //안드로이드 OS 버전이 23 이상이 아닐 경우 - 권한 허용 불필요 goNext(true); } } /* View 설정 */ private void initView(){ setContentView(R.layout.activity_permission); Button btn_confirm = (Button)findViewById(R.id.btn_confirm); btn_confirm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(onRequestPermissionsCheck()){ goNext(true); } } }); } /* 권한 요청 코드 -> ~ 권한 허용하시겠습니까? 팝업 표시 */ private boolean onRequestPermissionsCheck() { if (!neededPermissionList.isEmpty()) { ActivityCompat.requestPermissions(this, neededPermissionList.toArray(new String[neededPermissionList.size()]), PERMISSION_REQUEST_CODE); return false; } return true; } /* 권한 요청에 대한 팝업 결과(허용/거부) 처리 */ @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); ArrayList<String> deniedPermission = new ArrayList<String>(); //권한 요청이 거부된 리스트 switch (requestCode) { case PERMISSION_REQUEST_CODE: if (grantResults.length > 0) { for (int i = 0; i < grantResults.length; i++) { Log.d(TAG, "***** onRequestPermissionsResult() - result : " + i); if(grantResults[i] != PackageManager.PERMISSION_GRANTED) { //권한 거부 - 권한허용이 필요한 거부된 경우 deniedPermission 리스트에 추가해준다 deniedPermission.add(requiredPermissionList[i]); } } if (deniedPermission.size() < 1) { goNext(true); } else { goNext(false); } } return; } } /* 권한 요청에 따른 결과 Toast 표시 */ private void goNext(boolean successFlag){ Log.d(TAG, "***** goNext() - successFlag : "+successFlag); if(successFlag) { Toast.makeText(context, "모든 권한을 허용했네요!", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, "모든 권한을 허용해야합니다.", Toast.LENGTH_SHORT).show(); } } }

결과화면

권한요청을 거부한 경우 / 모든 권한을 허용한 경우

감사합니당 ♡

Toplist

최신 우편물

태그