Ограничить взаимодействие с другими приложениями

Разрешения предназначены не только для запроса функций системы. Вы также можете ограничить взаимодействие других приложений с компонентами вашего приложения.

В этом руководстве объясняется, как проверить набор разрешений, объявленных другим приложением. В руководстве также объясняется, как вы можете настроить действия, службы, поставщиков контента и приемники вещания, чтобы ограничить взаимодействие других приложений с вашим приложением.

Проверьте разрешения другого приложения

Чтобы просмотреть набор разрешений, объявленных другим приложением, с помощью устройства или эмулятора выполните следующие действия:

  1. Откройте экран информации о приложении.
  2. Выберите Разрешения . Загрузится экран разрешений приложения .

    На этом экране показан набор групп разрешений. Система организует набор разрешений, объявленных приложением, в эти группы.

Есть ряд других полезных способов проверить разрешения:

  • Во время вызова службы передайте строку разрешения в Context.checkCallingPermission() . Этот метод возвращает целое число, указывающее, предоставлено ли это разрешение текущему вызывающему процессу. Обратите внимание, что это можно использовать только тогда, когда вы выполняете вызов, поступающий из другого процесса, обычно через интерфейс IDL, опубликованный из службы или каким-либо другим способом переданный другому процессу.
  • Чтобы проверить, предоставлено ли другому процессу определенное разрешение, передайте процесс (PID) в Context.checkPermission() .
  • Чтобы проверить, предоставлено ли другому пакету определенное разрешение, передайте имя пакета в PackageManager.checkPermission() .

Ограничьте взаимодействие с действиями вашего приложения.

Используйте атрибут 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() .

Ограничьте взаимодействие с приемниками вещания вашего приложения.

Используйте атрибут android:permission тега <receiver> , чтобы ограничить, какие другие приложения могут отправлять широковещательные сообщения на связанный BroadcastReceiver . Разрешение проверяется после возврата Context.sendBroadcast() , когда система пытается доставить отправленную трансляцию данному получателю. Это означает, что ошибка разрешения не приводит к возврату исключения вызывающему объекту — оно просто не доставляет Intent .

Таким же образом вы можете предоставить разрешение Context.registerReceiver() для управления тем, какие другие приложения могут осуществлять трансляцию на программно зарегистрированный получатель. И наоборот, вы можете предоставить разрешение при вызове Context.sendBroadcast() чтобы ограничить, какие получатели широковещательной рассылки могут получать широковещательную рассылку.

Обратите внимание, что разрешение может потребоваться как получателю, так и вещательной компании. В этом случае обе проверки разрешений должны пройти, чтобы намерение было доставлено в связанную цель. Дополнительные сведения см. в разделе Ограничение широковещательных рассылок с помощью разрешений .