애플리케이션 기본 항목

Android 앱은 Kotlin, Java 프로그래밍 언어, C++ 언어를 사용하여 작성할 수 있습니다. Android SDK 도구는 코드를 데이터 및 리소스 파일과 함께 APK 또는 Android App Bundle로 컴파일합니다.

Android 패키지는 접미사가 .apk인 보관 파일로, 런타임에 필요한 Android 앱의 콘텐츠가 포함되어 있으며 Android 지원 기기가 앱을 설치하는 데 사용하는 파일입니다.

접미사가 .aab인 보관 파일인 Android App Bundle에는 런타임에 필요하지 않은 추가 메타데이터를 비롯한 Android 앱 프로젝트의 콘텐츠가 포함되어 있습니다. AAB는 게시 형식이며 Android 기기에 설치할 수 없습니다. APK 생성 및 서명이 이후 단계로 지연됩니다.

예를 들어 Google Play를 통해 앱을 배포할 때 Google Play 서버는 앱 설치를 요청하는 특정 기기에 필요한 리소스와 코드만 포함하는 최적화된 APK를 생성합니다.

각 Android 앱은 자체 보안 샌드박스에 상주하며 다음 Android 보안 기능으로 보호됩니다.

  • Android 운영체제는 각 앱이 서로 다른 사용자인 멀티 사용자 Linux 시스템입니다.
  • 기본적으로 시스템은 각 앱에 고유한 Linux 사용자 ID를 할당합니다. 이 ID는 시스템에서만 사용하며 앱에서는 알 수 없습니다. 시스템은 앱에 할당된 사용자 ID만 액세스할 수 있도록 앱의 모든 파일에 관한 권한을 설정합니다.
  • 각 프로세스에는 자체 가상 머신 (VM)이 있으므로 앱의 코드가 다른 앱과 격리된 상태로 실행됩니다.
  • 기본적으로 모든 앱이 앱 자체의 Linux 프로세스에서 실행됩니다. Android 시스템은 앱의 구성요소 중 하나를 실행해야 할 때 프로세스를 시작한 다음 더 이상 필요하지 않거나 시스템이 다른 앱을 위해 메모리를 복구해야 하면 프로세스를 종료합니다.

Android 시스템은 최소 권한의 원칙을 구현합니다. 즉, 기본적으로 각 앱은 작업을 실행하는 데 필요한 구성요소에만 액세스할 수 있으며 그 이상은 허용되지 않습니다. 이렇게 하면 매우 안전한 환경이 만들어져 앱이 시스템에서 권한을 부여받지 못한 부분에는 액세스할 수 없게 됩니다.

그러나 앱이 다른 앱과 데이터를 공유하고 앱이 시스템 서비스에 액세스하는 방법에는 여러 가지가 있습니다.

  • 두 앱이 동일한 Linux 사용자 ID를 공유하도록 할 수 있으며, 이 경우 두 앱은 서로의 파일에 액세스할 수 있습니다. 시스템 리소스를 절약하기 위해 사용자 ID가 동일한 앱은 같은 Linux 프로세스에서 실행되고 동일한 VM을 공유하도록 설정할 수도 있습니다. 또한 앱은 동일한 인증서로 서명되어야 합니다.
  • 앱은 기기의 위치, 카메라, 블루투스 연결과 같은 기기 데이터에 액세스하기 위한 권한을 요청할 수 있습니다. 사용자는 이러한 권한을 명시적으로 부여해야 합니다. 권한에 관한 자세한 내용은 Android에서의 권한을 참고하세요.

이 문서의 나머지에서는 다음과 같은 개념을 소개합니다.

  • 앱을 정의하는 핵심 프레임워크 구성 요소.
  • 구성요소 및 앱에 필요한 기기 기능을 선언하는 매니페스트 파일입니다.
  • 앱 코드와는 별개이며 앱에서 다양한 기기 구성에 맞게 동작을 적절하게 최적화할 수 있는 리소스

앱 구성요소

앱 구성요소는 Android 앱의 필수 구성요소입니다. 각 구성요소는 시스템이나 사용자가 앱에 진입할 수 있는 진입점입니다. 일부 구성요소는 다른 구성요소에 종속됩니다.

앱 구성요소에는 네 가지 유형이 있습니다.

  • 활동
  • 서비스
  • broadcast receiver
  • 콘텐츠 제공자

각 유형에는 고유한 목적이 있으며 구성요소의 생성 및 소멸 방식을 정의하는 고유한 수명 주기가 있습니다. 다음 섹션에서는 앱 구성 요소의 네 가지 유형에 대해 설명합니다.

Activity
활동은 사용자와 상호작용하는 진입점입니다. 사용자 인터페이스가 있는 단일 화면을 나타냅니다. 예를 들어 이메일 앱에는 새 이메일 목록을 표시하는 활동, 이메일을 작성하는 활동, 이메일 읽기를 위한 활동이 하나 있을 수 있습니다. 여러 활동이 함께 작동하여 이메일 앱에서 일관된 사용자 환경을 형성하지만 각 활동은 서로 독립적입니다.

이메일 앱에서 허용하는 경우 다른 앱에서 이러한 활동 중 하나를 시작할 수 있습니다. 예를 들어 카메라 앱이 이메일 앱에서 사용자가 사진을 공유할 수 있는 새 이메일을 작성하는 활동을 시작할 수 있습니다.

액티비티는 다음과 같이 시스템과 앱의 주요 상호작용을 돕습니다.

  • 사용자가 현재 관심을 가지고 있는 것(화면에 표시된 내용)을 추적하여 시스템이 활동을 호스팅하는 프로세스를 계속 실행하도록 합니다.
  • 사용자가 돌아갈 수 있는 중지된 활동이 포함된 이전에 사용된 프로세스를 파악하고 이러한 프로세스의 우선순위를 더 높여 프로세스의 가용성을 유지합니다.
  • 앱이 프로세스 종료를 처리하도록 지원하여 사용자가 이전 상태가 복원된 활동으로 돌아갈 수 있도록 합니다.
  • 앱이 서로 사용자 흐름을 구현하고 시스템에서 이러한 흐름을 조정할 수 있는 방법을 제공합니다. 이에 대한 주된 예는 공유입니다.

활동을 Activity 클래스의 서브클래스로 구현합니다. Activity 클래스에 관한 자세한 내용은 활동 소개를 참고하세요.

서비스
서비스는 여러 가지 이유로 앱을 백그라운드에서 계속 실행하기 위한 범용 진입점입니다. 장기 실행 작업을 실행하거나 원격 프로세스의 작업을 실행하기 위해 백그라운드에서 실행되는 구성요소입니다. 서비스는 사용자 인터페이스를 제공하지 않습니다.

예를 들어 서비스는 사용자가 다른 앱에 있는 동안 백그라운드에서 음악을 재생하거나 사용자와 활동의 상호작용을 차단하지 않고 네트워크를 통해 데이터를 가져올 수 있습니다. 활동과 같은 다른 구성요소는 서비스를 시작한 다음 서비스가 실행되도록 하거나 서비스에 바인딩하여 상호작용하도록 할 수 있습니다.

시스템에 앱 관리 방법을 알려주는 두 가지 유형의 서비스가 있습니다. 바로 시작된 서비스와 바인드된 서비스입니다.

시작된 서비스는 작업이 완료될 때까지 서비스를 계속 실행하도록 시스템에 지시합니다. 일부 데이터를 백그라운드에서 동기화하거나 사용자가 앱을 종료한 후에도 음악을 재생하기 위한 작업일 수 있습니다. 백그라운드에서 데이터를 동기화하거나 음악을 재생하는 것은 시작된 서비스의 여러 유형을 나타내며 시스템에서 다르게 처리합니다.

  • 음악 재생은 사용자가 직접 알고 있는 것으로, 앱은 포그라운드에 있기를 원한다고 알리고 사용자에게 실행 중임을 알리는 알림을 통해 이를 시스템에 전달합니다. 이 경우 시스템은 해당 서비스의 프로세스를 실행 상태로 유지하는 것을 우선시합니다. 서비스가 사라지면 사용자의 경험이 저하되기 때문입니다.
  • 일반적인 백그라운드 서비스는 사용자가 직접 인식할 수 있는 것이 아니므로 시스템은 프로세스를 더 자유롭게 관리할 수 있습니다. 사용자와 더 직접적인 관련이 있는 작업에 RAM이 필요한 경우 서비스가 종료되어 나중에 서비스를 다시 시작할 수도 있습니다.

바인드된 서비스는 일부 다른 앱 (또는 시스템)이 서비스를 사용하고 싶다고 밝혔기 때문에 실행됩니다. 바인딩된 서비스는 다른 프로세스에 API를 제공하며 시스템은 이러한 프로세스 간에 종속 항목이 있음을 인식합니다. 따라서 프로세스 A가 프로세스 B의 서비스에 바인딩된 경우 시스템은 프로세스 B와 프로세스 B의 서비스를 A에 대해 실행 상태로 유지해야 한다는 것을 인식합니다. 또한 프로세스 A가 사용자가 관심을 갖는 것이라면 프로세스 B를 사용자가 중요하게 생각하는 것으로 취급합니다.

서비스는 유연성으로 인해 모든 종류의 상위 수준 시스템 개념에 유용한 구성 요소가 됩니다. 라이브 배경화면, 알림 리스너, 화면 보호기, 입력 방법, 접근성 서비스, 기타 여러 핵심 시스템 기능은 모두 애플리케이션이 구현하고 시스템이 실행될 때 결합하는 서비스로 빌드됩니다.

서비스는 Service의 서브클래스로 구현됩니다. Service 클래스에 관한 자세한 내용은 서비스 개요를 참고하세요.

참고: 앱이 Android 5.0 (API 수준 21) 이상을 타겟팅한다면 JobScheduler 클래스를 사용하여 작업을 예약하세요. JobScheduler는 전력 소모를 줄이기 위해 작업을 최적으로 예약하고 Doze API를 사용하여 배터리를 절약하는 이점이 있습니다. 이 클래스 사용에 관한 자세한 내용은 JobScheduler 참조 문서를 확인하세요.

broadcast receiver
broadcast receiver는 앱이 시스템 전체 브로드캐스트 알림에 응답할 수 있도록 시스템이 일반 사용자 플로우 외부에서 앱에 이벤트를 전달할 수 있게 하는 구성요소입니다. broadcast receiver는 앱에 관한 또 다른 잘 정의된 항목이므로 시스템은 현재 실행 중이 아닌 앱에도 브로드캐스트를 전달할 수 있습니다.

따라서 예를 들어 앱에서 사용자에게 예정된 이벤트에 관해 알리는 알림을 게시하도록 알람을 예약할 수 있습니다. 알람은 앱의 BroadcastReceiver에 전달되므로 알람이 울릴 때까지 앱이 실행 중 유지되지 않아도 됩니다.

많은 브로드캐스트는 시스템에서 발생합니다. 예를 들어 화면이 꺼져 있거나 배터리가 부족하거나 사진이 캡처되었음을 알리는 브로드캐스트가 있습니다. 앱은 일부 데이터가 기기에 다운로드되어 사용할 수 있음을 다른 앱에 알리는 등 브로드캐스트를 시작할 수도 있습니다.

broadcast receiver는 사용자 인터페이스를 표시하지 않지만 상태 표시줄 알림을 만들어 브로드캐스트 이벤트가 발생할 때 사용자에게 알릴 수 있습니다. 하지만 broadcast receiver는 다른 구성요소로 연결되는 게이트웨이인 경우가 더 흔하며 최소한의 작업만 실행합니다.

예를 들어 broadcast receiver는 JobScheduler를 사용하여 이벤트를 기반으로 작업을 실행하도록 JobService를 예약할 수 있습니다. Broadcast receiver는 서로 상호작용하는 앱을 포함하는 경우가 많으므로 broadcast receiver를 설정할 때 보안에 미치는 영향을 알고 있어야 합니다.

broadcast receiver는 BroadcastReceiver의 서브클래스로 구현되며 각 브로드캐스트는 Intent 객체로 전달됩니다. 자세한 내용은 BroadcastReceiver 클래스를 참고하세요.

콘텐츠 제공자
콘텐츠 제공자는 파일 시스템, SQLite 데이터베이스, 웹 또는 앱이 액세스할 수 있는 기타 영구 저장소 위치에 저장할 수 있는 공유된 앱 데이터 세트를 관리합니다. 콘텐츠 제공자가 허용하는 경우 다른 앱은 콘텐츠 제공자를 통해 데이터를 쿼리하거나 수정할 수 있습니다.

예를 들어 Android 시스템은 사용자의 연락처 정보를 관리하는 콘텐츠 제공자를 제공합니다. 적절한 권한이 있는 앱은 콘텐츠 제공자를 쿼리(예: ContactsContract.Data 사용)하여 특정 사람에 관한 정보를 읽고 쓸 수 있습니다.

콘텐츠 제공자를 데이터베이스의 추상화로 생각하기 쉽습니다. 이러한 일반적인 사례를 위해 콘텐츠 제공자에 많은 API와 지원이 내장되어 있기 때문입니다. 그러나 시스템 설계 관점에서 볼 때 핵심 목적은 다릅니다.

시스템에서 콘텐츠 제공자는 URI 스키마로 식별되는 이름이 지정된 데이터 항목을 게시하기 위한 앱의 진입점입니다. 따라서 앱은 앱에 포함된 데이터를 URI 네임스페이스에 매핑하는 방법을 결정하고 이러한 URI를 다른 항목에 제공하여 결과적으로 URI를 사용하여 데이터에 액세스할 수 있습니다. 시스템에서는 이를 통해 앱을 관리할 수 있는 몇 가지 특정 작업이 있습니다.

  • URI를 할당하기 위해 앱을 계속 실행할 필요는 없으므로 URI는 자체 앱이 종료된 후에도 유지될 수 있습니다. 시스템은 이를 소유한 앱이 상응하는 URI에서 앱의 데이터를 검색할 때 여전히 실행 중인지 확인하기만 하면 됩니다.
  • 이 URI는 중요하고 조밀한 보안 모델을 제공합니다. 예를 들어 앱은 클립보드에 있는 이미지의 URI를 배치하되 다른 앱이 자유롭게 액세스할 수 없도록 콘텐츠 제공자를 잠긴 상태로 둘 수 있습니다. 두 번째 앱이 클립보드에 있는 URI에 액세스하려고 하면 시스템은 이 앱이 임시 URI 권한 부여를 사용하여 데이터에 액세스하도록 허용할 수 있습니다. 그러면 앱이 URI 뒤에 있는 데이터에만 액세스하고 두 번째 앱의 다른 데이터에는 아무것도 액세스할 수 없습니다.

콘텐츠 제공자는 앱 전용이며 공유되지 않는 데이터를 읽고 쓰는 데도 유용합니다.

콘텐츠 제공자는 ContentProvider의 서브클래스로 구현되며, 다른 앱에서 트랜잭션을 실행할 수 있도록 하는 표준 API 세트를 구현해야 합니다. 자세한 내용은 콘텐츠 제공자 개발자 가이드를 참고하세요.

Android 시스템 디자인의 고유한 특징은 어떤 앱이든 다른 앱의 구성요소를 시작할 수 있다는 점입니다. 예를 들어 사용자가 기기 카메라로 사진을 캡처하도록 하려면 사진을 캡처하는 다른 앱이 있을 수 있습니다. 그러면 앱에서 직접 사진을 캡처하는 활동을 개발하는 대신 이 앱을 사용할 수 있습니다. 카메라 앱의 코드를 통합하거나 링크하지 않아도 됩니다. 대신 카메라 앱에서 사진을 캡처하는 활동을 시작할 수 있습니다. 작업이 완료되면 사진이 앱으로 반환되기까지 하여 바로 사용할 수 있습니다. 사용자에게는 마치 카메라가 앱의 일부인 것처럼 보입니다.

시스템이 구성요소를 시작할 때 앱이 아직 실행되고 있지 않다면 그 앱의 프로세스를 시작하고 구성요소에 필요한 클래스를 인스턴스화합니다. 예를 들어 앱이 사진을 캡처하는 카메라 앱에서 활동을 시작하면 이 활동은 앱의 프로세스가 아닌 카메라 앱에 속한 프로세스에서 실행됩니다. 따라서 대부분의 다른 시스템의 앱과 달리 Android 앱에는 단일 진입점이 없습니다. 즉, main() 함수가 없습니다.

시스템은 다른 앱에 대한 액세스를 제한하는 파일 권한을 사용하여 각 앱을 별도의 프로세스에서 실행하므로 앱은 다른 앱에서 구성요소를 직접 활성화할 수 없습니다. 그러나 Android 시스템은 할 수 있습니다. 다른 앱에서 구성요소를 활성화하려면 특정 구성요소를 시작할 인텐트를 지정하는 메시지를 시스템에 전달해야 합니다. 그러면 시스템이 대신 해당 구성 요소를 활성화해줍니다.

구성요소 활성화

인텐트라는 비동기 메시지는 4가지 구성요소 유형 중 3개(활동, 서비스, broadcast receiver)를 활성화합니다. 인텐트는 런타임에서 각 구성 요소를 서로 바인딩합니다. 즉, 구성요소가 내 앱에 속해 있는지 여부와 관계없이 다른 구성요소의 작업을 요청하는 메신저라고 볼 수 있습니다.

인텐트는 Intent 객체로 생성되며, 이 객체는 특정 구성요소 (명시적 인텐트) 또는 특정 유형의 구성요소(암시적 인텐트)를 활성화하기 위한 메시지를 정의합니다.

활동과 서비스의 경우 인텐트는 실행할 작업(예: 무언가를 보기 또는 전송)을 정의하며, 시작할 때 구성요소가 알아야 할 여러 가지 사항 중에서 작업할 데이터의 URI를 지정할 수도 있습니다.

예를 들어 인텐트는 활동에 이미지를 표시하거나 웹페이지를 열기 위한 요청을 전달할 수 있습니다. 경우에 따라 활동을 시작하여 결과를 수신할 수 있으며, 이 경우 활동은 Intent의 결과를 반환하기도 합니다. 사용자가 개인 연락처를 선택하여 반환하도록 하는 인텐트를 실행할 수도 있습니다. 반환 인텐트에는 선택된 연락처를 가리키는 URI가 포함됩니다.

broadcast receiver의 경우 인텐트가 브로드캐스트 알림을 정의합니다. 예를 들어 기기 배터리가 부족함을 나타내는 브로드캐스트에는 배터리 부족을 나타내는 알려진 작업 문자열만 포함됩니다.

활동, 서비스, broadcast receiver와 달리 콘텐츠 제공자는 ContentResolver의 요청으로 타겟팅될 때 활성화됩니다. 콘텐츠 리졸버는 콘텐츠 제공자와의 모든 직접 트랜잭션을 처리하고, 제공자와 트랜잭션을 실행하는 구성요소는 ContentResolver 객체의 메서드를 호출합니다. 이렇게 하면 콘텐츠 제공자와 정보를 요청하는 구성요소 간의 보안상의 이유로 추상화 레이어가 남게 됩니다.

각 유형의 구성 요소를 활성화하는 데는 각기 별도의 메서드가 있습니다.

  • IntentstartActivity()에 전달하거나 활동이 결과를 반환하도록 하려는 경우 startActivityForResult()를 전달하여 활동을 시작하거나 활동에 새로운 작업을 줄 수 있습니다.
  • Android 5.0 (API 수준 21) 이상에서는 JobScheduler 클래스를 사용하여 작업을 예약할 수 있습니다. 이전 Android 버전의 경우 IntentstartService()에 전달하여 서비스를 시작하거나 진행 중인 서비스에 새 안내를 제공할 수 있습니다. IntentbindService()에 전달하여 서비스에 바인딩할 수 있습니다.
  • IntentsendBroadcast() 또는 sendOrderedBroadcast()와 같은 메서드에 전달하여 브로드캐스트를 시작할 수 있습니다.
  • ContentResolver에서 query()를 호출하여 콘텐츠 제공업체에 쿼리를 실행할 수 있습니다.

인텐트 사용에 관한 자세한 내용은 인텐트 및 인텐트 필터 문서를 참고하세요. 다음 문서에서는 특정 구성요소를 활성화하는 방법에 관한 자세한 정보를 제공합니다. 활동 소개, 서비스 개요, BroadcastReceiver, 콘텐츠 제공자

매니페스트 파일

Android 시스템이 앱 구성요소를 시작하려면 먼저 시스템에서 앱의 매니페스트 파일AndroidManifest.xml를 읽어 구성요소가 존재하는지 알아야 합니다. 앱은 앱 프로젝트 디렉터리의 루트에 있는 이 파일에서 모든 구성요소를 선언합니다.

매니페스트는 앱의 구성요소를 선언하는 것 외에도 다음과 같은 여러 작업을 합니다.

  • 앱에 필요한 모든 사용자 권한(예: 인터넷 액세스 또는 사용자 연락처에 관한 읽기 액세스)을 식별합니다.
  • 앱이 사용하는 API에 따라 앱에 필요한 최소 API 수준을 선언합니다.
  • 앱에서 사용하거나 요구하는 하드웨어 및 소프트웨어 기능(예: 카메라, 블루투스 서비스 또는 멀티터치 화면)을 선언합니다.
  • 앱을 연결해야 하는 API 라이브러리(Android 프레임워크 API 제외)(예: Google 지도 라이브러리)를 선언합니다.

구성요소 선언

매니페스트의 기본 작업은 시스템에 앱의 구성요소에 관해 알리는 것입니다. 예를 들어 매니페스트 파일은 활동을 다음과 같이 선언할 수 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:icon="@drawable/app_icon.png" ... >
        <activity android:name="com.example.project.ExampleActivity"
                  android:label="@string/example_label" ... >
        </activity>
        ...
    </application>
</manifest>

<application> 요소에서 android:icon 속성은 앱을 식별하는 아이콘의 리소스를 가리킵니다.

<activity> 요소에서 android:name 속성은 Activity 서브클래스의 정규화된 클래스 이름을 지정하고 android:label 속성은 활동의 사용자에게 표시되는 라벨로 사용할 문자열을 지정합니다.

다음 요소를 사용하여 모든 앱 구성 요소를 선언해야 합니다.

소스에는 포함했지만 매니페스트에 선언하지 않는 활동, 서비스, 콘텐츠 제공자는 시스템에 표시되지 않으므로 실행할 수 없습니다. 그러나 브로드캐스트 수신기는 매니페스트에서 선언되거나 BroadcastReceiver 객체로 코드에서 동적으로 생성되고 registerReceiver()를 호출하여 시스템에 등록될 수 있습니다.

앱의 매니페스트 파일을 구조화하는 방법에 관한 자세한 내용은 앱 매니페스트 개요를 참고하세요.

구성요소 기능 선언

구성요소 활성화 섹션에서 설명한 대로 Intent를 사용하여 활동, 서비스, broadcast receiver를 시작할 수 있습니다. 이렇게 하려면 인텐트에서 구성요소 클래스 이름을 사용하여 타겟 구성요소의 이름을 명시적으로 지정하면 됩니다. 실행할 작업의 유형과 작업을 실행할 데이터(선택사항)를 설명하는 암시적 인텐트를 사용할 수도 있습니다. 암시적 인텐트를 사용하면 시스템이 기기에서 작업을 실행할 수 있는 구성요소를 찾아 시작할 수 있습니다. 인텐트에 설명된 작업을 실행할 수 있는 구성요소가 여러 개인 경우 사용할 구성요소를 선택합니다.

주의: 인텐트를 사용하여 Service를 시작하는 경우 명시적 인텐트를 사용하여 앱이 안전한지 확인하세요. 암시적 인텐트를 사용하여 서비스를 시작하면 보안 위험이 발생합니다. 어느 서비스가 인텐트에 응답하는지 확신할 수 없고 어떤 서비스가 시작하는지 사용자가 볼 수 없기 때문입니다. Android 5.0 (API 수준 21)부터는 암시적 인텐트로 bindService()를 호출하면 시스템에서 예외가 발생합니다. 서비스에 대한 인텐트 필터를 선언하지 마세요.

시스템은 수신된 인텐트를 기기에 있는 다른 앱의 매니페스트 파일에 제공된 인텐트 필터와 비교하여 인텐트에 응답할 수 있는 구성요소를 식별합니다.

앱 매니페스트에서 활동을 선언할 때 선택적으로 활동의 기능을 선언하는 인텐트 필터를 포함하여 다른 앱의 인텐트에 응답할 수 있습니다. <intent-filter> 요소를 구성요소 선언 요소의 하위 요소로 추가하면 됩니다.

예를 들어 새 이메일을 작성하는 활동이 포함된 이메일 앱을 빌드하는 경우 다음 예와 같이 '전송' 인텐트에 응답하여 새 이메일을 보내는 인텐트 필터를 선언할 수 있습니다.

<manifest ... >
    ...
    <application ... >
        <activity android:name="com.example.project.ComposeEmailActivity">
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <data android:type="*/*" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

다른 앱이 ACTION_SEND 작업으로 인텐트를 만들어 startActivity()에 전달하면 시스템은 사용자가 이메일 초안을 작성하고 전송할 수 있도록 활동을 시작할 수 있습니다.

인텐트 필터 만들기에 관한 자세한 내용은 인텐트 및 인텐트 필터 문서를 참고하세요.

앱 요구사항 선언

Android로 구동되는 기기는 다양하지만 모두 동일한 기능을 제공하는 것은 아닙니다. 앱에 필요한 기능이 없는 기기에 앱이 설치되지 않도록 하려면 매니페스트 파일에서 기기 및 소프트웨어 요구사항을 선언하여 앱이 지원하는 기기 유형의 프로필을 명확하게 정의하는 것이 중요합니다.

이러한 선언의 대부분은 정보 제공의 목적으로만 사용됩니다. 시스템에서는 이러한 정보를 읽지 않지만, Google Play와 같은 외부 서비스는 사용자가 기기에서 앱을 검색할 때 필터링을 제공하기 위해 읽습니다.

예를 들어 앱에 카메라가 필요하고 Android 8.0 (API 레벨 26)에 도입된 API를 사용한다고 가정해 보겠습니다. 이러한 요구사항을 선언해야 합니다. minSdkVersiontargetSdkVersion 값은 앱 모듈의 build.gradle 파일에 설정됩니다.

android {
  ...
  defaultConfig {
    ...
    minSdkVersion 26
    targetSdkVersion 29
  }
}

참고: minSdkVersiontargetSdkVersion를 매니페스트 파일에서 직접 설정하지 마세요. 빌드 프로세스 중에 Gradle에 의해 덮어쓰기 때문입니다. 자세한 내용은 API 수준 요구사항 지정을 참고하세요.

앱의 매니페스트 파일에서 카메라 기능을 선언합니다.

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

이 예에 표시된 선언을 사용하면 카메라가 없거나 Android 버전이 8.0 이하인 기기에는 Google Play에서 앱을 설치할 수 없습니다. 그러나 앱이 카메라를 사용하지만 필수는 아니라고 선언할 수도 있습니다. 이렇게 하려면 required 속성을 false로 설정하고 런타임에 기기에 카메라가 있는지 확인하며 필요에 따라 카메라 기능을 사용 중지합니다.

다양한 기기와 앱의 호환성을 관리하는 방법에 관한 자세한 내용은 기기 호환성 개요를 참고하세요.

앱 리소스

Android 앱은 코드 외에도 다양한 요소로 구성됩니다. 이미지, 오디오 파일 및 앱의 시각적 표현과 관련된 모든 리소스와 같이 소스 코드와는 별도의 리소스가 필요합니다. 예를 들어 XML 파일을 사용하여 애니메이션, 메뉴, 스타일, 색상과 활동 사용자 인터페이스의 레이아웃을 정의할 수 있습니다.

앱 리소스를 사용하면 코드를 수정하지 않고도 앱의 다양한 특성을 쉽게 업데이트할 수 있습니다. 일련의 대체 리소스를 제공하면 다양한 기기 설정(예: 여러 언어, 화면 크기)에 맞게 앱을 최적화할 수 있습니다.

Android 프로젝트에 포함된 모든 리소스에 대해 SDK 빌드 도구는 고유한 정수 ID를 정의하며, 이 ID를 사용하여 앱 코드나 XML로 정의된 다른 리소스에서 리소스를 참조할 수 있습니다. 예를 들어 앱에 logo.png (res/drawable/ 디렉터리에 저장됨)라는 이름의 이미지 파일이 포함되어 있으면 SDK 도구는 R.drawable.logo라는 리소스 ID를 생성합니다. 이 ID는 이미지를 참조하고 사용자 인터페이스에 삽입하는 데 사용할 수 있는 앱별 정수에 매핑됩니다.

소스 코드와는 별개로 리소스를 제공하는 것의 가장 중요한 측면 중 하나는 다양한 기기 구성에 맞는 대체 리소스를 제공할 수 있다는 것입니다.

예를 들어 UI 문자열을 XML로 정의하여 문자열을 다른 언어로 번역하고 이 문자열을 별도의 파일로 저장할 수 있습니다. 그러면 Android는 리소스 디렉터리 이름에 추가되는 언어 한정자(예: 프랑스어 문자열 값의 경우 res/values-fr/)와 사용자의 언어 설정을 기반으로 적절한 언어 문자열을 UI에 적용합니다.

Android에서는 대체 리소스에 대한 여러 한정자를 지원합니다. 한정자란 리소스 디렉터리의 이름에 포함하는 짧은 문자열로, 이러한 리소스가 사용되는 기기 설정을 정의합니다.

예를 들어 기기의 화면 방향과 크기에 따라 활동에 다양한 레이아웃을 만들 수 있습니다. 기기 화면이 세로 (세로) 방향인 경우 버튼이 수직으로 정렬된 레이아웃이 필요할 수 있지만, 화면이 가로 모드 (와이드) 방향인 경우 버튼을 가로로 정렬하는 것이 좋습니다. 방향에 따라 레이아웃을 변경하려면 두 개의 레이아웃을 정의하고 각 레이아웃의 디렉터리 이름에 적절한 한정자를 적용하면 됩니다. 그러면 시스템이 현재 기기 방향에 따라 적절한 레이아웃을 자동으로 적용합니다.

애플리케이션에 포함할 수 있는 여러 종류의 리소스 및 여러 기기 설정에 맞는 대체 리소스를 만드는 방법에 관한 자세한 내용은 앱 리소스 개요를 참고하세요. 권장사항 및 강력한 프로덕션 품질의 앱 설계에 관한 자세한 내용은 앱 아키텍처 가이드를 참고하세요.

추가 리소스

동영상 및 코드 튜토리얼을 사용하여 Android 개발을 알아보려면 Kotlin을 사용하여 Android 앱 개발 Udacity 과정을 참고하세요.

계속 읽기:

인텐트 및 인텐트 필터
Intent API를 사용하여 활동 및 서비스와 같은 앱 구성요소를 활성화하는 방법과 앱 구성요소를 다른 앱에서 사용할 수 있도록 하는 방법을 알아봅니다.
활동 소개
애플리케이션에서 사용자 인터페이스가 있는 고유한 화면을 제공하는 Activity 클래스의 인스턴스를 만드는 방법을 알아봅니다.
앱 리소스 개요
특정 기기 구성에 관한 대체 리소스를 제공하는 방법을 비롯하여 Android 앱이 앱 코드와 별개의 앱 리소스에 대해 어떻게 구성되는지 알아봅니다.

기타 관심 사항:

기기 호환성 개요
Android가 다양한 유형의 기기에서 작동하는 방식과 각 기기에 맞게 앱을 최적화하거나 앱의 가용성을 여러 기기로 제한하는 방법을 알아봅니다.
Android에서의 권한
앱에서 특정 API를 사용하려면 사용자의 동의를 요구하는 권한 시스템을 통해 Android에서 앱의 액세스를 제한하는 방법을 알아봅니다.