[ Do it! ] 안드로이드 앱 프로그래밍 - #3. 어플리케이션 구성하기 (7)

ma.caron_g·2022년 4월 9일
0

Do it! - Android Studio

목록 보기
18/18
post-thumbnail

1. 위험 권한 부여하기

1-1. 위험 권한

앞 게시글에 브로드캐스트 수신자를 만들어 SMS 문자를 받으려면 RECEIVE_SMS 권한이 필요하다는 것을 알고 있습니다.

예를 들어, 인터넷을 사용할 때 부여하는 INTERNET 권한은 일반 권한이므로 앱을 설치할 때 사용자에게 권한이 부여되어야 함을 알려주고 설치할 것인지를 물어봅니다.
사용자가 부여할 권한들에 대한 설명을 보고 수락하면 앱이 설치되고 앱에는 INTERNET 권한이 부여됩니다. 그러나 위험 권한으로 분류되는 RECEIVE_SMS의 경우에는 설치 시에 부여한 권한은 의미가 없으며 실행시에 사용자에게 권한을 부여할 것인지 물어보게 됩니다.
만약 사용자가 권한을 부여하지 않으면 해당 기능은 동작하지 않습니다.

1-2. 대표적인 위험 권한

  • 위치
  • 카메라
  • 마이크
  • 연락처
  • 전화
  • 문자
  • 일정
  • 센서

위험 권한으로 분류된 주요 권한들을 보면 대부분 개인정보가 담겨 있는 정보에 접근하거나 개인정보를 만들어낼 수 있는 단말의 주요 장치에 접근하는 경우에 부여되는 권한이라는 것을 알 수 있습니다.

분류(Permission Group)세부 권한 (Permission)
LOCATION(위치)ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
CAMERACAMERA
MICROPHONERECORD_AUDIO
CONTACTSREAD_CONTACTS
READ_CONTACTS
GET_ACCOUNTS
PHONEREAD_PHONE_STATE
CALL_PHONE
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
SMSSEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
CALENDARREAD_CALENDAR
WRITE_CALENDAR
SENSORBODY_SENSORS
STORAGEREAD_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE

1-3. 권한 부여 구현 (SMS)

package com.study.doit;

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

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

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

		//권한이 부여되어 있는지 확인함.
        int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS);
        if(permissionCheck == PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "SMS 수신 권한 있음", Toast.LENGTH_SHORT).show();
        }
        else {
            Toast.makeText(this, "SMS 수신 권한 없음", Toast.LENGTH_SHORT).show();
          if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECEIVE_SMS)) {
                Toast.makeText(this, "SMS 권한 설정 필요함.", Toast.LENGTH_SHORT).show();
            }
            else {
            	// 사용자가 볼 수 있도록 새로운 권한 부여 요청 대화상자를 띄움.
                ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.RECEIVE_SMS }, 1);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch(requestCode) {
            case 1:
                //사용자가 권한을 수락했는지 여부를 확인함
                if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "SMS 권한을 사용자가 승인함.", Toast.LENGTH_SHORT).show();
                }
                else {
                    Toast.makeText(this, "SMS 권한 거부됨.", Toast.LENGTH_SHORT).show();
                }

                return;
        }
    }
}

2. 리소스와 매니페스트

2-1. 리소스

안드리오드 앱은 크게 자바코드리소스로 구성됩니다.

자바 코드

  • 앱의 흐름
  • 기능

리소스

  • 레이아웃
  • 보여주기 위해 사용하는 파일 또는 데이터 관리

2-2. 매니페스트

설치된 앱의 구성 요소가 어떤 것인지, 그리고 어떤 권한이 부여되었는지 시스템에 알려주기 때문에 매우 중요합니다.
모든 안드로이드 앱은 가장 상위 폴더에 매니페스트 파일이 있어야 하며 이 정보는 앱이 실행되기 전에 시스템이 알아야 할 내용들을 정의하고 있습니다.

Reference

<action>
<activity>
<activity_alias>
<application>
<category>
<data>
<grant-uri-permission>
<instrumetation>
<intent-filter>
<manifest>
<meta-data>
<permission>
<permission-group>
<permission-tree>
<provider>
<receiver>
<service>
<uses-configuration>
<uses-library>
<uses-permission>
<uses-sdk>

이 태그들 중에서 <action>, <service>, <receiver>와 같은 태그들은 어플케이션 구성 요소를 등록하기 위해 사용됩니다.

매니페스트의 주요 역할

  • 어플리케이션의 자바 패키지 이름 지정
  • 어플리케이션의 구성 요소에 대한 정보 등록
    (액티비티, 서비스, 브로드캐스트 수신자, 내용 제공자)
  • 각 구성요소를 구현하는 클래스 이름 지정
  • 어플리케이션이 가져야 하는 권한에 대한 정보 등록
  • 다른 어플리케이션이 접근하기 위해 필요한 권한에 대한 정보 등록
  • 어플리케이션 개발 과정에서 프로파일링을 위해 필요한 instrumentation 클래스 등록
  • 어플리케이션에 필요한 안드로이드 API의 레벨 정보 등록
  • 어플리케이션에서 사용하는 라이브러리 리스트

매니페스트 기본 구조

<manifest ...>
  <application ...>
    ...
    <service android:name="com.study.doit" ...>
    ...
    </service>
  ...
  </applciation>
</manifest>

어플리케이션을 의미하는 <application> 태그는 한 개만 있을 수 있습니다.
그 내부에 들어가는 다양한 구성 요소 태그는 여러 번 추가될 수 있습니다.

그중 메인 액티비티는 항상 다음과 같은 형태로 추가되어야 합니다.
인텐트 필터에 들어가는 정보는 <action>태그의 경우 MAIN이 되어야 하고 <category>태그의 경우 LAUNCHER가 되어야 합니다.

<activity android:name="com.study.doit"
  android:label="@string/app_name">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <catregory android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</action>

리소스의 사용

리소스를 자바 코드와 분리하는 이유는 이해하기 쉽고 유지관리가 용이하기 때문입니다.

/res 폴더 이외에 /asset 폴더를 따로 만들 수 있는데 두 가지 모두 리소스라고 할 수 있으며
대부분은 /res 폴더 밑에서 관리됩니다.

  • 에셋(Asset)은 동영상이나 웹페이지와 같은 용량이 큰 데이터를 의미합니다
  • 리소스는 빌드되어 설치파일에 추라되지만 에셋은 빌드되지 않습니다

/res/values 폴더에는 문자열이나 기타 기본 데이터 타입에 해당하는 정보들이 저장됩니다.
기본적으로 stings.xml 파일 안에 문자열을 저장합니다.

/res/drawable 폴더에는 이미지를 저장합니다.

저장되 있는 리소스 정보들은 Resources객체를 참조하여 리소스를 읽어들여야합니다.
Resources 객체는 Context.getResources() 메서드를 이용해 액티비티 안에서 언제든지 참조할 수 있습니다.

스타일과 테마

스타일과 테마는 여러가지 속성들을 한꺼번에 모아서 정의한 것 입니다.

버튼의 모양이나 대화상자의 모양들을 원하는대로 정의할 수 있는데 스타일을 직접 정의하고 싶으면
res/values/styles.xml 파일을 만들어야합니다.
다음은 styles.xml안에 정의한 <style> 태그를 보여줍니다.
이렇게 각각의 요소별로 정의한 UI속성들을 android:style 속성을 이용하여 레이아웃에 적용할 수 있습니다.

<style name="Alert" parent="android:Theme.Dialog">
  <item name="android:whindowBackground">@drawable/alertBackground</item>
</style>
profile
다른 사람이 만든 것을 소비하는 활동보다, 내가 생산적인 활동을 하는 시간이 더 많도록 생활화 하자.

0개의 댓글