Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Android 런타임에 위치 권한 요청하는 방법 – 단계별 구현 가이드

Android 6.0(API 23)부터 카메라, 연락처, 위치 같은 위험 권한(Dangerous Permissions)은 앱 설치 시점이 아니라 실행 중(런타임)에 사용자에게 직접 동의를 받아야 합니다. 이 글에서는 대표적인 위험 권한인 위치 권한(ACCESS_FINE_LOCATION)을 런타임에 요청하고, 그 결과를 처리하는 전체 과정을 단계별로 살펴봅니다.

1단계: 새 프로젝트 만들기

Android Studio를 실행한 뒤 File ⇒ New Project 메뉴로 이동하고, 필요한 모든 항목을 입력해 새 프로젝트를 생성합니다.

2단계: 레이아웃 작성하기 (activity_main.xml)

res/layout/activity_main.xml 파일에 아래 코드를 추가합니다. 화면 중앙에 안내 문구를 표시하는 간단한 TextView 하나만 배치했습니다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Request Location permission at Run time!"
        android:padding="4dp"
        android:layout_centerInParent="true"
        android:textSize="36sp"
        android:textStyle="bold"/>

</RelativeLayout>

3단계: 권한 요청 코드 작성하기 (MainActivity.java)

src/MainActivity.java에 다음 코드를 추가합니다. 핵심 흐름은 다음과 같습니다.

  • checkSelfPermission(): 현재 권한이 이미 부여되었는지 확인합니다.
  • shouldShowRequestPermissionRationale(): 사용자가 이전에 권한을 거부했는지 판단해, 필요하다면 요청 이유를 안내할 수 있습니다.
  • requestPermissions(): 실제로 시스템 권한 다이얼로그를 띄워 사용자에게 요청합니다.
  • onRequestPermissionsResult(): 사용자의 선택 결과(승인/거부)를 콜백으로 받아 처리합니다.
import android.Manifest;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (ContextCompat.checkSelfPermission(MainActivity.this,
            Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                Manifest.permission.ACCESS_FINE_LOCATION)){
                ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
            }else{
                ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
        int[] grantResults){
        switch (requestCode){
            case 1: {
                if (grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    if (ContextCompat.checkSelfPermission(MainActivity.this,
                        Manifest.permission.ACCESS_FINE_LOCATION)==PackageManager.PERMISSION_GRANTED){
                        Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
                    }
                }else{
                    Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
                }
                return;
            }
        }
    }
}

참고: 최신 프로젝트(AndroidX 기반)라면 import 문을 아래처럼 변경해 주세요.

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AppCompatActivity;

4단계: 매니페스트에 권한 선언하기 (AndroidManifest.xml)

런타임 요청과 별개로, AndroidManifest.xml에도 반드시 해당 권한을 선언해야 합니다. 누락되면 권한 요청 자체가 정상적으로 동작하지 않습니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.sample">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

앱 실행 및 결과 확인

이제 애플리케이션을 실행해 보겠습니다. 실제 Android 스마트폰을 컴퓨터에 연결했다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run(실행) 아이콘을 클릭하고, 옵션 목록에서 연결된 모바일 기기를 선택하세요.

앱이 실행되면 화면 중앙에 안내 문구가 표시되고, 곧이어 시스템 권한 다이얼로그가 나타납니다. 여기서 Allow(허용)를 누르면 "Permission Granted" 토스트가, Deny(거부)를 누르면 "Permission Denied" 토스트가 화면에 잠깐 표시됩니다.

Android 런타임에 위치 권한 요청하는 방법 – 단계별 구현 가이드


Android 런타임에 위치 권한 요청하는 방법 – 단계별 구현 가이드

마무리

이 예제에서는 위치 권한 하나만 다루었지만, 같은 패턴으로 카메라(CAMERA), 저장소(READ_EXTERNAL_STORAGE) 등 다른 위험 권한도 동일하게 요청할 수 있습니다. 여러 권한을 한 번에 요청하려면 requestPermissions()의 배열에 권한 문자열을 추가하기만 하면 됩니다. 사용자 경험을 높이려면 권한이 필요한 이유를 미리 설명하는 UI를 제공하는 것도 좋은 방법입니다.