정답보다 해답을

[Android] [멋쟁이 사자처럼] Menifest, 앱의 자기소개서 본문

Android

[Android] [멋쟁이 사자처럼] Menifest, 앱의 자기소개서

스탑스톤 2024. 10. 19. 17:34

목차

1. 안드로이드 매니페스트란?
2. 매니페스트에서 할 수 있는 일
3.구성 요소 선언
4. Intent 필터로 구성 요소 노출하기
5. 앱 요구사항 선언
6. Fragment는 매니페스트에 왜 선언되지 않을까?
7. 기본적인 매니페스트 속성들
8. 안드로이드 매니페스트 분석하기
- 앱 권한 분석
- 앱 기본 정보 분석
- 액티비티 분석
- 외부 서비스 연동 분석

안드로이드 매니페스트란?

AndroidManifest.xml은 안드로이드 앱의 구성 및 속성을 정의하는 매우 중요한 파일입니다.
시스템은 이 파일을 읽어 앱의 구성 요소(액티비티, 서비스 등)를 인식하고, 앱이 필요로 하는 권한과 기능을 확인합니다. 앱이 정상적으로 동작하려면 매니페스트 파일에 올바르게 선언되어야 합니다.
 

매니페스트에서 할 수 있는 일 ✨

매니페스트는 단순한 앱 구성 요소 선언을 넘어 다양한 작업을 처리합니다:

  1. 사용자 권한 요구: 예를 들어, 인터넷 사용 권한이나 연락처에 접근할 권한을 명시할 수 있습니다.
  2. 최소 API 수준 설정: 앱이 사용할 최소 SDK 버전을 지정합니다.
  3. 하드웨어 및 소프트웨어 요구사항: 앱이 카메라나 블루투스와 같은 기능을 요구할 경우, 이를 명시합니다.
  4. 외부 라이브러리 선언: Google Maps API와 같은 외부 라이브러리를 사용하는 경우 명시합니다.

구성 요소 선언 🏗️

매니페스트 파일에서 시스템에 앱의 구성 요소를 알리기 위해 다음과 같은 요소들을 선언해야 합니다:

  • <activity>: 앱의 화면을 구성하는 활동(Activity) 선언.
  • <service>: 백그라운드에서 실행되는 서비스(Service) 선언.
  • <receiver>: 특정 브로드캐스트 메시지 수신기(BroadcastReceiver) 선언.
  • <provider>: 데이터 관리(ContentProvider)를 위한 콘텐츠 제공자 선언.

이 선언들이 없으면 시스템이 해당 요소를 인식하지 못해 실행되지 않습니다.
 

Intent 필터로 구성 요소 노출하기 📬

인텐트(Intent)는 구성 요소 간의 통신을 담당하며, Intent-filter를 통해 다른 앱이 특정 액션을 처리할 수 있도록 구성할 수 있습니다.
예를 들어, 예를 들어, 앱의 메인 활동을 다음과 같이 선언할 수 있습니다.

<activity android:name="com.example.project.MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

이 선언은 앱을 실행할 때 메인 화면이 첫 번째로 표시되도록 하며, 기기의 홈 화면에서 앱 아이콘을 눌렀을 때 이 활동이 실행되도록 합니다.

<action> 요소는 이 활동이 기본적인 'MAIN' 액션을 처리한다는 것을 나타내고, <category> 요소는 홈 화면의 'LAUNCHER' 카테고리에서 실행될 수 있음을 의미합니다. 이를 통해 앱의 메인 액티비티가 시스템과 상호작용하여 사용자에게 적절히 노출됩니다.

 

앱 요구사항 선언 💡

앱이 특정 하드웨어나 소프트웨어 요구사항을 가질 경우, 이를 매니페스트 파일에 선언해야 합니다. 예를 들어, 앱이 카메라 기능을 요구할 때 다음과 같이 선언할 수 있습니다

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera.any" 
              android:required="true" />
  • <uses-permission>:
    • 이 요소는 앱이 카메라에 접근할 수 있는 권한을 요청합니다. 사용자가 앱을 설치하거나 실행할 때 이 권한을 허용해야만 카메라 기능을 사용할 수 있습니다. 따라서 사용자의 동의를 얻기 위해 명시적으로 요청하는 것이 필요합니다.
  • <uses-feature>:
    • 이 요소는 앱이 카메라 기능을 요구한다는 것을 시스템에 알립니다. android.hardware.camera.any는 앱이 어떤 종류의 카메라(후면 카메라, 전면 카메라 등)와 상관없이 카메라 기능이 필요하다는 것을 나타냅니다.
    • android:required="true"로 설정하면 카메라가 없는 기기에서는 앱이 설치되지 않습니다. 만약 카메라 기능이 필수가 아니라 선택 사항이라면 android:required="false"로 설정하여 카메라가 없어도 앱이 설치될 수 있도록 할 수 있습니다.

Fragment는 매니페스트에 왜 선언되지 않을까? 🤔

액티비티는 매니페스트에 반드시 선언되어야 하지만, 프래그먼트는 그렇지 않습니다.

그 이유는 프래그먼트가 직접적으로 앱의 화면을 구성하는 것이 아니라, 액티비티의 일부로 포함되기 때문입니다.

따라서 액티비티에서 프래그먼트를 관리하며, 별도의 선언이 필요하지 않습니다.

 

기본적인 매니페스트 속성들 📄

  • android:allowBackup: 앱 데이터의 백업 허용 여부를 설정합니다.
  • android:icon: 앱 아이콘을 설정합니다.
  • android:label: 앱 이름을 설정합니다.
  • android:theme: 앱의 테마를 설정합니다.

 

안드로이드 매니페스트 분석하기 💡

카카올 소셜로그인을 활용하는 게시판 프로젝트의 매니페스트의 일부분을 분석해보겠습니다.

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

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

    <application
        android:name=".App"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:networkSecurityConfig="@xml/network_security_config"
        android:roundIcon="@mipmap/ic_launcher"
        android:supportsRtl="true"
        android:theme="@style/Theme.WhaTheLook"
        tools:targetApi="31">

        <activity
            android:name=".view.search.SearchActivity"
            android:exported="false" />
        <activity
            android:name=".view.post.PostActivity"
            android:exported="false" />
        <activity
            android:name=".view.login.LogInActivity"
            android:exported="false" />
        <activity
            android:name=".view.splash.SplashActivity"
            android:exported="true"
            android:theme="@style/Theme.App.Starting">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".view.MainActivity"
            android:exported="false" />
        <activity
            android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:host="oauth"
                    android:scheme="kakao${KAKAO_API_KEY}" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 

앱 권한 분석

이 앱은 다음과 같은 권한들을 요청합니다.

  1. android.permission.INTERNET
    • 목적: 앱이 인터넷에 접속할 수 있도록 합니다.
  2. android.permission.READ_EXTERNAL_STORAGE
    • 목적: 기기의 외부 저장소에서 파일을 읽을 수 있게 합니다.
    • 특이사항: android:maxSdkVersion="32"로 설정되어 있어, Android 13(API 33) 이상에서는 이 권한이 사용되지 않습니다.
    • 사용 사례: 사용자의 갤러리에서 이미지 로드
  3. android.permission.READ_MEDIA_IMAGES
    • 목적: Android 13 이상에서 이미지 파일에 접근할 수 있게 합니다.

앱 기본 정보 분석

<application> 태그 내의 주요 속성들:

  • android:name=".App": 커스텀 Application 클래스를 지정합니다. 앱 전역 상태 관리에 사용됩니다.
  • android:allowBackup="true": 앱 데이터 백업을 허용합니다.
  • android:dataExtractionRules="@xml/data_extraction_rules": 데이터 추출 규칙을 정의합니다.
  • android:fullBackupContent="@xml/backup_rules": 전체 백업 내용을 정의합니다.
  • android:icon="@mipmap/ic_launcher": 앱 아이콘을 설정합니다.
  • android:label="@string/app_name": 앱 이름을 설정합니다.
  • android:networkSecurityConfig="@xml/network_security_config": 네트워크 보안 설정을 정의합니다.
  • android:roundIcon="@mipmap/ic_launcher": 둥근 앱 아이콘을 설정합니다.
  • android:supportsRtl="true": 오른쪽에서 왼쪽으로 읽는 언어 지원을 활성화합니다.
  • android:theme="@style/Theme.WhaTheLook": 앱의 기본 테마를 설정합니다.
  • tools:targetApi="31": 앱이 타겟팅하는 API 레벨을 지정합니다 (Android 12).

액티비티 분석

이 앱은 다음과 같은 액티비티들을 포함하고 있습니다.

  1. SearchActivity: 검색 기능을 제공합니다.
  2. PostActivity: 게시물 작성 화면으로 추정됩니다.
  3. LogInActivity: 로그인 화면입니다.
  4. SplashActivity: 앱 시작 시 표시되는 스플래시 화면입니다.
    • android:exported="true"로 설정되어 있어 다른 앱에서 시작 가능합니다.
    • LAUNCHER 인텐트 필터가 있어 앱의 시작점 역할을 합니다.
  5. MainActivity: 앱의 메인 화면으로 보입니다.
⭐️  대부분의 액티비티가 android:exported="false"로 설정되어 있어 앱 내부에서만 접근 가능합니다.
11이하: 인텐트 필터가 있으면 기본값이 true
12이후: 인텐트 필터 유무와 관계없이 반드시 명시적으로 속성을 설정해주어야 합니다. 

 
 

외부 서비스 연동 분석

카카오 SDK 인증 핸들러

        <activity
            android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:host="oauth"
                    android:scheme="kakao${KAKAO_API_KEY}" />
            </intent-filter>
        </activity>
  • 목적: 카카오 로그인 기능을 구현합니다.
  • android:exported="true": 외부 앱(카카오톡 등)에서 이 액티비티를 시작할 수 있게 합니다.
  • 인텐트 필터: OAuth 인증 과정에서 필요한 URI 스킴을 처리합니다.
  • android:scheme="kakao${KAKAO_API_KEY}": 카카오 개발자 콘솔에서 받은 API 키를 사용합니다.

 
이상으로 안드로이드 매니페스트 파일에 대해 알아보았습니다.
매니페스트는 앱의 구조와 동작을 정의하는 핵심 파일로, 다음과 같은 중요한 역할을 합니다.

  1. 앱의 구성 요소 선언
  2. 사용자 권한 요청
  3. 최소 API 레벨 지정
  4. 하드웨어 및 소프트웨어 요구사항 명시
  5. 사용하는 라이브러리 선언

출처:
멋쟁이사자처럼 앱스쿨 3기
https://developer.android.com/guide/topics/manifest/manifest-intro?hl=ko