앱을 만들 때는 기기에 설치된 다른 앱, 즉 내 앱에서 액세스하려는 앱을 표시하는 패키지 집합을 고려하는 것이 중요합니다. 앱이 Android 11(API 수준 30) 이상을 타겟팅한다면 시스템에서 일부 앱은 내 앱에 자동으로 표시되게 하지만 어떤 앱은 기본적으로 숨깁니다. 기본적으로 일부 앱이 표시되지 않도록 하여 앱에 표시될 다른 앱을 시스템에 알림으로써 최소 권한의 원칙을 시스템을 통해 권장할 수 있습니다. 또한 앱 스토어(예: Google Play)에서 앱이 사용자에게 제공하는 개인정보 보호 및 보안을 평가할 수 있습니다.
이러한 앱 공개 상태의 차이는 다른 앱에 관한 정보를 제공하는 메서드(예: queryIntentActivities()
)의 반환 결과에 영향을 미칩니다.
공개 상태의 차이는 다른 앱과의 명시적 상호작용(예: 다른 앱의 서비스 시작)에도 영향을 줍니다.
이 가이드에서는 자동으로 앱에 표시되는 일련의 앱을 나열하고 앱에 다른 앱이 표시되도록 하는 방법을 설명합니다. 또한 다른 앱의 공개 상태가 내 앱에 미치는 영향을 확인하기 위해 로그 메시지를 구성하는 몇 가지 방법도 제안합니다.
자동으로 표시되는 앱
시스템에서는 앱이 <queries>
요소를 선언하지 않고 다른 앱과 상호작용할 수 있도록 일부 앱을 자동으로 표시합니다. 이 동작을 사용하면 기본 기능과 일반 사용 사례를 지원하는 데 도움이 됩니다.
특히, 앱에서 Android 11(API 수준 30) 이상을 타겟팅하는 경우에도 다음 유형의 앱은 항상 내 앱에 표시됩니다.
- 내 앱
- Android 핵심 기능을 구현하는 특정 시스템 패키지(예: 미디어 제공자). 앱을 실행하는 기기에 자동으로 표시되는 패키지를 확인하는 방법을 자세히 알아보세요.
- 내 앱을 설치한 앱
- 활동에서 결과를 가져오는 방법 가이드에 설명한 대로
startActivityForResult()
메서드를 사용하여 내 앱에서 활동을 실행하는 모든 앱 - 내 앱의 서비스를 시작하거나 바인딩하는 모든 앱
- 내 앱의 콘텐츠 제공자에 액세스하는 모든 앱
- 내 앱에서 콘텐츠 제공자에 액세스하도록 URI 권한을 부여한 콘텐츠 제공자를 보유한 모든 앱
- 내 앱으로부터 입력을 수신하는 모든 앱. 이는 앱에서 입력 방식 편집기(IME)로 입력을 제공하는 경우에만 적용됩니다.
또한, 다른 앱이 내 앱에 표시되는지와 관계없이 암시적 또는 명시적 인텐트를 사용하여 다른 앱의 활동을 시작할 수 있습니다.
자동으로 표시되는 시스템 패키지
앱이 Android 11(API 수준 30) 이상을 타겟팅하는 경우에도 Android 핵심 기능을 구현하는 일부 시스템 패키지는 앱에 자동으로 표시됩니다. 구체적인 패키지 집합은 앱을 실행하는 기기에 따라 다릅니다.
특정 기기의 전체 패키지 목록을 보려면 개발 머신의 터미널에서 다음 명령어를 실행합니다.
adb shell dumpsys package queries
명령어 결과에서 forceQueryable
섹션을 찾습니다. 이 섹션에는 기기가 앱에 자동으로 표시되도록 한 패키지 목록이 포함됩니다.
앱이 다른 앱 집합과 상호작용한다고 선언
앱이 Android 11(API 수준 30) 이상을 타겟팅하며 자동으로 표시되는 앱이 아닌 다른 앱과 상호작용해야 한다면 앱의 매니페스트 파일에 <queries>
요소를 추가하세요. 다음 섹션에서 설명한 대로 <queries>
요소 내에 패키지 이름, 인텐트 서명 또는 제공자 권한으로 다른 앱을 지정합니다.
특정 패키지 쿼리 및 상호작용
쿼리하거나 상호작용하려는 특정 앱 세트(예: 내 앱과 통합된 앱 또는 내가 사용 중인 서비스를 제공하는 앱)를 알고 있다면 <queries>
요소 내의 <package>
요소 세트에 패키지 이름을 포함합니다.
<manifest package="com.example.game"> <queries> <package android:name="com.example.store" /> <package android:name="com.example.services" /> </queries> ... </manifest>
인텐트 필터가 제공된 앱 쿼리 및 상호작용
앱이 특정 용도로 사용되는 앱 집합을 쿼리하거나 상호작용해야 하는데 포함할 구체적인 패키지 이름을 모를 수 있습니다. 이럴 때는 <queries>
요소에 인텐트 필터 서명을 나열하면 됩니다. 그러면 <intent-filter>
요소와 일치하는 요소가 있는 앱을 찾을 수 있습니다.
다음 예에서는 앱이 JPEG 이미지 공유를 지원하는 설치된 앱을 확인할 수 있습니다.
<manifest package="com.example.game"> <queries> <intent> <action android:name="android.intent.action.SEND" /> <data android:mimeType="image/jpeg" /> </intent> </queries> ... </manifest>
<intent>
요소에는 몇 가지 제한사항이 있습니다.
- 정확히
<action>
요소 하나를 포함해야 합니다. <data>
요소에서path
,pathPrefix
,pathPattern
또는port
속성을 사용할 수 없습니다. 시스템은 각 속성 값을 일반 와일드 카드 문자(*
)로 설정한 것처럼 동작합니다.<data>
요소의mimeGroup
속성을 사용할 수 없습니다.단일
<intent>
요소의<data>
요소 내에서 다음 각 속성을 최대 한 번 사용할 수 있습니다.mimeType
scheme
host
이러한 속성을 여러
<data>
요소 전체에 배포하거나 단일<data>
요소에서 사용할 수 있습니다.
<intent>
요소는 일반 와일드 카드 문자(*
)를 몇 가지 속성의 값으로 지원합니다.
<action>
요소의name
속성<data>
요소(image/*
)의mimeType
속성의 하위유형<data>
요소(*/*
)의mimeType
속성의 유형 및 하위유형<data>
요소의scheme
속성<data>
요소의host
속성
이전 목록에 달리 지정되지 않은 한 시스템에서는 텍스트와 와일드 카드 문자가 혼합된 경우(예: prefix*
)를 지원하지 않습니다.
제공자 권한이 부여된 앱 쿼리 및 상호작용
콘텐츠 제공자를 쿼리해야 하지만 구체적인 패키지 이름을 모르는 경우 다음 스니펫과 같이 <provider>
요소에서 제공자 권한을 선언할 수 있습니다.
<manifest package="com.example.suite.enterprise"> <queries> <provider android:authorities="com.example.settings.files" /> </queries> ... </manifest>
단일 <queries>
요소에 여러 제공자 권한을 선언할 수 있습니다.
여러 제공자 권한을 선언하려면 다음 단계 중 하나를 완료하세요.
- 단일
<provider>
요소에서 세미콜론으로 구분된 권한 목록을 선언합니다. - 동일한
<queries>
요소 내에 여러<provider>
요소를 모두 포함합니다. 각<provider>
요소에서 단일 권한 또는 세미콜론으로 구분된 권한 목록을 선언합니다.
모든 앱 쿼리 및 상호작용
드물지만 포함하는 구성요소와 상관없이 기기에 설치된 모든 앱을 쿼리하거나 상호작용해야 할 수 있습니다. 앱이 설치된 모든 앱을 확인할 수 있도록 허용하려면 시스템에서 QUERY_ALL_PACKAGES
권한을 제공합니다.
다음 목록은 QUERY_ALL_PACKAGES
권한이 포함하기에 적절한 사용 사례의 예입니다.
- 런처 앱
- 접근성 앱
- 브라우저
- P2P 공유 앱
- 기기 관리 앱
- 보안 앱
하지만 대부분의 경우 자동으로 표시되는 일련의 앱과 상호작용하고 매니페스트 파일에 앱이 액세스해야 하는 다른 앱을 선언하여 앱의 사용 사례를 충족할 수 있습니다. 사용자 개인정보 보호를 준수하기 위해 앱은 앱이 작동하는 데 필요한 패키지 공개 상태를 최소한으로 요청해야 합니다.
예정된 정책 업데이트에서 QUERY_ALL_PACKAGES
권한이 필요한 앱에 관한 가이드라인을 제공하는 Google Play를 확인하세요.
패키지 필터링의 로그 메시지
앱의 기본 공개 상태가 앱에 미치는 영향을 자세히 알아보려면 패키지 필터링의 로그 메시지를 사용 설정하면 됩니다. Android 스튜디오에서 테스트 앱 또는 디버그 가능 앱을 개발하고 있다면 이 기능이 사용 설정됩니다. 그 외에는 터미널 창에서 다음 명령어를 실행하여 수동으로 사용 설정할 수 있습니다.
adb shell pm log-visibility --enable PACKAGE_NAME
그러면 패키지가 PackageManager
객체의 반환 값에서 필터링될 때마다 Logcat의 다음과 유사한 메시지가 표시됩니다.
I/AppsFilter: interaction: PackageSetting{7654321 \ com.example.myapp/12345} -> PackageSetting{...} BLOCKED