Ograniczanie interakcji z innymi aplikacjami

Uprawnienia nie służą tylko do żądania funkcji systemowych. Możesz też ograniczyć możliwość interakcji innych aplikacji z komponentami Twojej aplikacji.

Z tego przewodnika dowiesz się, jak sprawdzić zestaw uprawnień zadeklarowanych przez inną aplikację. Ten przewodnik wyjaśnia też, jak skonfigurować działania, usługi, dostawców treści i odbiorników, aby ograniczyć możliwość interakcji innych aplikacji z Twoją aplikacją.

Sprawdzanie uprawnień innej aplikacji

Aby wyświetlić zestaw uprawnień deklarowanych przez inną aplikację, wykonaj te czynności za pomocą urządzenia lub emulatora:

  1. Otwórz ekran Informacje o aplikacji.
  2. Kliknij Uprawnienia. Pojawi się ekran Uprawnienia aplikacji.

    Na tym ekranie widać zbiór grup uprawnień. System porządkuje zbiór uprawnień, które aplikacja zadeklarowała w tych grupach.

Jest kilka innych przydatnych sposobów sprawdzania uprawnień:

  • Podczas wywołania usługi przekaż ciąg uprawnień do Context.checkCallingPermission(). Ta metoda zwraca liczbę całkowitą wskazującą, czy to uprawnienie zostało przyznane bieżącemu procesowi wywołującemu. Pamiętaj, że tej opcji można używać tylko podczas wykonywania wywołania pochodzącego z innego procesu, zwykle przez interfejs IDL opublikowany z usługi lub w inny sposób przypisany do innego procesu.
  • Aby sprawdzić, czy innemu procesowi przyznano określone uprawnienie, przekaż ten proces (PID) do Context.checkPermission().
  • Aby sprawdzić, czy innemu pakietowi przyznano określone uprawnienie, przekaż jego nazwę do PackageManager.checkPermission().

Ograniczanie interakcji z aktywnością w aplikacji

Użyj atrybutu android:permission do tagu <activity> w pliku manifestu, aby określić, które inne aplikacje mogą uruchamiać ten komponent Activity. Uprawnienie jest sprawdzane w czasie Context.startActivity() i Activity.startActivityForResult(). Jeśli element wywołujący nie ma wymaganych uprawnień, występuje SecurityException.

Ograniczanie interakcji z usługami aplikacji

Użyj atrybutu android:permission do tagu <service> w pliku manifestu, aby określić, które inne aplikacje mogą uruchamiać się z powiązanym elementem Service lub z nim powiązać. Uprawnienie jest sprawdzane w czasie Context.startService(), Context.stopService() i Context.bindService(). Jeśli element wywołujący nie ma wymaganych uprawnień, występuje SecurityException.

Ograniczanie interakcji z dostawcami treści aplikacji

Aby określić, które inne aplikacje mogą mieć dostęp do danych w elemencie ContentProvider, użyj atrybutu android:permission w tagu <provider>. Dostawcy treści mają dostęp do ważnej dodatkowej usługi zabezpieczeń zwanej uprawnieniami identyfikatora URI. Zostało to opisane w następnej sekcji. W odróżnieniu od pozostałych komponentów istnieją 2 osobne atrybuty uprawnień, które możesz ustawić dla dostawców treści: android:readPermission określa, które aplikacje mogą odczytywać dane od dostawcy, a android:writePermission określa, które inne aplikacje mogą do niego zapisywać. Pamiętaj, że jeśli dostawca jest zabezpieczony uprawnieniami do odczytu i zapisu, posiadanie samego uprawnienia do zapisu nie pozwala aplikacji na odczyt od dostawcy.

Uprawnienia są sprawdzane przy pierwszym pobieraniu dostawcy i przy wykonywaniu operacji na tym dostawcy. Jeśli aplikacja żądająca nie ma tych uprawnień, występuje SecurityException. Użycie właściwości ContentResolver.query() wymaga uprawnień do odczytu; użycie ContentResolver.insert(), ContentResolver.update() lub ContentResolver.delete() wymaga uprawnień do zapisu. We wszystkich tych przypadkach brak wymaganych uprawnień skutkuje wyświetleniem stanu SecurityException.

Przyznawanie dostępu na podstawie identyfikatora URI

System zapewnia dodatkową, szczegółową kontrolę nad tym, jak inne aplikacje mogą uzyskiwać dostęp do dostawców treści. Dostawca treści może się chronić za pomocą uprawnień do odczytu i zapisu, a jednocześnie pozwalać swoim klientom bezpośrednim na udostępnianie określonych identyfikatorów URI innym aplikacjom. Aby zadeklarować, że 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. Gdy rozpoczynasz działanie lub zwracasz wynik, ustaw flagę intencji Intent.FLAG_GRANT_READ_URI_PERMISSION, flagę intencji Intent.FLAG_GRANT_WRITE_URI_PERMISSION lub obie te flagi. Daje to innym aplikacjom uprawnienia do odczytu, zapisu lub odczytu i zapisu w przypadku identyfikatora URI danych uwzględnionego w zamiarze. Inne aplikacje uzyskują te uprawnienia do określonego identyfikatora URI niezależnie od tego, czy mają bardziej ogólne uprawnienia dostępu do danych u dostawcy treści.

Załóżmy np., że użytkownik korzysta z Twojej aplikacji, aby wyświetlić e-maila z załączonym obrazem. Inne aplikacje nie powinny mieć dostępu do treści e-maili, ale być może będą zainteresowane obejrzeniem obrazu. Aplikacja może korzystać z intencji i flagi intencji Intent.FLAG_GRANT_READ_URI_PERMISSION, aby umożliwić aplikacji wyświetlającej obraz obraz.

Kolejną kwestią jest widoczność aplikacji. Jeśli Twoja aplikacja jest kierowana na Androida 11 (poziom interfejsu API 30) lub nowszego, system automatycznie ustawi dla niej niektóre aplikacje, a inne domyślnie ukryje. Jeśli Twoja aplikacja korzysta z usług dostawcy treści i przyznał(a) uprawnienia URI innej aplikacji, jest ona widoczna automatycznie dla tej aplikacji.

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

Ograniczanie interakcji z odbiornikami w aplikacji

Użyj atrybutu android:permission w tagu <receiver>, aby określić, które inne aplikacje mogą wysyłać komunikaty do powiązanego elementu BroadcastReceiver. Uprawnienia są sprawdzane po zwróceniu zasobu Context.sendBroadcast(), ponieważ system próbuje dostarczyć przesłaną transmisję do danego odbiornika. Oznacza to, że błąd uprawnień nie powoduje, że wyjątek jest zwracany do elementu wywołującego – po prostu nie dostarcza elementu Intent.

W ten sam sposób możesz zezwolić usłudze Context.registerReceiver() na kontrolowanie, które inne aplikacje mogą przesyłać wiadomości do automatycznie zarejestrowanego odbiornika. Inną opcją jest przyznanie uprawnienia podczas wywoływania funkcji Context.sendBroadcast(), aby określić, którzy odbiorniki mogą ją odbierać.

Zarówno odbiorca, jak i nadawca mogą wymagać zezwolenia. W takim przypadku obie operacje sprawdzania uprawnień muszą zakończyć się, aby intencja została dostarczona do powiązanego miejsca docelowego. Więcej informacji znajdziesz w artykule o ograniczaniu transmisji przy użyciu uprawnień.