필자가 매니페스트를 혼자서 배우면서 주로 많이 참고한 것은 안드로이드 개발자 공식 문서 사이트를 많이 참고 하였다.
매니페스트는 간단하게 한 개만 배우는게 아니라 많은 다양한 속성을 선언해야 하기때문에 공부할 양이 많고 엄청 중요한 내용이다.
혼자서 공부하고 사람들에게 보여주기용이 아니라 나중에 보면 기억이 나게끔 하는용이기 때문에 정리가 난잡할 것이다..
참고 : https://developer.android.com/guide/topics/manifest/manifest-intro?hl=ko#components
✔️ 기본적으로 앱을 만들때의 절차는
- 사용자 인터페이스 작성(XML)
- 자바 코드 작성(JAVA)
- 매니페스트 파일 작성(XML)
순으로 작성하게 된다. 그래서 가장 기본인 매니페스트( 안드로이드 애플리케이션에 대한 각종 정보를 기술한 애플리케이션 명세서 ) 가 무엇인지 알아보기로 했다.
◼️ 1. 매니페스트 ◼️
1.매니페스트란 : XML 파일로 앱의 전반적인 정보 즉 앱의 이름이나 컴포넌트 구성과 같은 정보를 가지고 있다, 또한 '나타내다'로 프로젝트 내에서 어떤 기능들이 사용되고 있는지 나타내는 명세서이다. 앱의 전반적인 정보, 즉, 애플리케이션의 이름이나 앱을 구성하고 있는 컴포터넌트를 기술하고 실행 시에 필요한 권한을 지정하는 역할을 한다.
✔️1-1. 전반적인 매니패스트에 대해서 알았으니 어떤 것을 선언해야 하는지를 알아보겠다.
- 앱의 패키지 이름
- 앱의 구성요소( 모든 액티비티, 서비스, Broadcast Receiver, 콘텐츠 제공자)
( 액티비티 : 사용자 인터페이스 화면을 가지는 하나의 작업
서비스(스레드)독립적 : 백그라운드에서 실행(스레드)되는 컴포넌트로서 오랫동안 실행되는 작업이나 원격 프로세스를 위한 작업 ex)배경 음악을 연주하는 작업(액티비티#1 : 음악 재생화면, 서비스#1 : 음악 재생서비스)
Broadcast Receiver : 방송을 받고 반응하는 컴포넌트, content provider:데이터를 관리하고 다른 애플리케이션에게 제공하는 컴포넌트 ex)전화번호부를 이용한 시스템 ) - 앱이 시스템 또는 다른 앱의 보호된 부분에 허용하기 위해 필요한 권한 <> 다른앱이 이 앱의 보호된 부분을 허용하고자 하는 권한 설정도 선언
의 것들을 선언해야 정상적으로 어플을 작동할 수 있었다. 즉, 어떤 작업을 하면은 어떤 작업을 할 것이다 라는 말을 매니페스트에 적는다고 생각하면 편할 것 이다.
✔️1-2. 구체적으로 들어가서 매니페스트의 상위 속성에 선언되어야 할 것들을 보게 된다면
- xmlns:android: 안드로이드의 네임스페이스를 정의한다.(네임스페이스란 xml 문서 내에서 유일한 엘리먼트나 속성 이름을 제공하기 위해 사용된다.(* 엘리먼트 : 태그의 시작과 끝을 포함해서 그 내부에 들어가는 모든 것) 사용자가 엘리먼트를 자유롭게 설정할 수 있지만 이러한 엘리먼트가 xml 문서 내에서 중복될 수 있는데, 이러한 이름 중복 충돌을 방지하는 것이 네임스페이스의 기능이다)
[네임스페이스를 모른다면 참고 : https://srzero.tistory.com/76 ]. - package : 패키지 이름을 지정하는 데 사용된다. 보통 도메인 주소를 반대로 써서 설정한다. 예를 들어 google.com에서 게시한 애플리케이션의 패키지명은 "com.google.googleapplication"으로 설정한다. R.java(안드로이드 프로젝트에서 사용되는 리소스들을 ID 형태로 관리한다.) 클래스용 네임스페이스로 패키지 이름이 사용되는데, 위의 예시를 다시 들면 R 클래스는 "com.google.googleapplication.R"에 생성된다.
- android:sharedUserId: Android에서는 각 앱에 고유한 사용자 ID를 할당한다. android:sharedUserId은 다른 앱과 공유될 Linux 사용자 ID를 할당한다. 그러나 API 레벨 29에서 지원이 중단되었고 향후 안드로이드 버전에서 삭제될 수 있기에 사용에 유의해야 한다.
- android:sharedUserLabel: 사용자가 읽을 수 있는 공유 사용자 ID에 관한 라벨이다. android:sharedUserId 속성이 설정돼야 한다. 후에 삭제될 수 있는 속성이므로 사용하지 않는 것이 좋다.
- android:targetSandboxVersion: 해당 앱에서 사용할 타겟 샌드박스를 설정한다.(샌드박스란 : 외부로부터 받은 파일을 바로 실행하지 않고 보호된 영역에서 실행시켜 봄으로써 외부로부터 들어오는 파일과 프로그램이 내부 시스템에 악영향을 주는 것을 미연에 방지하는 기술이다. 외부로부터 들어온 프로그램이나 실행 파일을 가상화 내부에서 시험적으로 동작시켜봄으로써 가상화 밖으로는 영향을 주지 않는다. 가상화 기술을 악성행위나 악성코드 감지 시스템에 적용한, 보안 가상화의 일종으로 설명할 수 있다.
안드로이드 샌드박스란 : Android 플랫폼은 Linux 사용자 기반 보호 기능을 활용하여 앱 리소스를 식별하고 분리하며, 앱과 시스템을 악성 앱으로부터 분리한다. 이 기능을 위해서 Android는 각 Android 애플리케이션에 고유한 사용자 ID(UID)를 할당하여 자체 프로세스에서 실행하며, UID를 사용하여 Linux 커널 수준의 애플리케이션 샌드박스를 설정한다.) - android:versionCode: 내부 버전 번호이다. 사용자에게는 표시되지 않는다.
- android:versionName: 사용자에게 표시되는 버전 번호이다.
- android:installLocation: 앱의 기본 설치 위치이다. 기본적으로 앱은 내부 저장소에 설치되며, 'auto' 또는 'preferExternal' 값을 설정하여 외부 저장소에 설치할 수 있다.
정도를 매니페스트의 상위 속성으로 선언 할 수 있다.
✔️1-3. 매니페스트의 상위 속성 밑에 하위 속성 들은
- <compatible-screens> : 애플리케이션과 호환되는 각 화면 구성을 지정한다.
- <instrumentation> : 애플리케이션과 시스템의 상호작용을 모니터링 할 수 있는 Instrumentation 클래스를 선언한다.
- <permission> : 콘텐츠 제공자 내에서 특정 데이터 하위 집합에 대한 경로와 필수 권한을 정의합니다.
- <permission-group> : 관련 권한의 논리적 집합에 대한 이름을 선언한다.
- <permission-tree> : 권한 트리의 기본 이름을 선언한다.
- <queries> :
- <supports-gl-texture> : 앱이 지원하는 단일 GL 텍스처 압축을 선언한다.
- <supports-screens> : 앱이 지원하는 화면 크기를 선언하고 앱이 지원하는 것보다 큰 화면에 대해 화면 호환성 모드를 활성화한다.
- <uses-configuration> : 애플리케이션이 요구하는 특정 입력 기능을 나타낸다.
- <uses-feature> : 애플리케이션이 사용하는 단일 하드웨어 도는 소프트웨어 기능을 선언한다.
- <uses-permission> : 앱이 올바르게 작동하기 위해 사용자가 반드시 부여해야 하는 시스템 권한이다.
- <uses-permission-sdk-23> : 앱이 특정 권한을 원한다는 것을 지정한다. 단, 오직 Android 6.0(API 레벨 23)이상을 실행하는 기기에서 설치되는 경우에만 해당된다.
- <uses-sdk> : 하나 이상의 Android 플랫폼 버전과의 애플리케이션 호환성을 API 레벨 정수로 표시 할 수 있다.
- <application> : 어플리케이션을 선언한다.
의 하위 속성들이 있고 이 하위 속성에 대해서는 의미하는 바가 다르고 그 안에 속해 있는 하위 속성도 조금씩 다르다. 그 주 가장 많이 쓰이고 중요한 <application>의 속성에 대해서 알아보자. (<application>의 속성에 대해 자세히 공부하고 다른 속성이 필요할때도 이와 같은 방식으로 공부하고 쓰면 되겠구나 라는 느낌으로 공부했다.)
◼️ 2. application ◼️
✔️2. <application> : Android manifest 파일 내에 한 번 반드시 사용돼야 하는 항목이다. 애플리케이션 선언, 애플리케이션의 각 구성요소를 선언하고 그 하위 요소를 포함한다. <application>안에서 쓸 수 있는 하위 속성으로는 <activity> <activity-alias> <meta-data> <service> <receiver> <profileable> <provider> <uses-library> <uses-native-library> 가 있다.
◼️ <application>에서 사용 가능한 속성들은
- android:allowTaskReparenting
>> 애플리케이션이 정의하는 활동이 시작한 작업에서 비롯되지 않고 포그라운드에서 실행될 때 어피니티를 가지는 작업에서 출발하도록 이동할 수 있는지 여부. 있다면 true, 앱 시작한 작업에 머물러 잇어야 한다면 false.
예) 유저가 이메일을 읽다가 인터넷 주소링크 클릭시, false로 되어있다면 새롭게 띄워진 웹페이지는 E-mail task의 가장 윗 층을 차지, true라면 웹브라우저의 task로 이동하게(Re-parenting=부모 재지정) 된다.
-> 원래 이메일 task에서는 해당 웹페이지가 빠지게 된다.
선호하는 어피니티 설정은 android:taskAffinity 여기서 설정한다.
- android:allowBackup
>> 앱이 백업 및 복원 인프라에 참여하도록 허용할지 여부, false이면 전체 시스템 백업에 의해서도 백업 및 복원이 수행되지 않으므로 기본값은 true이다. - android:allowClearUserData
>> 앱이 사용자 데이터(사용자가 소개 도움발을 봤는지 여부 플래그, 사용자 환경설정)를 재설정하도록 허용할지 여부 기본값은 true. - android:backupAgent
>> 백업에이전트인 BackupAgent의 서브 클래스를 구현하는 클래스 이름. - android:backupInForeground
>> 앱이 포그라운드에 상응하는 상태일 때도 앱에서 자동 백업 작업이 수행될 수 있다는 것을 나타냄. 기본값은 false이며 이 경우 OS는 앱이 포그라운드에서 실행되는 동안 백업되지 않게 함. - android:banner
>> 연결된 항목에 확장 그래픽 배너를 제공하는 드로어블 리소스. 기본값 x - android:debuggable
>> 사용자 모드로 기기에서 실행할 때에서 앱디버그 할 수 있는지 여부. 기본값은 false. - android:description
>> 앱에 관해 사용자가 읽을 수 있는 텍스트. 이 값은 문자열 리소스 참조로 설정해야한다. 기본값 x - android:directBootAware
>> 앱이 직접 부팅을 인식하는지 여부, 사용자가 기기를 잠금해제 하기 전에 앱이 실행될 수 있을지 여부. 기본값은 false. - android:enabled
>> 앱의 구성요소를 인스턴스화할 수 있는지 여부이다. true일 경우 각 구성요소의 enabled 속성은 구성요소가 사용 설정 되는지 여부를 결정하고, 값이 false이면 이 속성은 구성요소별 값을 재정의하여 모든 구성요소가 사용 중지된다. - android:extractNativeLibs
>> 패키지 설치 프로그램이 APK에서 파일 시스템으로 네이티브 라이브러리를 추출하는지 여부이다. - android:fullBackupContent
>> 자동 백업용 전체 백업 규칙이 포함된 XML파일을 가리킨다.(규칙에 다라 백업대상 파일을 결정한다.) - android:fullBackupOnly
>> 자동 백업을 기기에서 사용할지 여부이다. 기본값은 false이다. - android:hasCode
>> 앱에 코드가 포함되는지 여부이다. false이면 구성요소를 시작할 때 앱 코드를 로드하지 않는다. 기본값은 true이다. - android:hasFragileUserData
>> 사용자가 앱을 제거할 때 사용자에게 앱의 데이터를 유지하라는 메시지를 표시할지 여부입니다. 기본값은 "false"입니다. - android:hardwareAccelerated
>> 앱의 모든 활동과 뷰에 하드웨어 가속 렌더링을 사용설정해야하는지 여부이다. - android:icon
>> 전체 앱의 각 구성요소의 기본 아이콘이다. 이 속성은 이미지가 포함된 드로어블 리소스의 참조로 설정한다. (예: "@drawable/icon"). - android:killAfterRestore
>> 전체 시스템 복원 작업 중에 설정이 복원된 후 문제의 앱을 종료할 지 여부이다. 기본값은 true로 앱이 데이터 처리를 완료한 후에 앱이 종료된다. - android:largeHeap
>> 대규모 Dalvik 힙으로 애플리케이션의 프로세스를 생성해야 하는지 여부, 대부분의 앱에서는 이 속성이 필요하지 않으며 대신 성능 개선을 위해 전체 메모리 사용량을 줄이는 데 초점을 맞춰야 한다. - android:label
>> 전체 앱을 나타내는 사용자가 읽을 수 있는 라벨 및 각 구성요소의 기본라벨이다. - android:logo
>> 전체 앱의 로고 및 활동을 나타내는 기본 로고이다. 이 속성은 이미지가 포함된 드로어블 리소스의 참조로 설정한다.
(예: "@drawable/icon").
- android:manageSpaceActivity
>> 사용자가 기기에서 앱이 차지하는 메모리를 관리할 수 있게 시스템이 시작할 수 있는 액티비티 서브클래스의 정규화된 이름이다.
<activity> 요소를 사용해 활동을 선언해야 합니다.
- android:name
>> 앱에 관해 구현되는 application 서브클래스의 정규화된 이름이다.
- android:networkSecurityConfig
>> 네트워크 보안 구성이 포함된 xml파일 이름 지정한다. - android:permission
>> 클라이언트가 앱과 상호작용하기 위해 있어야 하는 권한의 이름이다. - android:persistent
>> 앱을 항상 실행상태로 유지할 지 여부이다. 기본값은 false이다. - android:process
>> 앱의 모든 구성요소를 실행해야하는 프로세스의 이름이다. 기본적으로 Android는 첫 번째 구성요소를 실행해야 할 때 애플리케이션의 프로세스를 만듭니다. 그런 다음 프로세스의 모든 구성요소가 실행됩니다. 기본 프로세스의 이름은 <manifest> 요소에서 설정된 패키지 이름과 일치합니다.
- android:restoreAnyVersion
>> 앱이 백업된 데이터 세트를 복원할 준비가 되었음을 나타낸다. 이 속성의 기본값은 false입니다.
- android:requestLegacyExternalStorage
>> 애플리케이션이 범위 지정 저장소를 선택 해제할지 여부입니다. - android:requiredAccountType
>> 앱이 작동하는데 필요한 계정유형을 지정한다. 앱이 account가 필요하면 com.google과 같은 계정 인증자 유형(AuthenticatorDescription으로 정의됨)과 일치해야한다. 기본값은 null이며, 이 경우 애플리케이션이 계정없이 작동할 수 있음을 나타냄 - android:resizeableActivity
>> 앱이 멀티 윈도우 화면을 지원하는지 여부를 지정한다. true시 분할 화면 모드와 자유 형식 모드로 활동을 시작할 수 있다. - android:restrictedAccountType
>> 앱이 필요한 계정 유형을 지정하며 제한된 프로필이 소유자 사용자가 가진 유형의 계정에 액세스 할 수 있음을 나타낸다.
기본값은 null이며, 이 경우 애플리케이션이 계정 없이 작동할 수 있음을 나타낸다.
- android:supportsRtl
>> 애플리케이션이 오른쪽에서 왼쪽(RTL) 레이아웃을 지원하는지 여부를 선언합니다. 이 속성이 true로, targetSdkVersion이 17 이상으로 설정되면 앱이 RTL 레이아웃을 표시할 수 있도록 시스템에서 다양한 RTL API가 활성화되고 사용됩니다. false로 설정되거나 targetSdkVersion이 16 이하로 설정되면 RTL API가 무시되거나 아무런 영향도 미치지 않아, 앱은 사용자의 언어 선택과 관련된 레이아웃 방향과 상관없이 동일하게 작동하며 레이아웃은 항상 왼쪽에서 오른쪽이 됩니다.
- android:taskAffinity
>> 고유한 taskAffinity 속성을 사용하여 다른 어피니티를 설정하는 활동을 제외하고 애플리케이션 내의 모든 활동에 적용되는 어피니티 이름
- android:testOnly
>> 앱이 테스트만을 목적으로 하는지 여부를 나타낸다. 외부에 노출할 수도 있으며 보안에 허점이 생기지만 테스트는 유용하다. - android:theme
>> 앱의 모든 활동의 기본 테마를 정의하는 스타일 리소스의 참조이다. - android:uiOptions
>> 활동의 UI에 적용되는 추가 옵션이다. ( "none" : 추가 UI 옵션이 없습니다. 기본값입니다. , "splitActionBarWhenNarrow" : 가로 공간이 제한적일 때(예: 핸드셋에서 인물 사진 모드 사용) 화면 하단에 표시줄을 추가하여 앱 바(작업 모음이라고도 함)에 작업 항목을 표시합니다. 상단의 탐색 섹션과 하단의 작업 항목 표시줄로 앱 바가 나뉘게 됩니다. ) - android:vmSafeMode
>> 앱이 가상 머신(VM)을 안전 모드로 작동할지 여부를 나타냅니다. 기본값은 "false"입니다.
정도가 있고 , 향후에 만들 어플리케이션에 원하는 기능을 맞게 선언해주면 될 것이다.
[ 참고 : https://developer.android.com/guide/topics/manifest/application-element ]
◼️ 3. Activity ◼️
✔️3-1. <application>의 태그 안의 하위 속성 중 4대 컴포넌트 중 하나인 <activity> 태그를 살펴 보게 되면
기능 : 애플리케이션의 시각적 사용자 인터페이스 요소를 구현하는 액티비티를 선언한다.
포함 가능한 요소 : <intent-filter>, <meta-data>, <layout> 의 하위속성을 갖을 수 있다.
◼️ 여기서 간단하게 Activity에 대해 설명하자면,
Activity : 안드로이드에서 액티비티는 앱의 화면을 말합니다. 사용자가 직접 누를수 있는 화면이죠. 하지만 개발자 관점에서 본다면 activitiy를 두가지로 볼 수 있습니다. 기능을 담당하는 Java 파일과 UI를 담당하는 xml 파일이 있습니다. 하나의 Java파일에 하나의 xml파일이 연결되어 하나의 화면을 이룬다.
예를 들어, 새로운 화면을 만들고 싶거나/시작화면으로 세팅하고 싶다면 당연히 1개의 Java 파일과 xml 파일을 만들어 줘야겠죠. xml 파일을 원하는대로 만들었다면 Java 파일에서 연결을 시켜줘야한다. 중요한 것은 새로만든 파일을 AndroidManifest.xml에 명시해주어야 합니다. 또한 시작화면으로 세팅하는것도 매니페스트에 선언해줘야한다.(ex) <activity>태그 안 <intent-filter>의 <category>를 통해)
◼️ 메니페스트의 <activity>태그의 사용 가능한 속성 으로는
- android:allowEmbedded
>> 액티비티가 다른 액티비티의 포함된 하위 항목으로 시작할 수 있다. 기본값은 false이다. - android:alwaysRetainTaskState
>> 시스템이 액티비티의 작업 상태를 항상 유지관리하는지 여부를 설정한다. 기본값은 false이며, 기본값일 경우 시스템이 특정 상황에서 작업을 초기 상태로 다시 설정할 수 있다. true인 경우 사용자는 작업을 지운 후에도 다시 방문할 시 항상 마지막 상태의 작업으로 돌아가게 된다. 사용예로는 웹 브라우저 애플리케이션에서 방문한 페이지의 상태를 유지하는 탭을 설정할 때 사용된다. - android:banner
>> 연결된 항목에 대한 그래픽 배너를 제공한다. - android:clearTaskOnLaunch
>> 홈 화면에서 다시 시작할 때마다 루트 액티비티를 제외한 모든 액티비티를 작업에서 제거할지 여부를 결정한다. 기본값은 false로, true인 경우에는 사용자가 작업을 다시 시작할 때마다 액티비티를 작업에서 제거하며 루트 액티비티로 이동한다. - android:colorMode
>> 넓은 색 공간 모드가 호환되는 기기에서 해당 모드로 액티비티가 요청되도록 표시한다. 넓은 색 공간모드에서 더욱 선명한 색을 표시할 수 있다. - android:configChanges
>> 액티비티가 스스로 handling할 구성 변경(환경 변화)을 지정한다. runtime 시 환경 변화가 일어나면, 기본 동작은 Activity가 종료되고 재시작되는 것이다. 하지만 해당 속성을 활용해 환경 변화가 돼도 Activity가 restart되지 않게 할 수 있다. 가급적 사용하지 말아야 하는 속성이다. 이 속성보다는 구성 변경 처리에 관한 문서를 바탕으로 설정해야 한다. - android:directBootAware
>> 액티비티가 직접 부팅을 인식하는지 여부를 설정한다. 기본값은 false이다. - android:documentLaunchMode
>> 시작할 때마다 새 액티비티 인스턴스를 작업에 추가하는 방법을 지정한다. 기본값은 'none'으로, 액티비티가 문서에 대해 새 작업을 생성하지 않는다. 앱에 대한 하나의 작업을 표시하고, 이때 사용자가 마지막으로 호출한 작업이 무엇이든 관계없이 그 작업에서부터 재개한다.
값의 종류로는 : intoExisting, always, none, never 이 있다. [ 참고: 'none' 및 'never' 외의 값에서는 활동을 launchMode="standard"로 정의해야 합니다. 이 속성을 지정하지 않으면 documentLaunchMode="none"이 사용됩니다.] - android:enabled
>> 시스템이 액티비티를 인스턴스화할 수 있는지 여부를 정한다. 기본값은 true이다. - android:excludeFromRecents
>> 이 활동이 새 작업의 루트 활동인 경우 이 속성은 최근 앱 목록에 작업을 표시하지 않을지를 결정합니다. 목록에서 작업을 제외해야 하는 경우 'true'로 설정하고 포함해야 하는 경우 'false'로 설정, 기본값은 'false이다. - android:exported
>> 다른 애플리케이션의 구성요소로 액티비티를 시작할 수 있는지 설정한다. 인텐트 필터가 없는 경우, 이 요소의 기본값은 false이다. - android:finishOnTaskLaunch
>> 사용자가 작업을 다시 시작(홈 화면에서 작업을 선택)할 때마다 액티비티의 기존 인스턴스를 종료할지 여부를 정한다. 기본값은 false이다. - android:hardwareAccelerated
>> 해당 액티비티에 대해 하드웨어 가속 렌더링을 활성화할지 정한다. 기본값은 false이다. 하드웨어 가속 렌더러를 활성화하면 애니메이션과 스크롤이 원활하게 작동하고 응답성이 전반적으로 개선되지만, 하드웨어 가속을 활성화하는 데 필요한 리소스가 증가하면서 앱의 RAM 사용량이 증가한다. - android:icon
>> Activity를 나타내는 아이콘이다. 드로어블 리소스를 참조로 설정한다. - android:immersive
>> 현재 액티비티에 대해 몰입형 모드를 설정한다. 몰입형 모드란 전체 화면을 의미한다. - android:label
>> 액티비티에 대해 사용자가 읽을 수 있는 레이블을 나타낸다. - android:launchMode
>> 액티비티를 시작하는 방법에 대한 지침이다. 기본값은 'standard'이다. 기본값일 때 시스템이 항상 대상 작업에 새 액티비티 인스턴스를 생성하고 인텐트를 해당 인스턴스로 라우팅한다. (모드의 종류는 'standard','singleTop','singleTask','singleInstance')
(인텐트
액티비티끼리 서로 호출하기 위해서 필요한 통신 장치를 의미한다. 텐트에 호출할 대상 컴포넌트가 분명히 명시되어 있는 것을 명시적(Explicit) 인텐트, 호출 대상이 분명히 정해지지 않은 인텐트를 암시적(Implicit) 인텐트라 한다. 각 컴포넌트들은 하나의 독립된 형태로 존재하며, 정해진 역할을 수행한다. 이때, 인텐트를 통하여 다른 애플리케이션의 컴포넌트를 활성화시킬 수 있다.) - android:lockTaskMode
>> 기기가 잠금 작업 모드에서 실행 중일 때 시스템이 이 액티비티를 표시하는 방법을 결정한다.(모드 : "normal", "never", "if_whitelisted", "always" ) 기본값: normal - android:maxRecents
>> 액티비티에 루팅된 작업의 최대 개수가 개요 화면에 나타난다.
(루팅 : 모바일 기기에서 구동되는 안드로이드 운영 체제 상에서 최상위 권한(루트 권한)을 얻음으로 해당 기기의 생산자 또는 판매자 측에서 걸어 놓은 제약을 해제하는 행위를 의미한다.) - android:maxAspectRatio
>> 액티비티가 지원하는 최대 화면비를 설정한다. - android:multiprocess
>> 액티비티 인스턴스를 시작한 구성 요소의 프로세스에서 액티비티 인스턴스를 시작할 수 있는지 여부를 나타낸다. 기본값은 false이다. 사용하는 데 주의가 필요한 속성이다.
(인스턴스 :실행 중인 임의의 프로세스, 클래스의 현재 생성된 오브젝트를 의미한다.) - android:name
>> 액티비티를 구현하는 클래스(Activity의 하위 클래스)의 이름이다. - android:noHistory
>> 사용자가 액티비티 밖으로 탐색하고 화면에 액티비티가 더 이상 표시되지 않을 때 액티비티 스택에서 액티비티를 제거하고 종료(finish() 메서드 호출)하는지 여부를 나타낸다. 기본값은 false이다. 기본값일 시 종료되지 않는다. - android:parentActivityName
>> 액티비티의 논리적 상위 액티비티의 클래스 이름을 입력한다. - android:persistableMode
>> 기기를 다시 시작할 때 포함 작업 내에 액티비티의 인스턴스를 어떤 식으로 보존할지 정의한다. 기본값은 'persistRootOnly'이다. 기본값일 시, 시스템이 다시 시작되면 액티비티 작업이 보존되지만, 루트 액티비티의 시작 인텐트만 사용됩니다. - android:permission
>> 클라이언트가 액티비티를 시작하거나 인텐트에 응답하는 데 필요한 권한의 이름을 입력한다. 이 속성을 설정하지 않는 경우 <application> 요소의 permission 속성이 설정한 권한을 활동에 적용 - android:process
>> 액티비티가 실행해야 하는 프로세스의 이름을 입력한다. - android:relinquishTaskIdentity
>> 액티비티가 작업 스택에서 상위 액티비티에 대한 작업 식별자를 포기하는지 여부를 나타낸다. 기본값은 false이다. - resizeableActivity
>> 앱이 다중 창 표시를 지원하는지 여부를 지정한다. - android:screenOrientation
>> 기기에서 액티비티의 디스플레이 방향을 지정한다. 기본값은 'unspecified'이다. 기본값일 시 시스템이 방향을 선택한다.
(모드 : ‘unspecified’, ‘behind’, ‘landscape’, ‘portrait’, ‘reverseLandscape’, ‘reversePortrait’, ‘sensorLandscape’, ‘sensorPortrait’, ‘userLandscape’, ‘userPortrait’, ‘sensor’,‘fullSensor’, ‘nosensor’, ‘user’, ‘fullUser’, ‘locked’ ) - android:showForAllUsers
>> 기기의 현재 사용자가 액티비티를 시작한 사용자와 다를 경우 액티비티를 표시할지 설정한다. - android:stateNotNeeded
>> 상태를 저장하지 않고 액티비티를 중지했다가 다시 시작할 수 있는지 여부를 지정한다. 기본값은 false이다. - supportsPictureInPicture
>> 액티비티가 화면 속 화면 표시를 지원하는지 여부를 지정한다.
[참고 : https://developer.android.com/guide/topics/ui/picture-in-picture] - android:theme
>> 액티비티의 전체 테마를 정의하는 스타일 리소스에 대해 참조한다. - android:uiOptions
>> 액티비티 UI에 대한 추가 옵션이다. (값 : "none" , "splitActionBarWhenNarrow") 기본값은 "none" - android:windowSoftInputMode
>> 액티비티의 기본 창이 화상 키보드를 포함하는 창과 상호작용하는 방법을 지정한다.
(모드: ‘stateUnspecified’,‘stateUnchanged’,‘stateHidden’,‘stateAlwaysHidden’,‘stateVisible’,‘stateAlwaysVisible’,‘adjustUnspecified’,‘adjustResize’,‘adjustPan’)
<activity> 태그에서 사용할 수 있는 속성은 위와 같다.
✔️3-2. <application>태그 안에 하위 속성 중 컴포넌트<activity-alias>를 살펴보게 되면
targetActivity 속성을 제외하고는 대부분 이전에 배운<activity>속성과 같은 것을 알 수 있다. 같을뿐 아니라 같은 기능을 그대로 가진다. 그렇다면 왜 <activity-alias>라는 것이 존재할까?
◼️ 그 이유를 예를 든다면, <activity> 항목을 추가하여 하나의 Activity component를 등록하였다. 하나의 <activity>항목은 하나의 Activity에 대한 모든 속성을 정의한다. 그렇다면 하나의 <activity>와 같은 또 하나의 <activity>를 정의하고 그에 대한 다른 속성을 정의할 수는 없을까?
즉, 같은 <activity>를 각기 다른 속성으로 활성화 시킬 방법은 없을까?
>> 그것을 가능케 하는 것이 바로 <activity-alias>항목이다. 정리를 하자면 Alias를 사용하는 것은 바로 이렇게 속성을 달리한 Activity를 정의하기 위함이다. 참고로 Activity-Alias는 Target이 되는 Activity의 속성을 모두 상속받는다. 또한 상속 받은 속성을 Activity-Alias에서 재정의 하거나 다른 속성을 추가할 수 있다.
단점으로는 <activity>의 모든 속성을 재정의 하거나 추가할 수 없고, enabled,exported,icon,label,name,permission 만이 사용 가능하다 그래서 쓰이는 곳은 업데이트를 하면서 category LAUNCHER 로 지정했던 녀석의 이름이 바뀌게 되면, 런처 구현에 따라 다르지만 보통 바로가기가 삭제되거나 혹은 아이콘은 존재하지만 "존재하지 않는 앱입니다." 와 같은 메세지를 보이며 연결이 제대로 되지 않는다. 이럴 경우에는 Activity Alias 라는 녀석을 사용하면 이런 사건을 방지할 수 있다. (참고로 activity-alias 를 사용하기 위해서는 alias 가 reference 하는 activity 가 먼저 정의되어야 한다.)
[참고 : https://blog.daum.net/kinpmanse/45 , https://mrgamza.tistory.com/621 , https://aroundck.tistory.com/2744 ]
✔️3-3. <application> 의 태그 안의 하위 속성 중 4대 컴포넌트 중 하나인 <Service> 를 살펴 보게 되면
◼️Service : UI 없이 백그라운드 작업을 수행하는 구성요소이다. Activity 와 비교하면 이해가 쉽다. Activity 가 사용자에게 직접 보이는 화면이라면, Activity 가 종료되어 있는 상태에서도 동작하기 위해 만들어진 구성요소이다.
예를 들어, 전화 앱을 켜놓지 않은 상태에서 전화를 받을 수 있는 것은 백그라운드에서 서비스가 돌아가고 있기 때문이다.
안드로이드 서비스는 U.I 없이 백그라운드에서 실행되는 기능을 말합니다.예를들어 네트워크 통신,음악재생,I/O 작업등의 작업등이 해당된다.
- 서비스 : 메인 쓰레드에서 실행됨(액티비티 생명주기와 독립적인 백그라운드에서 실행)
- 스레드 : 자체 쓰레드에서 실행된다(액티비티 생명주기에서 실행되고, 액티비티가 파괴되면 종료)
주의할점 : 서비스는 메인 스레드에서 실행됩니다. 만약 서비스가 CPU 자원을 많이 소모하는 작업이라면 서비스안에 스레드를 생성해서 작업하는게 좋습니다. 앱이 실행중일때만 필요한 기능이라면 스레드를 사용하는게 맞고 앱이 실행중이지 않을때 실행되어야 한다면 서비스를 이용해야 한다.
◼️ 서비스 타입
- Started 타입 : 이 서비스는 startService() 호출하면 시작됩니다. 한번 시작되면 백그라운드에서 무기한으로 실행됩니다. 보통은 작업이 완료되면 스스로 종료됩니다. 예를들어 파일 다운로드, 음악재생 등이 있습니다. ( onStartComand() )
- Bound 타입 : bindService() 호출후에 시작됩니다. 클라이언트와 서버 와 같이 동작합니다. 액티비티는 서비스에게 어떤 요청을 하고 서비스는 결과값을 반환합니다. Bound 서비스는 여러 액티비티와 연결될 수 있습니다. ( onBind() )
다시 돌아와 메니페스트의 <service> 태그에 대해서 포함 가능한 요소는 <intent-filter>, <meta-data> 정도이고,
◼️ 메니페스트의 <service>태그의 사용 가능한 속성 으로는
- android:description
>> 서비스를 사용자에게 설명하는 문자열입니다. 라벨은 사용자 인터페이스의 다른 문자열처럼 현지화될 수 있도록 문자열 리소스의 참조로 설정 - android:directBootAware
>> 서비스가 직접 부팅을 인식하는지 여부, 즉 사용자가 기기를 잠금 해제하기 전에 서비스가 실행될 수 있는지 여부입니다. - android:enabled
>> 시스템에서 서비스를 인스턴스화할 수 있는지 여부입니다. 인스턴스화할 수 있으면 'true'이고 인스턴스화할 수 없으면 'false'입니다. 기본값은 'true'입니다. <application> 요소에는 서비스를 포함한 모든 애플리케이션 구성요소에 적용되는 자체 enabled 속성이 있습니다. <application> 속성과 <service> 속성이 모두 'true'(두 속성의 기본값)여야 서비스를 사용할 수 있습니다. 둘 중 하나가 'false'이면 서비스가 사용 중지되며 서비스를 인스턴스화할 수 없습니다. - android:exported
>> 다른 애플리케이션의 구성요소가 서비스를 호출하거나 서비스와 상호작용할 수 있는지 여부입니다. 할 수 있으면 'true', 할 수 없으면 'false'입니다. 이 값이 'false'이면 동일한 애플리케이션의 구성요소 또는 동일한 사용자 ID를 가진 애플리케이션만 서비스를 시작하거나 서비스에 바인딩할 수 있습니다. 인텐트 필터가 없는 경우 기본값은 false, 인텐트 필터가 하나 이상 있으면 기본값은 true - android:foregroundServiceType
>> 서비스가 특정 사용 사례를 충족하는 포그라운드 서비스임을 지정합니다. - android:icon
>> 서비스를 나타내는 아이콘 , 이 속성은 이미지 정의가 포함된 드로어블 리소스의 참조로 설정해야 합니다. 이 속성이 설정되지 않은 경우 전체 애플리케이션에 지정된 아이콘이 대신 사용된다. - android:isolatedProcess
>> 이 값을 true로 설정하면 이 서비스는 나머지 시스템에서 분리된 특수한 프로세스 아래에서 실행되고 자체적인 권한이 없습니다. Service API(바인딩 및 시작)를 통해서만 서비스와 통신할 수 있습니다. - android:label
>> 사용자에게 표시될 수 있는 서비스의 이름입니다. 이 속성을 설정하지 않으면 전체 애플리케이션에 설정된 라벨이 대신 사용됩니다. - android:name
>> 서비스를 구현하는 Service 서브클래스의 이름입니다. 애플리케이션을 게시한 후에는 android:exported="false"를 설정하지 않은 경우 이 이름을 변경하면 안 됩니다. 기본값은 없으며, 이름을 지정해야 합니다. - android:permission
>> 서비스를 시작하거나 서비스에 바인딩하기 위해 항목이 반드시 가져야 하는 권한의 이름입니다. startService()나 bindService(), stopService() 호출자가 이 권한을 부여하지 않았을 경우 이 메서드는 작동하지 않고 인텐트 객체가 서비스에 전달되지 않습니다. 이 속성을 설정하지 않은 경우 <application> 요소의 permission 속성이 설정한 권한을 서비스에 적용 - android:process
>> 서비스를 실행할 프로세스의 이름입니다.
<service> 태그에서 사용할 수 있는 속성은 위와 같다.
[ 참고 : https://jitolit.tistory.com/112 , https://jroomstudio.tistory.com/13?category=386216 ]
✔️3-4. <application> 의 태그 안의 하위 속성 중 4대 컴포넌트 중 하나인 <receiver> 를 살펴 보게 되면
◼️ BroadcastReceiver : system 전반에서 특정 이벤트에 대해 응답하는 역할을 한다. 배터리가 부족할 때, 스크린이 캡쳐될 때, 파일 다운로드가 완료되었을 때 등 이러한 행위는 broadcast receiver 를 통해 응답받을 수 있다.
다만 broadcast receiver 자체는 이벤트를 확인하는 기능만 담당할 뿐 사용자에게 이벤트를 알리지는 않는다. 개발자는 이를 알리기 위해서는 notification, Toast 를 사용하여 알림을 전달해야한다.
예를 들어, 핸드폰에서 에어팟 연결이 해제 되었을 경우 서비스에서 실행되고 있는 음악을 일시정지 시키려면, 브로드캐스트 리시버를 통해 이어폰 연결이 해제되었다는 정보를 수신하고 서비스를 종료해야한다.
Ex) 전원 충전, 전원 충전 해제, 비행기 모드 돌입, 애플리케이션 설치 완료 등등
◼️ BroadcastReceiver에서 받을 수 있는 액션의 종류
- ACTION_BOOT_COMPLETED :부팅이 끝났을 때 (RECEIVE_BOOT_COMPLETED 권한등록 필요)
- ACTION_CAMERA_BUTTON : 카메라 버튼이 눌렸을 때
- ACTION_DATE_CHANGED,ACTION_TIME_CHANGED : 폰의 날짜, 시간이 수동으로 변했을때 (설정에서 수정했을때)
- ACTION_SCREEN_OFF, ACTION_SCREEN_ON : 화면 on, off
- ACTION_AIRPLANE_MODE_CHANGED : 비행기 모드
- ACTION_BATTERY_CHANGED, ACTION_BATTERY_LOW, ACTION_BATTERY_OKAY : 배터리 상태변화
- (ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_DATA_CLEARED ,ACTION_PACKAGE_INSTALL,ACTION_PACKAGE_REMOVED,ACTION_PACKAGE_REPLACED,ACTION_PACKAGE_RESTARTED) : 어플 설치/제거
- ACTION_POWER_CONNECTED,ACTION_POWER_DISCONNECTED : 충전 관련
- ACTION_REBOOT,ACTION_SHUTDOWN : 재부팅/종료
- ACTION_TIME_TICK : 매분마다 수신
- android.provider.Telephony.SMS_RECEIVED :sms 수신 (RECEIVE_SMS 권한 필요)
◼️ 정적 BroadcastReceiver / 동적 BroadcastReceiver
- 정적 BroadcastReceiver : 앱이 실행되지 않은 상황에도 리시버가 등록이 되어 있기 때문에 모든 이벤트를 수신 할 수 있다.하지만 리시버를 해제할 수는 없다. 매니페스트에 등록한다.
- 동적 BroadcastReceiver : 앱이 실행되는 상황에서만 리시버가 등록이 되어 있다. 원하는 시간, 상황에 리시버를 등록하고 해제 할 수 있다. 앱이 실행되지 않으면 리시버를 등록 할 수 없다. 매니페스트에 등록하지 않는다.
◼️ 메니페스트의 <receiver>태그의 사용 가능한 속성 으로는
- android:directBootAware : broadcast receiver가 직접 부팅을 인식하는지 여부입니다. 즉, 사용자가 기기를 잠금 해제하기 전에 실행할 수 있는지 여부입니다. 기본값 : false
- android:enabled : 시스템에서 broadcast receiver를 인스턴스화할 수 있는지 여부입니다. broadcast receiver가 인스턴스화될 수 있으면 'true', 인스턴스화될 수 없으면 'false'입니다. 기본값은 'true'입니다.
- android:exported : broadcast receiver에서 애플리케이션 외부의 비시스템 소스에서 메시지를 수신할 수 있는지 여부입니다. 수신할 수 있으면 'true', 수신할 수 없으면 'false'입니다. 'false'인 경우 broadcast receiver는 시스템이나 동일한 애플리케이션의 구성요소, 사용자 ID가 같은 애플리케이션에서 보낸 메시지만 수신할 수 있습니다. 기본값에 대해서 broadcast receiver에 인텐트 필터가 1개 이상 포함되어 있으면 기본값은 'true'이고 그 외 경우 기본값은 'false'입니다.
- android:icon : broadcast receiver를 나타내는 아이콘입니다. 이 속성은 이미지 정의가 포함된 드로어블 리소스의 참조로 설정해야 합니다. 이 속성이 설정되지 않은 경우 전체 애플리케이션에 지정된 아이콘이 대신 사용됩니다
- android:label : broadcast receiver에 관한 사용자가 읽을 수 있는 라벨입니다. 이 속성을 설정하지 않으면 전체 애플리케이션에 설정된 라벨이 대신 사용됩니다
- android:name : broadcast receiver를 구현하는 클래스의 이름으로, BroadcastReceiver의 서브클래스입니다. 애플리케이션을 게시한 후에는 android:exported="false"를 설정하지 않은 경우 이 이름을 변경하면 안 됩니다. 기본값은 없으며, 이름을 지정해야 합니다.
- android:permission : broadcaster가 broadcast receiver에 메시지를 보내는 데 필요한 권한 이름입니다. 이 속성이 설정되어 있지 않으면 <application> 요소의 permission 속성에서 설정한 권한이 broadcast receiver에 적용됩니다. 아무 속성도 설정되어 있지 않으면 receiver가 권한으로 보호되지 않습니다.
- android:process : broadcast receiver가 실행되어야 하는 프로세스의 이름입니다. 일반적으로 애플리케이션의 모든 구성요소는 애플리케이션용으로 만들어진 기본 프로세스에서 실행됩니다.
<receiver> 태그에서 사용할 수 있는 속성은 위와 같다.
[참고 : https://codechacha.com/ko/android-broadcast-receiver/ , https://developer.android.com/guide/topics/manifest/receiver-element ]
✔️3-5. <application> 의 태그 안의 하위 속성 중 4대 컴포넌트 중 하나인 <Content Provider> 를 살펴 보게 되면
◼️ Content Provider : 앱 내에서 사용할 수 있는 데이터를 공유하기 위한 구성요소로 앱은 Content Provider에만 접근하며 필요한 데이터를 얻어올 수 있다.
일반적으로 어플리케이션에서 자료를 저장할 때 DB를 주로 사용한다. 이때 한 어플리케이션 내에 저장되어 있는 DB에는 해당 앱 외에 다른 앱이 접근하는 것이 불가능하다.
그렇다면 다른 앱이 데이터에 접근할 수 있는 방법은 없는 것인가? 그렇지 않다.
외부 어플리케이션이 마음대로 내 DB에 접근하지 못하게 하면서 동시에 내가 가진 DB 중 원하는 것들만 공유할 수 있도록 해주는 역할을 하는 것이 바로 Contents Provider 이다.
Ex) 전화번호부에 등록되어 있는 전화번호 데이터가 자동으로 연동되어 카카오톡에 친구가 추가된다. 이것이 가능한 이유는 전화번호부에 content provider가 전화번호부에 접근할 수 있게 해주는 것이고 카카오톡의 content resolver 가 번호를 요청하여 친구추가에 이용하는 것이다.
즉, 외부 앱이 특정 앱의 DB 정보가 필요한 경우, 외부 앱은 컨텐트 리졸브를 통해 Uri를 해당 앱에 보내고, 해당 앱의 컨텐트 프로바이더가 Uri를 해석하여 필요한 DB작업을 하게 된다. 이때, Uri를 전달받은 컨텐트 프로바이더는 기본적은 CRUD 연산을 모두 처리 가능하다. 컨텐트 프로바이더는 필요한 작업을 모두 수행하고, 결과값을 컨텐트 리졸브에 반환한다. 즉, 컨텐트 프로바이더와 컨텐트 리졸브를 통해 앱과 앱 사이에 데이터베이스를 공유하면서 직접적인 접근을 차단할 수 있다.
◼️ 사용방법 : 사용방법은 꽤 복잡하기에 간단하게 하고 첨부 링크를 대체하겠다.
1. 데이터 베이스를 만들어 데이터를 저장한다. 2. 콘탠트 프로바이더클래스를 생성한다. 3. 프로바이더 클래스로 찾아올 수 있도록 uri도 알려준다. 4. 콘탠트 리졸브를 생성하여 crud 기능을 구현한다.
[ https://choidev-1.tistory.com/56 , https://jroomstudio.tistory.com/15 ]
◼️ 메니페스트의 < Content Provider >태그의 사용 가능한 속성 으로는
- android:authorities : 콘텐츠 제공자에서 제공되는 데이터를 식별하는 URI 권한을 하나 이상 보여주는 목록입니다. 기본값은 없으며 권한을 하나 이상 지정
- android:enabled : 시스템에서 콘텐츠 제공자를 인스턴스화할 수 있는지 여부입니다. 인스턴스화할 수 있으면 'true'이고 인스턴스화할 수 없으면 'false'입니다. 기본값은 'true'
- android:directBootAware : 콘텐츠 제공자가 직접 부팅을 인식하는지, 즉 사용자가 기기를 잠금 해제하기 전에 콘텐츠 제공자를 실행하도록 허용할지 지정합니다. 기본값은 "false"
- android:exported : 다른 애플리케이션에서 콘텐츠 제공자를 사용할 수 있는지 지정합니다.
- android:grantUriPermissions : 일반적으로는 콘텐츠 제공자의 데이터에 액세스할 권한이 없는 사용자에게 액세스 권한을 부여함으로써 readPermission, writePermission, permission, exported 속성에 따른 제한을 일시적으로 극복할 수 있는지 여부입니다. 부여할 수 있으면 'true'이고 부여할 수 없으면 'false'입니다. 'true'일 때는 콘텐츠 제공자의 모든 데이터에 액세스할 권한을 부여할 수 있습니다. 'false'일 때는 <grant-uri-permission> 하위 요소(있는 경우)에 나열된 데이터 하위 집합에만 액세스할 권한을 부여할 수 있습니다. 기본값은 'false'입니다.
- android:icon : 콘텐츠 제공자를 나타내는 아이콘입니다.
- android:initOrder : 동일한 프로세스에서 호스팅하는 다른 콘텐츠 제공자에 상대적으로 콘텐츠 제공자를 인스턴스화해야 하는 순서입니다.
- android:label : 제공된 콘텐츠와 관련하여 사용자가 읽을 수 있는 라벨입니다.
- android:multiprocess : 앱이 여러 프로세스에서 실행되는 경우 이 속성은 콘텐츠 제공자 인스턴스를 여러 개 만들지 결정합니다. true이면 앱의 각 프로세스마다 고유한 콘텐츠 제공자 객체가 있고, false이면 앱의 여러 프로세스가 콘텐츠 제공자 객체 하나만 공유합니다. 기본값은 false입니다.
- android:name : 콘텐츠 제공자를 구현하는 클래스이자 ContentProvider의 서브클래스의 이름입니다, 기본값은 없으며 이름을 지정해야 합니다.
- android:permission : 클라이언트가 콘텐츠 제공자의 데이터를 읽거나 쓰기 위해 필요한 권한의 이름입니다.
- android:process : 콘텐츠 제공자가 실행해야 하는 프로세스의 이름입니다.
- android:readPermission : 클라이언트가 콘텐츠 제공자를 쿼리하는 데 필요한 권한입니다.
- android:syncable : 콘텐츠 제공자에 의해 제어되는 데이터를 서버의 데이터와 동기화할지 여부입니다. 동기화하면 'true'이고 동기화하지 않으면 'false'입니다.
- android:writePermission : 클라이언트가 콘텐츠 제공자에 의해 제어되는 데이터를 변경하는 데 필요한 권한입니다.
<receiver> 태그에서 사용할 수 있는 속성은 위와 같다.
[참고 : https://developer.android.com/reference/android/content/ContentProvider ]
✔️3-6. 컴포넌트가 수신하려는 인텐트 유형을 지정하는 중요한 <intent-filter> 를 알아보자.
◼️ 인텐트 : 4대 컴포넌트끼리 유기적으로 정보전달을 가능하게 해주는 역할
◼️ 인텐트의 종류
- 명시적 인텐트 : 인텐트에 클래스 객체나 컴포넌트 이름을 지정하여 호출할 대상을 확실히 알 수 있는 경우에 사용
➡️ 사용하는 이유로는 특정 컴포넌트나 액티비티가 명확하게 실행되어야 할 경우에 사용된다. - 암시적 인텐트 : 인텐트의 액션과 데이터를 지정하긴 했지만, 호출할 대상이 달라질 수 있는 경우에 사용된다. 즉, 설치된 애플리케이션들에 대한 정보를 알고 있는 안드로이드 시스템이 인텐트를 이용해 요청한 정보를 처리 할 수 있는 적절한 컴포넌트를 찾아본 다음 사용자에게 그 대상과 처리 결과를 보여주는 과정을 거치게 된다.
➡️ 사용하는 이유로는 기존에 어떤 기능들을 지원하는 앱들이 있는 경우에 암시적 인텐트를 사용해서 그 앱들을 사용하면 되는 것이다.
◼️ <intent-filter>가 필요한 이유 : 위에서 말했던 암시적인 인텐트를 통해 사용자로 하여금 어느 컴포넌트를 사용할지 선택하도록 하고자 할 때 필요하다. 즉, 안드로이드 시스템 내부에서 수많은 어플리케이션들에 의해 수많은 인텐트들이 발생하는데 이 중 자신에게 필요한 인텐트만 받기 위해 <intent-filter>가 필요한 것이다.
◼️ 암시적 인텐트가 필요한 이유 : 인텐트 필터는 암시적인 인텐트를 받을 때만 필요할 뿐 , 명시적인 인텐트는 인텐트 필터가 없어도 된다.
그렇다면 암시적인 인텐트가 필요한 이유는 자신이 만든 컴포넌트라면 컴포넌트의 이름을 정확히 알 수 있지만, 다른 사람이 만든 컴포넌트의 이름을 알기는 어렵다. 따라서 명시적 인텐트를 사용하여 호출할 수 없다. 이것을 암시적 인텐트, <intent-filter> 를 이용하여 호출할 수 있다.
◼️ intent-filter에 들어가는 정보
- action 필터 : 인텐트 객체 내의 action을 검사여 인텐트 필터에 정의된 액션과 일치하는지 여부를 검사, 이 검사를 통과하려면 인텐트 객체 내의 액션이 인텐트 필터에 정의된 액션과 일치해야함, 인텐트에 액션이 아예 정의되어 있지 않은 경우는 인텐트 액션 필터를 통과가능하다.
ex) 인텐트 객체에 정의된 액션(Intent.Action_VIEW) | 인텐트 필터에 정의된 액션(android.intent.action.View) : 통과
인텐트 객체에 정의된 액션(Intent.Action_VIEW) | 인텐트 필터에 정의된 액션(android.intent.action.EDiT) : 통과하지 못함
인텐트 객체에 정의된 액션(없음) | 인텐트 필터에 정의된 액션(어떤 액션이든 관계없음) : 통과 - category 필터 : 인텐트 객체 내의 category 항목을 검사하여 인텐트 필터에 정의된 카테고리와 일치하는지 여부를 검사한다. 액션 검사에서는 인텐트 객체 내에 아예 액션이 정의되어있지 않은 경우 액션 검사를 통과할 수 있었던 것에 반해 카테고리 검사는 인텐트 객체에 정의된 카테고리가 인텐트 필터에 정의된 카테고리들과 일치해야 한다. 암시적 인텐트를 만들 때 카테고리르 추가하지 않을 경우 안드로이드에서 자동으로 CATEGORY_DEFAULT(android.intent.category.DEFAULT)를 추가해준다.(기본값으로라도 인텐트 필터를 DEFAULT로 설정해야함)
>> 때문에 카테고리를 특별히 추가해주지 않은 인텐트를 받을 수 있게 하려면 카테고리 필터에 android.intent.category.DEFAULT 를 추가해줘야한다.
Ex) 인텐트 객체의 카테고리(intent.category.DEFAULT) | 인텐트 필터의 카테고리(없음) : 통과하지 못함
인텐트 객체의 카테고리(intent.category.DEFAULT) | 인텐트 필터의 카테고리(android. intent.category.DEFAULT) : 통과 - data 필터 : 인텐트 객체 내의 data 항목 및 type을 검사하여 인텐트 필터에 정의된 값과 비교하여 일치 여부를 검사한다.
데이터 검사는 크게 데이터의 주소(URI)를 검사하는 부분과 데이터의 유형(type, MIME type)을 검사하는 부분으로 나누어진다.
데이터의 주소를 검사하는 부분 예시)
➡️ <action>태그의 경우 MAIN 이 되어야하고 <category> 태그의 경우 LAUNCHER 되어야 한다.
\✔️3-7. <activity> 태그는 물론 <application> 등등 모든 항목의 하위 속성으로 들어가 있는 <meta-data> 태그를 보게 되면
메타데이터의 뜻 : 데이터에 대한 데이터 쉽게 말해, 다른 데이터를 설명해주는 데이터이다
(대량의 정보 가운데에서 찾고 있는 정보를 효율적으로 찾아내서 이용하기 위해 일정한 규칙에 따라, 콘텐츠에 대하여 부여되며, 구조화된 정보를 분석, 분류하고 부가적 정보를 추가하기 위해 그 데이터 뒤에 함께 따라가는 정보를 말한다.)
◼️ meta-data 에서 사용 할 수 있는 속성
- android:name : 아이템의 이름을 설정한다. 'com.example.project.activity.fred' 와 같이 자바 스타일의 명명 규칙을 사용해야 한다.
- android:resource : 리소스의 레퍼런스다. ID는 Bundle.getInt() 메서드를 사용해 meta-data Bundle로부터 얻을 수 있다
- android:value : 아이템에 할당된 값이다. 할당할 수 있는 데이터 타입과 값을 얻기 위해 사용하는 메서드는 다음과 같다
문자열 값 : getString(), 정수 값 : getInt(), #rgb, #argb 형식의 컬러 값 : getString(), 부동 소수점 값 : getFloat()
◼️ 4. Permission ◼️
✔️4. 앱과 앱 사이의 연동에서 가장 중요한 Permission 에 대해 알아본다.
안드로이드 컴포넌트를 이용한 앱과 앱 사이의 연동이 빈번한데, 이러한 연동에서 어떤 앱이 <permission>을 부여했다면 그 앱을 이용하는 앱은 매니페스트에서 <uses-permission>을 선언해야 한다.
◼️ <permission> 이용 : <permission>은 자신의 앱을 외부에서 이용 할 때 권한을 부여하여 해당 권한을 가지고 들어올 때만 실행되게 하기 위한 설정이다. 즉, <permission>으로 선언된 앱을 이용하는 앱이 <uses-permission>을 선언하지 않으면 실행 시 에러가 발생한다. 쉽게 말해 앱의 컴포넌트를 보호하고 싶을 때는 <permission>을 선언하고, 그렇게 선언된 앱을 이용하려면 <uses-permission>을 선언한다.
◼️<permission> 태그 속성
- name : 퍼미션 이름
- label, description : 퍼미션에 대한 설명
- protectionLevel : 보호 수준
[normal : 낮은 수준의 보호, 사용자에게 권한 부여 요청이 필요 없는 경우, dangerous : 높은 수준의 보호, 사용자에게 권한 부여 요청이 필요한 경우, signature : 동일한 키로 서명된 앱만 실행, signatureOrSystem : 안드로이드 시스템 앱이거나 동일 키로 서명된 앱만]