개발 일기

Android Manifest ? 본문

Client/안드로이드

Android Manifest ?

이건욱

모든 앱 프로젝트는 프로젝트 소스 세트의 루트에 AndroidManifest.xml 파일(정확히 이 이름)이 있어야 합니다. 매니페스트 파일은 Android 빌드 도구, Android 운영체제 및 Google Play에 앱에 관한 필수 정보를 설명합니다.

 

주요 4가지의 기능에 대해서 선언을 해야합니다.

 

  • 앱의 패키지 이름(일반적으로 코드의 네임스페이스와 일치). Android 빌드 도구는 프로젝트를 빌드할 때 이 이름으로 코드 엔터티의 위치를 확인합니다. 앱을 패키징할 때 빌드 도구가 이 값을 Gradle 빌드 파일의 애플리케이션 ID로 대체합니다. 이는 시스템과 Google Play에서 고유한 앱 식별자로 사용됩니다. 패키지 이름과 앱 ID에 대해 자세히 알아보세요.
  • 앱의 구성 요소(모든 액티비티, 서비스, Broadcast Receiver, 콘텐츠 제공자 포함). 각 구성 요소는 Kotlin이나 Java 클래스의 이름과 같은 기본 속성을 정의해야 합니다. 또한 자신이 처리할 수 있는 기기 구성의 종류, 그리고 구성 요소가 어떻게 시작되는지 설명하는 인텐트 필터와 같은 기능을 선언할 수도 있습니다. 앱 구성 요소에 대해 자세히 알아보세요.
  • 앱이 시스템 또는 다른 앱의 보호된 부분에 액세스하기 위해 필요한 권한. 이것은 다른 앱이 이 앱의 콘텐츠에 액세스하고자 하는 경우 반드시 있어야 하는 모든 권한도 선언합니다. 권한에 대해 자세히 알아보세요.
  • 앱에 필요한 하드웨어 및 소프트웨어 기능으로, 이에 따라 앱을 Google Play에서 설치할 수 있는 기기의 종류가 달라집니다. 기기 호환성에 대해 자세히 알아보세요.

 

앱의 패키지 이름 :)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp"
    android:versionCode="1"
    android:versionName="1.0" >
    ...
</manifest>

예를 들어 다음과 같이 패키지 이름이 "com.example.myapp" manifest 요소를 나타납니다.

 

목적 :)

  • 빌드 도구는 앱에서 생성된 R.java 클래스의 네임스페이스로 이 이름을 적용합니다(앱 리소스에 액세스하는 데 사용).

    예: 위의 매니페스트와 함께 R 클래스가 com.example.myapp.R에서 생성됩니다.

  • 빌드 도구는 이 이름을 사용하여 매니페스트 파일에 선언되어 있는 상대 클래스 이름을 확인합니다.

    예: 위 매니페스트를 사용하면 <activity android:name=".MainActivity">로 선언된 액티비티가 com.example.myapp.MainActivity인 것으로 확인됩니다.

주의 사항:) APK가 컴파일 되고 나면 build.gradle 파일의 applicationId 속성에 지정된 값으로 package을 대신 합니다.

 

앱의 구성 요소:)

앱에서 생성하는 각각의 앱 구성 요소에 대해 매니페스트 파일에서 해당하는 XML 요소를 선언해야 합니다.

activity :)

 

아래와 같이 activity를 name이란 특성으로 지정해야 합니다.

<manifest ... >
    <application ... >
        <activity android:name="com.example.myapp.MainActivity" or ".MainActivity" ... >
        </activity>
    </application>
</manifest>

Intent :)

Intent는 메시징 객체로, 다른 앱 구성 요소로부터 작업을 요청하는 데 사용할 수 있습니다. 인텐트가 구성 요소 사이의 통신을 촉진하는 데는 여러 가지 방식이 있지만 기본적인 사용 사례는 크게 세 가지로 나눌 수 있습니다.

  • 액티비티 시작

    Activity는 앱 안의 단일 화면을 나타냅니다. Activity의 새 인스턴스를 시작하려면 Intent startActivity()로 전달하면 됩니다. Intent는 시작할 액티비티를 설명하고 모든 필수 데이터를 담습니다.

    액티비티가 완료되었을 때 결과를 수신하려면, startActivityForResult()를 호출합니다. 액티비티는 해당 결과를 이 액티비티의 onActivityResult() 콜백에서 별도의 Intent 객체로 수신합니다. 자세한 내용은 액티비티 가이드를 참조하세요.

  • 서비스 시작

    Service는 사용자 인터페이스 없이 백그라운드에서 작업을 수행하는 구성 요소입니다. Android 5.0(API 레벨 21) 이상부터는 JobScheduler로 서비스를 시작할 수 있습니다. JobScheduler에 대한 자세한 내용은 API-reference documentation을 참조하세요.

    Android 5.0(API 레벨 21) 이하 버전은 Service 클래스의 메서드를 사용하면 서비스를 시작할 수 있습니다. 서비스를 시작하여 일회성 작업을 수행하도록 하려면(예: 파일 다운로드) Intent startService()에 전달하면 됩니다. Intent는 시작할 서비스를 설명하고 모든 필수 데이터를 담고 있습니다.

    서비스가 클라이언트-서버 인터페이스로 디자인된 경우, 다른 구성 요소로부터 서비스에 바인딩하려면 Intent bindService()에 전달하면 됩니다. 자세한 내용은 서비스 가이드를 참조하세요.

  • 브로드캐스트 전달

    브로드캐스트는 모든 앱이 수신할 수 있는 메시지입니다. 시스템은 시스템이 부팅될 때 또는 기기가 충전을 시작할 때 등 시스템 이벤트에 대한 다양한 브로드캐스트를 전달합니다. Intent sendBroadcast() 또는 sendOrderedBroadcast()에 전달하면 다른 앱에 브로드캐스트를 전달할 수 있습니다.

인텐트 유형 :)

  • 명시적 인텐트는 인텐트를 충족하는 애플리케이션이 무엇인지 지정합니다. 이를 위해 대상 앱의 패키지 이름 또는 완전히 자격을 갖춘 구성 요소 클래스 이름을 제공합니다. 명시적 인텐트는 일반적으로 앱 안에서 구성 요소를 시작할 때 씁니다. 시작하고자 하는 액티비티 또는 서비스의 클래스 이름을 알고 있기 때문입니다. 예를 들어, 사용자 작업에 응답하여 새로운 액티비티를 시작하거나 백그라운드에서 파일을 다운로드하기 위해 서비스를 시작하는 것 등이 여기에 해당됩니다.
  • 암시적 인텐트는 특정 구성 요소의 이름을 대지 않지만, 그 대신 수행할 일반적인 작업을 선언하여 다른 앱의 구성 요소가 이를 처리할 수 있도록 해줍니다. 예를 들어 사용자에게 지도에 있는 한 위치를 표시하고자 하는 경우, 암시적 인텐트를 사용하여 해당 기능을 갖춘 다른 앱이 지정된 위치를 지도에 표시하도록 요청할 수 있습니다.

Intent-filter :)

앱이 수신할 수 있는 암시적 인텐트가 어느 것인지 알리려면, <intent-filter> 요소를 사용하여 각 앱 구성 요소에 대해 하나 이상의 인텐트 필터를 매니페스트 파일에 선언합니다. 각 인텐트 필터는 인텐트의 작업, 데이터 및 카테고리를 기반으로 어느 유형의 인텐트를 수락하는지 지정합니다. 시스템은 인텐트가 인텐트 필터 중 하나를 통과한 경우에만 암시적 인텐트를 앱 구성 요소에 전달합니다.

참고: 명시적 인텐트는 항상 자신의 대상에게 전달되며, 이는 구성 요소가 어떤 인텐트 필터를 선언하든 무관합니다.

앱 구성 요소는 자신이 수행할 수 있는 각각의 고유한 작업에 대하여 별도의 필터를 선언해야 합니다. 예를 들어 이미지 갤러리 앱에 있는 어떤 액티비티에 두 개의 필터가 있을 수 있습니다. 한 필터는 이미지를 보고, 다른 필터는 이미지를 편집하기 위한 것입니다. 액티비티가 시작되면, Intent를 검사한 다음 Intent에 있는 정보를 근거로 어떻게 동작할 것인지 결정합니다(편집기 제어 항목을 표시할 것인지 말 것인지 등).

각 인텐트 필터는 앱의 매니페스트 파일에 있는 <intent-filter>요소에서 정의하고, 이는 대응되는 앱 구성 요소에서 중첩됩니다(예: <activity> 요소). <intent-filter> 내부에서는 다음과 같은 세 가지 요소 중 하나 이상을 사용하여 허용할 인텐트 유형을 지정할 수 있습니다.

<action>name 특성에서 허용된 인텐트 작업을 선언합니다. 이 값은 어떤 작업의 리터럴 문자열 값이어야 하며, 클래스 상수가 아닙니다.<data>허용된 데이터 유형을 선언합니다. 이때 데이터 URI(scheme, host, port, path)와 MIME 유형의 여러 가지 측면을 나타내는 하나 이상의 특성을 사용합니다.

<category>name 특성에서 허용된 인텐트 카테고리를 선언합니다. 이 값은 어떤 작업의 리터럴 문자열 값이어야 하며, 클래스 상수가 아닙니다.

 

권한 :)

Android 앱은 민감한 사용자 데이터(예: 연락처, SMS) 또는 특정 시스템 기능(예: 카메라, 인터넷 액세스)에 액세스하기 위한 권한을 요청해야 합니다. 각 권한은 고유한 레이블로 식별됩니다. 예를 들어 SMS 메시지를 보내야 하는 앱은 매니페스트에 다음과 같은 줄이 있어야 합니다.

 

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

 

Android 6.0(API 레벨 23)부터 사용자는 런타임에서 일부 앱 권한을 승인하거나 거절할 수 있게 됩니다.

그러나 앱이 어떤 Android 버전을 지원하든 매니페스트에서 <uses-permission> 요소로 모든 권한 요청을 선언해야 합니다.

권한이 부여되면 앱이 보호된 기능을 사용할 수 있습니다.

권한이 부여되지 않으면 그러한 기능에 액세스하려는 시도가 실패합니다.

앱은 권한을 사용하여 자체적인 구성 요소를 보호할 수도 있습니다. Android에서 정의된 권한(android.Manifest.permission에서 설명) 또는 다른 앱에서 선언된 권한을 사용할 수 있습니다. 또한, 앱에서 권한을 정의할 수도 있습니다. 새 권한을 선언할 때는 <permission> 요소를 사용합니다.

 

기기 호환성 :)

매니페스트 파일에서는 앱에 필요한 하드웨어 또는 소프트웨어 기능을 선언할 수 있고, 따라서 앱과 호환되는 기기 유형도 선언할 수 있습니다.

Google Play Store에서는 앱에 필요한 기능이나 시스템 버전을 제공하지 않는 기기에 앱 설치를 허용하지 않습니다.

어느 기기가 앱과 호환되는지 정의하는 매니페스트 태그가 여러 가지 있습니다. 가장 일반적으로 사용하는 태그의 몇 가지 예를 들자면 다음과 같습니다.

 

<uses-feature> 요소를 사용하여 앱에 필요한 하드웨어 및 소프트웨어 기능을 선언할 수 있습니다.

예를 들어 나침반 센서가 없는 기기에서 앱이 기본적인 기능을 실행할 수 없다면, 필요에 따라 다음과 같이 매니페스트 태그를 사용하여 나침반 센서를 선언할 수 있습니다.

<manifest ... >
    <uses-feature android:name="android.hardware.sensor.compass"
                  android:required="true" />
    ...
</manifest>

 

<uses-sdk> 요쇼를 사용하여 앱이 호환되는 최소 버전을 나타내려면 매니패스트에  <uses-sdk> 태그와 해당 태그의 minSdkVersion 특성을 포함해야 합니다.

주의 사항 :)

그러나 <uses-sdk> 요소의 특성은 build.gradle 파일의 해당 속성으로 재정의됩니다.

 

파일 규칙 :)

<manifest>  <application> 요소만 필수입니다.

두 요소는 각각 한 번만 실행되어야 합니다.

다른 요소는 대부분 한 번도 실행되지 않거나 한 번 이상 실행되어도 됩니다. 다만 이들 중 일부가 있어야만 매니페스트 파일에 쓸모가 있습니다.

모든 값은 요소 내의 문자 데이터로서가 아니라 특성을 통해 설정됩니다.

같은 레벨에 있는 여러 요소는 보통 순서가 지정되지 않습니다. 예를 들어 <activity>, <provider>  <service> 요소는 어느 순서로든 배치할 수 있습니다. 이 규칙에는 두 가지 중요한 예외 사항이 있습니다.

다음 표에서는 AndroidManifest.xml 파일에 있는 모든 유효한 요소에 대한 참조 문서의 링크를 제공합니다.

<action> 인텐트 필터에 작업을 추가합니다.
<activity> 액티비티 구성 요소를 선언합니다.
<activity-alias> 액티비티의 별명을 선언합니다.
<application> 애플리케이션을 선언합니다.
<category> 인텐트 필터에 카테고리 이름을 추가합니다.
<compatible-screens> 애플리케이션과 호환되는 각 화면 구성을 지정합니다.
<data> 인텐트 필터에 데이터 사양을 추가합니다.
<grant-uri-permission> 상위 콘텐츠 제공자가 액세스할 권한이 있는 앱 데이터의 하위 집합을 지정합니다.
<instrumentation> 애플리케이션과 시스템의 상호작용을 모니터링할 수 있는 Instrumentation 클래스를 선언합니다.
<intent-filter> 액티비티, 서비스 또는 Broadcast Receiver가 응답할 수 있는 인텐트 유형을 지정합니다.
<manifest> AndroidManifest.xml 파일의 루트 요소입니다.
<meta-data> 상위 구성 요소에 제공할 수 있는 추가적인 임의의 데이터 항목에 대한 이름-값 쌍입니다.
<path-permission> 콘텐츠 제공자 내에서 특정 데이터 하위 집합에 대한 경로와 필수 권한을 정의합니다.
<permission> 이 애플리케이션 또는 다른 애플리케이션의 각 구성 요소나 기능에 대한 액세스를 제한하는 데 사용하는 보안 권한을 선언합니다.
<permission-group> 관련 권한의 논리적 집합에 대한 이름을 선언합니다.
<permission-tree> 권한 트리의 기본 이름을 선언합니다.
<provider> 콘텐츠 제공자 구성 요소를 선언합니다.
<receiver> Broadcast Receiver 구성 요소를 선언합니다.
<service> 서비스 구성 요소를 선언합니다.
<supports-gl-texture> 앱이 지원하는 단일 GL 텍스처 압축을 선언합니다.
<supports-screens> 앱이 지원하는 화면 크기를 선언하고 앱이 지원하는 것보다 큰 화면에 대해서는 화면 호환성 모드를 활성화합니다.
<uses-configuration> 애플리케이션이 요구하는 특정 입력 기능을 나타냅니다.
<uses-feature> 애플리케이션이 사용하는 단일 하드웨어 또는 소프트웨어 기능을 선언합니다.
<uses-library> 애플리케이션과 링크되어야 하는 공유 라이브러리를 지정합니다.
<uses-permission> 앱이 올바르게 작동하기 위해 사용자가 반드시 부여해야 하는 시스템 권한입니다.
<uses-permission-sdk-23> 앱이 특정 권한을 원한다는 것을 지정합니다. 단, 오직 Android 6.0(API 레벨 23) 이상을 실행하는 기기에서 설치되는 경우에만 해당됩니다.
<uses-sdk> 하나 이상의 Android 플랫폼 버전과의 애플리케이션 호환성을 API 레벨 정수로 표시할 수 있습니다.

 

아래의 XML은 앱의 두 가지 액티비티를 선언하는 단순 예시 AndroidManifest.xml입니다.<?xml version="1.0" encoding="utf-8"?>

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0"
    package="com.example.myapp">

    <!-- Beware that these values are overridden by the build.gradle file -->
    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="26" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!-- This name is resolved to com.example.myapp.MainActivity
             based upon the package attribute -->
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".DisplayMessageActivity"
            android:parentActivityName=".MainActivity" />
    </application>
</manifest>

'Client > 안드로이드' 카테고리의 다른 글

paging library ? (페이징 라이브러리)  (0) 2020.03.24
Databinding ?  (0) 2020.03.21
WorkManager ?  (0) 2020.03.18
LiveData ?  (0) 2020.03.18
Picasso , Glide , Fresco  (0) 2020.03.16
Comments