다른 앱과의 상호작용 제한

권한은 시스템 기능을 요청하기 위해서만 사용되는 것은 아닙니다. 다른 앱이 내 앱의 구성요소와 상호작용하는 방법을 제한할 수도 있습니다.

이 가이드에서는 다른 앱에서 선언한 권한 집합을 보는 방법을 설명합니다. 또한, 이 가이드에서는 활동, 서비스, 콘텐츠 제공업체, broadcast receiver를 구성하여 다른 앱이 내 앱과 상호작용하는 방식을 제한하는 방법을 설명합니다. 마지막으로 이 페이지에서는 앱 간 상호작용 패턴을 적용하는 여러 방법을 안내합니다.

다른 앱의 권한 보기

다른 앱에서 선언한 권한 집합을 보려면 기기 또는 에뮬레이터를 사용하여 다음 단계를 완료하세요.

  1. 앱의 앱 정보 화면을 엽니다.
  2. 권한을 선택합니다. 앱 권한 화면이 표시됩니다.

    이 화면에는 권한 그룹 집합이 표시됩니다. 시스템에서는 앱이 이러한 그룹에 선언한 권한 집합을 구성합니다.

앱 활동과의 상호작용 제한

android:permission 속성을 사용하여 매니페스트의 <activity>태그에 적용된 권한은 Activity를 시작할 수 있는 사용자를 제한합니다. 권한은 Context.startActivity()Activity.startActivityForResult() 중에 확인됩니다. 필요한 권한이 호출자에 없으면 SecurityException이 발생합니다.

앱 서비스와의 상호작용 제한

android:permission 속성을 사용하여 매니페스트의 <service> 태그에 적용된 권한은 연결된 Service를 시작하거나 바인딩할 수 있는 사용자를 제한합니다. 권한은 Context.startService(), Context.stopService(), Context.bindService() 중에 확인됩니다. 필요한 권한이 호출자에 없으면 SecurityException이 발생합니다.

콘텐츠 제공업체와 앱의 상호작용 제한

android:permission 속성을 사용하여 <provider> 태그에 적용된 권한은 ContentProvider의 데이터에 액세스할 수 있는 사용자를 제한합니다. (콘텐츠 제공업체가 사용할 수 있는 URI 권한이라고 하는 중요한 추가 보안 기능이 있습니다. 이에 관해서는 뒷부분에서 설명합니다.) 다른 구성요소와 달리 두 가지 개별적인 권한 속성을 설정할 수 있습니다. android:readPermission은 제공업체로부터 데이터를 읽을 수 있는 사용자를 제한하고 android:writePermission은 제공업체에 데이터를 쓸 수 있는 사용자를 제한합니다. 참고로 제공업체가 읽기 및 쓰기 권한을 모두 사용하여 보호되는 경우 쓰기 권한만 보유하면 제공업체로부터 데이터를 읽을 수 없습니다.

처음 제공업체를 검색할 때(두 권한이 모두 없는 경우 SecurityException이 발생함) 그리고 제공업체에서 작업을 실행할 때 권한이 확인됩니다. ContentResolver.query()를 사용하려면 읽기 권한이 있어야 하고 ContentResolver.insert(), ContentResolver.update() 또는 ContentResolver.delete()를 사용하려면 쓰기 권한이 있어야 합니다. 이러한 모든 경우에 필요한 권한이 없으면 SecurityException이 발생합니다.

URI별로 액세스 허용

시스템을 통해 개발자는 다른 앱이 앱의 콘텐츠 제공업체에 액세스할 수 있는 방법을 세밀하게 추가로 제어할 수 있습니다. 특히 콘텐츠 제공업체는 읽기 및 쓰기 권한을 사용해 자체적으로 보호하면서 제공업체의 직속 클라이언트가 특정 URI를 다른 앱과 공유하도록 계속 허용할 수 있습니다. 이 모델에 관한 앱의 지원을 선언하려면 android:grantUriPermissions 속성이나 <grant-uri-permission 요소를 사용하세요.

URI별로 권한을 부여할 수도 있습니다. 활동을 시작하거나 활동에 결과를 반환할 때 Intent.FLAG_GRANT_READ_URI_PERMISSION 인텐트 플래그, Intent.FLAG_GRANT_WRITE_URI_PERMISSION 인텐트 플래그 또는 두 플래그를 모두 설정합니다. 이렇게 하면 인텐트에 포함되어 있는 데이터 URI의 읽기, 쓰기, 읽기/쓰기 권한이 다른 앱에 각각 부여됩니다. 다른 앱은 콘텐츠 제공업체의 데이터에 더 일반적으로 액세스하는 권한이 있는지와 상관없이 이러한 특정 URI 권한을 얻습니다.

예를 들어 사용자가 앱에서 이메일을 보고 있는데 이 이메일에는 이미지가 첨부파일로 포함되어 있다고 가정해 보겠습니다. 일반적으로 다른 앱은 이메일 콘텐츠에 액세스할 수 없어야 하지만 이미지를 보는 데 관심이 있을 수도 있습니다. 앱은 이미지 보기 앱이 이미지를 보도록 인텐트와 Intent.FLAG_GRANT_READ_URI_PERMISSION 인텐트 플래그를 사용할 수 있습니다.

또 다른 고려사항은 앱 가시성입니다. 앱이 Android 11(API 수준 30) 이상을 타겟팅한다면 시스템에서는 일부 앱은 내 앱에 자동으로 표시되게 하지만 어떤 앱은 기본적으로 숨깁니다. 앱이 콘텐츠 제공업체를 보유하고 있고 다른 앱에 URI 권한을 부여한 경우 앱은 다른 앱에 자동으로 표시됩니다.

자세한 내용은 grantUriPermission(), revokeUriPermission(), checkUriPermission() 메서드 관련 참고 자료를 확인하세요.

broadcast receiver와 앱의 상호작용 제한

android:permission 속성을 사용하여 <receiver> 태그에 적용된 권한은 연결된 BroadcastReceiver에 브로드캐스트를 전송할 수 있는 사용자를 제한합니다. 시스템이 제출된 브로드캐스트를 지정된 수신기에 전달하려고 하므로 이 권한은 Context.sendBroadcast()가 반환된 후에 확인됩니다. 따라서 권한 오류로 인해 호출자에 예외가 다시 발생하지 않습니다. Intent만 전달하지 않습니다.

같은 방법으로 권한을 Context.registerReceiver()에 제공하여 프로그래매틱 방식으로 등록된 수신기에 브로드캐스트할 수 있는 사용자를 제어할 수 있습니다. 다른 방법으로는 Context.sendBroadcast()를 호출할 때 권한을 제공하여 브로드캐스트를 수신할 수 있는 broadcast receiver를 제한할 수 있습니다.

수신기와 브로드캐스터 모두에 권한이 필요할 수 있습니다. 이 경우 두 권한 검사를 모두 통과해야만 인텐트를 연결된 타겟에 제공할 수 있습니다. 자세한 내용은 권한으로 브로드캐스트 제한을 참조하세요.

기타 권한 확인

권한을 확인하는 데 유용한 여러 가지 다른 방법이 있습니다.

  • 서비스 호출 중에 권한 문자열을 Context.checkCallingPermission()에 전달합니다. 이 메서드는 권한이 현재 호출 프로세스에 부여되었는지를 나타내는 정수를 반환합니다. 이 방법은 일반적으로 서비스에서 게시된 IDL 인터페이스를 통해서나 다른 프로세스에 지정된 다른 방법을 통해 다른 프로세스에서 들어오는 호출을 실행하는 경우에만 사용할 수 있습니다.
  • 다른 프로세스에 특정 권한이 부여되었는지 확인하려면 프로세스(PID)를 Context.checkPermission()에 전달합니다.
  • 다른 패키지에 특정 권한이 부여되었는지 확인하려면 패키지 이름을 PackageManager.checkPermission()에 전달합니다.