Realizowanie typowych przypadków użycia przy ograniczonej widoczności przesyłek.

W tym dokumencie przedstawiamy kilka typowych przypadków użycia, w których aplikacja wchodzi w interakcję z innymi aplikacjami. W każdej sekcji znajdziesz wskazówki, jak osiągnąć funkcjonalność aplikacji przy ograniczonej widoczności pakietów. Musisz to wziąć pod uwagę, jeśli Twoja aplikacja jest kierowana na Androida 11 (API na poziomie 30) lub nowszego.

Gdy aplikacja, której docelowy poziom to Android 11 lub nowszy, używa intencji do uruchomienia aktywności w innej aplikacji, najprostszym rozwiązaniem jest wywołanie intencji i obsługa wyjątku ActivityNotFoundException, jeśli żadna aplikacja nie jest dostępna.

Jeśli część aplikacji zależy od tego, czy wywołanie funkcji startActivity() może się powieść (np. wyświetlanie interfejsu), dodaj element do elementu <queries> w manifeście aplikacji. Zazwyczaj jest to element <intent>.

Otwieranie adresów URL

W tej sekcji opisujemy różne sposoby otwierania adresów URL w aplikacji, która jest przeznaczona na Androida 11 lub nowszego.

Otwieranie adresów URL w przeglądarce lub innej aplikacji

Aby otworzyć adres URL, użyj intencji zawierającej działanie intencji ACTION_VIEW, zgodnie z opisem w przewodniku po wczytywaniu adresu URL. Po wywołaniu startActivity() za pomocą tego zamiaru nastąpi jedna z tych sytuacji:

  • Adres URL otworzy się w aplikacji przeglądarki.
  • Adres URL otworzy się w aplikacji, która obsługuje go jako precyzyjny link.
  • Wyświetli się okno, które pozwoli użytkownikowi wybrać aplikację, która otworzy adres URL.
  • Występuje ActivityNotFoundException, ponieważ na urządzeniu nie ma aplikacji, która może otworzyć adres URL. (To nietypowe).

    Zalecamy, aby aplikacja przechwytywała i obsługiwała błąd ActivityNotFoundException, jeśli wystąpi.

Metoda startActivity() nie wymaga widoczności pakietu, aby uruchomić aktywność innej aplikacji, więc nie musisz dodawać elementu <queries> do manifestu aplikacji ani wprowadzać żadnych zmian w istniejącym elemencie <queries>. Dotyczy to zarówno niejawnych, jak i jawnych intencji, które otwierają adres URL.

Sprawdzanie, czy przeglądarka jest dostępna

W niektórych przypadkach aplikacja może przed próbą otwarcia adresu URL sprawdzić, czy na urządzeniu jest dostępna co najmniej jedna przeglądarka lub czy określona przeglądarka jest domyślna. W takich przypadkach dodaj ten element <intent> do elementu <queries> w pliku manifestu:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data android:scheme="https" />
</intent>

Gdy wywołasz funkcję queryIntentActivities() i przekażesz intencję internetową jako argument, zwrócona lista będzie w niektórych przypadkach zawierać dostępne aplikacje przeglądarki. Lista nie zawiera aplikacji przeglądarki, jeśli użytkownik skonfigurował adres URL tak, aby domyślnie otwierał się w aplikacji innej niż przeglądarka.

Otwieranie adresów URL na kartach niestandardowych

Karty niestandardowe umożliwiają aplikacji dostosowanie wyglądu i sposobu działania przeglądarki. Możesz otworzyć adres URL na karcie niestandardowej bez konieczności dodawania ani zmieniania elementu <queries> w pliku manifestu aplikacji.

Możesz jednak sprawdzić, czy urządzenie ma przeglądarkę obsługującą karty niestandardowe lub wybrać konkretną przeglądarkę, która ma być uruchamiana z kartami niestandardowymi, za pomocą CustomTabsClient.getPackageName(). W takich przypadkach dodaj ten element <intent> do elementu <queries> w pliku manifestu:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>

Zezwalanie aplikacjom innym niż przeglądarki na obsługę adresów URL

Nawet jeśli Twoja aplikacja może otwierać adresy URL za pomocą kart niestandardowych, zalecamy, aby w miarę możliwości otwierać adresy URL w aplikacji innej niż przeglądarka. Aby udostępnić tę funkcję w aplikacji, spróbuj wykonać połączenie z startActivity() za pomocą intencji, która ustawia flagę intencji FLAG_ACTIVITY_REQUIRE_NON_BROWSER. Jeśli system zgłosi ActivityNotFoundException, aplikacja może otworzyć adres URL w niestandardowej karcie.

Jeśli intencja zawiera ten flagę, wywołanie funkcji startActivity() powoduje zgłoszenie wyjątku ActivityNotFoundException, gdy wystąpi jeden z tych warunków:

  • Połączenie uruchomiłoby bezpośrednio aplikację przeglądarki.
  • W tym przypadku użytkownik zobaczyłby okno z wyborem, w którym jedynymi opcjami byłyby aplikacje przeglądarki.

Poniższy fragment kodu pokazuje, jak zaktualizować logikę, aby używać flagi intencji FLAG_ACTIVITY_REQUIRE_NON_BROWSER:

Kotlin

try {
    val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
        // The URL should either launch directly in a non-browser app (if it's
        // the default) or in the disambiguation dialog.
        addCategory(CATEGORY_BROWSABLE)
        flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER
    }
    startActivity(intent)
} catch (e: ActivityNotFoundException) {
    // Only browser apps are available, or a browser is the default.
    // So you can open the URL directly in your app, for example in a
    // Custom Tab.
    openInCustomTabs(url)
}

Java

try {
    Intent intent = new Intent(ACTION_VIEW, Uri.parse(url));
    // The URL should either launch directly in a non-browser app (if it's the
    // default) or in the disambiguation dialog.
    intent.addCategory(CATEGORY_BROWSABLE);
    intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER);
    startActivity(intent);
} catch (ActivityNotFoundException e) {
    // Only browser apps are available, or a browser is the default.
    // So you can open the URL directly in your app, for example in a
    // Custom Tab.
    openInCustomTabs(url);
}

Unikanie okna z prośbą o wybór

Jeśli chcesz uniknąć wyświetlania okna dialogowego, które może pojawić się, gdy użytkownicy otwierają adres URL, i zamiast tego wolisz samodzielnie obsługiwać adres URL w takich sytuacjach, możesz użyć intencji, która ustawia flagę intencji FLAG_ACTIVITY_REQUIRE_DEFAULT.

Jeśli intencja zawiera ten flagę, wywołanie funkcji startActivity() powoduje zgłoszenie wyjątku ActivityNotFoundException, gdy wywołanie spowodowałoby wyświetlenie użytkownikowi okna z prośbą o wybranie jednej z możliwości.

Jeśli intencja zawiera zarówno tę flagę, jak i flagę intencji FLAG_ACTIVITY_REQUIRE_NON_BROWSER, wywołanie startActivity() powoduje zgłoszenie wyjątku ActivityNotFoundException, gdy wystąpi jeden z tych warunków:

  • Połączenie uruchomiłoby aplikację przeglądarki bezpośrednio.
  • Wywołanie wyświetliłoby użytkownikowi okno z prośbą o wybranie odpowiedniej opcji.

Poniższy fragment kodu pokazuje, jak używać razem flag FLAG_ACTIVITY_REQUIRE_NON_BROWSERFLAG_ACTIVITY_REQUIRE_DEFAULT:

Kotlin

val url = URL_TO_LOAD
try {
    // For this intent to be invoked, the system must directly launch a
    // non-browser app.
    val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
        addCategory(CATEGORY_BROWSABLE)
        flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER or
                FLAG_ACTIVITY_REQUIRE_DEFAULT
    }
    startActivity(intent)
} catch (e: ActivityNotFoundException) {
    // This code executes in one of the following cases:
    // 1. Only browser apps can handle the intent.
    // 2. The user has set a browser app as the default app.
    // 3. The user hasn't set any app as the default for handling this URL.
    openInCustomTabs(url)
}

Java

String url = URL_TO_LOAD;
try {
    // For this intent to be invoked, the system must directly launch a
    // non-browser app.
    Intent intent = new Intent(ACTION_VIEW, Uri.parse(url));
    intent.addCategory(CATEGORY_BROWSABLE);
    intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER |
            FLAG_ACTIVITY_REQUIRE_DEFAULT);
    startActivity(intent);
} catch (ActivityNotFoundException e) {
    // This code executes in one of the following cases:
    // 1. Only browser apps can handle the intent.
    // 2. The user has set a browser app as the default app.
    // 3. The user hasn't set any app as the default for handling this URL.
    openInCustomTabs(url);
}

Otwórz plik

Jeśli aplikacja obsługuje pliki lub załączniki, np. sprawdza, czy urządzenie może otworzyć dany plik, najłatwiej jest zwykle spróbować uruchomić aktywność, która może obsłużyć ten plik. Aby to zrobić, użyj intencji, która zawiera działanie ACTION_VIEW i identyfikator URI reprezentujący konkretny plik. Jeśli na urządzeniu nie ma aplikacji, Twoja aplikacja może przechwycić ActivityNotFoundException. W logice obsługi wyjątków możesz wyświetlić błąd lub spróbować samodzielnie obsłużyć plik.

Jeśli Twoja aplikacja musi z wyprzedzeniem wiedzieć, czy inna aplikacja może otworzyć dany plik, w tym fragmencie kodu umieść element <intent> jako część elementu <queries> w manifeście. Jeśli w momencie kompilacji znasz już typ pliku, podaj go.

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.VIEW" />
  <!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
  <data android:mimeType="application/pdf" />
</intent>

Następnie możesz sprawdzić, czy aplikacja jest dostępna, wywołując funkcję resolveActivity() z odpowiednim zamiarem.

Przyznawanie dostępu do identyfikatora URI

Uwaga: deklarowanie uprawnień dostępu do URI w sposób opisany w tej sekcji jest wymagane w przypadku aplikacji kierowanych na Androida 11 (poziom interfejsu API 30) lub nowszego i zalecane w przypadku wszystkich aplikacji, niezależnie od docelowej wersji pakietu SDK i tego, czy eksportują dostawców treści.

Aby aplikacje kierowane na Androida 11 lub nowszego miały dostęp do identyfikatora URI treści, intencja aplikacji musi deklarować uprawnienia dostępu do identyfikatora URI przez ustawienie co najmniej jednej z tych flag intencji: FLAG_GRANT_READ_URI_PERMISSIONFLAG_GRANT_WRITE_URI_PERMISSION.

Na Androidzie 11 i nowszych uprawnienia dostępu do URI zapewniają aplikacji, która odbiera intencję, te możliwości:

  • Odczytywanie lub zapisywanie danych reprezentowanych przez identyfikator URI treści w zależności od przyznanych uprawnień do identyfikatora URI.
  • Uzyskaj wgląd w aplikację zawierającą dostawcę treści, który pasuje do organu URI. Aplikacja zawierająca dostawcę treści może być inna niż aplikacja wysyłająca intencję.

Ten fragment kodu pokazuje, jak dodać flagę intencji uprawnień dotyczących identyfikatora URI, aby inna aplikacja, która jest przeznaczona na Androida 11 lub nowszego, mogła wyświetlać dane w identyfikatorze URI treści:

Kotlin

val shareIntent = Intent(Intent.ACTION_VIEW).apply {
    flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
    data = CONTENT_URI_TO_SHARE_WITH_OTHER_APP
}

Java

Intent shareIntent = new Intent(Intent.ACTION_VIEW);
shareIntent.setFlags(FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setData(CONTENT_URI_TO_SHARE_WITH_OTHER_APP);

Łączenie z usługami

Jeśli Twoja aplikacja musi wchodzić w interakcję z usługą, która nie jest automatycznie widoczna, możesz zadeklarować odpowiednie działanie intencji w elemencie <queries>. W kolejnych sekcjach znajdziesz przykłady korzystania z najczęściej używanych usług.

Nawiązywanie połączenia z mechanizmem zamiany tekstu na mowę

Jeśli Twoja aplikacja wchodzi w interakcję z mechanizmem zamiany tekstu na mowę, w ramach elementu <queries> w pliku manifestu umieść ten element:<intent>

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.TTS_SERVICE" />
</intent>

Łączenie z usługą rozpoznawania mowy

Jeśli Twoja aplikacja korzysta z usługi rozpoznawania mowy, dodaj ten element <intent> do elementu <queries> w pliku manifestu:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.speech.RecognitionService" />
</intent>

Łączenie z usługami przeglądarki multimediów

Jeśli Twoja aplikacja jest przeglądarką multimediów klienta, w pliku manifestu w ramach elementu <queries> umieść ten element <intent>:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.media.browse.MediaBrowserService" />
</intent>

Zapewnianie niestandardowych funkcji

Jeśli Twoja aplikacja musi wykonywać działania, które można dostosowywać, lub wyświetlać informacje, które można dostosowywać, na podstawie interakcji z innymi aplikacjami, możesz przedstawić to niestandardowe zachowanie za pomocą sygnatur filtrów intencji jako części elementu <queries> w pliku manifestu. W kolejnych sekcjach znajdziesz szczegółowe wskazówki dotyczące kilku typowych scenariuszy.

Zapytanie o aplikacje do SMS-ów

Jeśli aplikacja potrzebuje informacji o zestawie aplikacji do obsługi SMS-ów zainstalowanych na urządzeniu, np. aby sprawdzić, która aplikacja jest domyślnym programem do obsługi SMS-ów na urządzeniu, w ramach elementu <queries> w pliku manifestu umieść ten element <intent>:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.SENDTO"/>
  <data android:scheme="smsto" android:host="*" />
</intent>

Tworzenie niestandardowego arkusza udostępniania

Jeśli to możliwe, używaj arkusza udostępniania dostarczonego przez system. Możesz też dodać ten element <intent> do elementu <queries> w pliku manifestu:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.SEND" />
  <!-- Replace with the MIME type that your app works with, if needed. -->
  <data android:mimeType="image/jpeg" />
</intent>

Proces tworzenia arkusza udostępniania w logice aplikacji, np. wywołanie queryIntentActivities(), pozostaje niezmieniony w porównaniu z wersjami Androida starszymi niż Android 11.

Wyświetlanie niestandardowych działań związanych z zaznaczaniem tekstu

Gdy użytkownicy wybiorą tekst w aplikacji, na pasku narzędzi wyboru tekstu wyświetli się zestaw możliwych operacji, które można wykonać na wybranym tekście. Jeśli ten pasek narzędzi wyświetla działania niestandardowe z innych aplikacji, w ramach elementu <queries> w pliku manifestu umieść ten element:<intent>

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.PROCESS_TEXT" />
  <data android:mimeType="text/plain" />
</intent>

Wyświetlanie wierszy danych niestandardowych dotyczących kontaktu

Aplikacje mogą dodawać niestandardowe wiersze danych do dostawcy kontaktów. Aby aplikacja do obsługi kontaktów mogła wyświetlać te dane niestandardowe, musi mieć możliwość wykonania tych czynności:

  1. Odczytaj plik contacts.xml z innych aplikacji.
  2. Wczytaj ikonę odpowiadającą niestandardowemu typowi MIME.

Jeśli Twoja aplikacja jest aplikacją do obsługi kontaktów, w ramach elementu <queries> w pliku manifestu umieść te elementy <intent>:

<!-- Place inside the <queries> element. -->
<!-- Lets the app read the contacts.xml file from other apps. -->
<intent>
  <action android:name="android.accounts.AccountAuthenticator" />
</intent>
<!-- Lets the app load an icon corresponding to the custom MIME type. -->
<intent>
  <action android:name="android.intent.action.VIEW" />
  <data android:scheme="content" android:host="com.android.contacts"
        android:mimeType="vnd.android.cursor.item/*" />
</intent>