Ograniczanie interakcji z innymi aplikacjami

Uprawnienia nie służą tylko do proszenia o dostęp do funkcji systemowych. Możesz też ograniczyć sposób, w jaki inne aplikacje mogą wchodzić w interakcje z komponentami Twojej aplikacji.

Z tego przewodnika dowiesz się, jak sprawdzić zestaw uprawnień zadeklarowanych przez inną aplikację. W przewodniku znajdziesz też informacje o tym, jak skonfigurować działania, usługi, dostawców treści i odbiorniki transmisji, aby ograniczyć sposób, w jaki inne aplikacje mogą wchodzić w interakcje z Twoją aplikacją.

Sprawdzanie uprawnień innej aplikacji

Aby wyświetlić zestaw uprawnień zadeklarowanych przez inną aplikację, wykonaj te czynności na urządzeniu lub emulatorze:

  1. Otwórz ekran Informacje o aplikacji.
  2. Wybierz Uprawnienia. Wyświetli się ekran Uprawnienia aplikacji.

    Na tym ekranie zobaczysz zestaw grup uprawnień. System porządkuje zbiór uprawnień zadeklarowanych przez aplikację w tych grupach.

Uprawnienia możesz sprawdzić na kilka innych przydatnych sposobów:

  • Aby sprawdzić uprawnienia podczas połączenia z usługą, przekaż ciąg uprawnień do funkcji Context.checkCallingPermission(). Ta metoda zwraca liczbę całkowitą, która wskazuje, czy uprawnienie zostało przyznane bieżącemu procesowi wywołującemu. Pamiętaj, że tej funkcji można używać tylko wtedy, gdy wykonujesz wywołanie pochodzące z innego procesu, zwykle za pomocą interfejsu IDL opublikowanego z usługi lub w inny sposób przekazanego do innego procesu.
  • Aby sprawdzić, czy inny proces ma przyznane określone uprawnienie, przekaż identyfikator procesu (PID) do funkcji Context.checkPermission().
  • Aby sprawdzić, czy inny pakiet ma określone uprawnienie, przekaż nazwę pakietu do funkcji PackageManager.checkPermission().

Ograniczanie interakcji z aktywnościami aplikacji

W pliku manifestu użyj atrybutu android:permission tagu <activity>, aby ograniczyć, które inne aplikacje mogą uruchamiać ten Activity. Uprawnienie jest sprawdzane podczas Context.startActivity()Activity.startActivityForResult(). Jeśli dzwoniący nie ma wymaganych uprawnień, wystąpi SecurityException.

Ograniczanie interakcji z usługami aplikacji

W pliku manifestu użyj atrybutu android:permission tagu <service>, aby ograniczyć, które inne aplikacje mogą uruchamiać powiązany element Service lub się z nim łączyć. Uprawnienie jest sprawdzane podczas Context.startService(), Context.stopService()Context.bindService(). Jeśli dzwoniący nie ma wymaganych uprawnień, wystąpi błąd SecurityException.

Ograniczanie interakcji z dostawcami treści w aplikacji

W pliku manifestu użyj atrybutu android:permission tagu <provider>, aby ograniczyć dostęp do danych w ContentProvider dla innych aplikacji. (Dostawcy treści mają do dyspozycji ważne dodatkowe zabezpieczenie o nazwie uprawnienia URI, które opisujemy w następnej sekcji). W przypadku dostawców treści możesz ustawić 2 osobne atrybuty uprawnień, które w odróżnieniu od innych komponentów ograniczają dostęp do odczytu i zapisu danych: android:readPermission ogranicza dostęp do odczytu danych z dostawcy, a android:writePermission ogranicza dostęp do zapisu danych w dostawcy. Pamiętaj, że jeśli dostawca jest chroniony zarówno uprawnieniami do odczytu, jak i do zapisu, samo posiadanie uprawnień do zapisu nie pozwala aplikacji na odczytywanie danych od dostawcy.

Uprawnienia są sprawdzane podczas pierwszego pobierania dostawcy i gdy aplikacja wykonuje na nim operacje. Jeśli aplikacja wysyłająca żądanie nie ma żadnego z tych uprawnień, wystąpi błąd SecurityException. Korzystanie z narzędzia ContentResolver.query() wymaga uprawnień do odczytu, a korzystanie z narzędzi ContentResolver.insert(), ContentResolver.update()ContentResolver.delete() wymaga uprawnień do zapisu. We wszystkich tych przypadkach brak wymaganych uprawnień powoduje wyświetlenie ikony SecurityException.

Przyznawanie dostępu do poszczególnych identyfikatorów URI

System zapewnia dodatkową, precyzyjną kontrolę nad tym, jak inne aplikacje mogą uzyskiwać dostęp do dostawców treści w Twojej aplikacji. W szczególności dostawca treści może chronić się za pomocą uprawnień do odczytu i zapisu, a jednocześnie zezwalać bezpośrednim klientom na udostępnianie określonych identyfikatorów URI innym aplikacjom. Aby zadeklarować, że Twoja aplikacja obsługuje ten model, użyj atrybutu android:grantUriPermissions lub elementu <grant-uri-permission>.

Możesz też przyznawać uprawnienia dla poszczególnych identyfikatorów URI. Podczas rozpoczynania aktywności lub zwracania wyniku do aktywności ustaw flagę intencji Intent.FLAG_GRANT_READ_URI_PERMISSION, flagę intencji Intent.FLAG_GRANT_WRITE_URI_PERMISSION lub obie flagi. Dzięki temu inne aplikacje uzyskują odpowiednio uprawnienia do odczytu, zapisu lub odczytu i zapisu w przypadku identyfikatora URI danych, który jest zawarty w intencji. Inne aplikacje uzyskują te uprawnienia w przypadku konkretnego identyfikatora URI niezależnie od tego, czy mają uprawnienia dostępu do danych w dostawcy treści w szerszym zakresie.

Załóżmy na przykład, że użytkownik korzysta z Twojej aplikacji, aby wyświetlić e-mail z załącznikiem w postaci obrazu. Inne aplikacje nie powinny mieć dostępu do treści e-maili, ale mogą być zainteresowane wyświetleniem obrazu. Aplikacja może używać intencji i flagi intencji Intent.FLAG_GRANT_READ_URI_PERMISSION, aby aplikacja do wyświetlania obrazów mogła zobaczyć obraz.

Kolejną kwestią jest widoczność aplikacji. Jeśli aplikacja jest kierowana na Androida 11 (poziom API 30) lub nowszego, system automatycznie udostępnia jej niektóre aplikacje, a inne domyślnie ukrywa. Jeśli Twoja aplikacja ma dostawcę treści i przyznała innej aplikacji uprawnienia identyfikatora URI, jest ona automatycznie widoczna dla tej aplikacji.

Więcej informacji znajdziesz w materiałach referencyjnych dotyczących metod grantUriPermission(), revokeUriPermission()checkUriPermission().

Ograniczanie interakcji z odbiornikami w aplikacji

Użyj atrybutu android:permission tagu <receiver>, aby ograniczyć, które inne aplikacje mogą wysyłać transmisje do powiązanego elementu BroadcastReceiver. System sprawdza uprawnienia po Context.sendBroadcast(), ponieważ próbuje dostarczyć przesłaną transmisję do danego odbiorcy. Oznacza to, że błąd uprawnień nie powoduje zgłoszenia wyjątku do wywołującego – po prostu nie dostarcza Intent.

Uprawnienia możesz też skonfigurować programowo:

  • Aby określić, które inne aplikacje mogą wysyłać transmisje do odbiornika zarejestrowanego programowo: podaj uprawnienie do Context.registerReceiver().
  • Aby ograniczyć liczbę odbiorników, które mogą odbierać transmisję: podczas wywoływania funkcji Context.sendBroadcast() podaj uprawnienia.

Pamiętaj, że zarówno odbiorca, jak i nadawca mogą wymagać uprawnień. W takim przypadku oba sprawdzenia uprawnień muszą zakończyć się powodzeniem, aby intencja została przekazana do powiązanego elementu docelowego. Więcej informacji znajdziesz w artykule Ograniczanie transmisji za pomocą uprawnień.