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. Każda sekcja zawiera wskazówki, jak uzyskać dostęp do funkcji aplikacji przy ograniczonej widoczności pakietu. Należy je wziąć pod uwagę, jeśli aplikacja jest kierowana na Androida 11 (poziom API 30) lub nowszego.

Jeśli aplikacja przeznaczona na Androida 11 lub nowszego używa intencji do uruchamiania 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ęść Twojej aplikacji zależy od tego, czy wywołanie startActivity() może się powieść (np. wyświetlenie interfejsu), dodaj element do elementu <queries> w pliku manifestu aplikacji. Zwykle jest to element <intent>.

Otwieranie adresów URL

W tej sekcji opisujemy różne sposoby otwierania adresów URL w aplikacji kierowanej na Androida 11 lub nowszego.

Otwieraj adresy URL w przeglądarce lub innej aplikacji

Aby otworzyć adres URL, użyj intencji zawierającej działanie intencji ACTION_VIEW, jak opisano w przewodniku dotyczącym ładowania adresu URL. Gdy wywołasz startActivity() za pomocą tego zamiaru, dzieje się jedno z tych działań:

  • Adres URL otworzy się w aplikacji przeglądarki.
  • Adres URL otwiera się w aplikacji, która obsługuje go jako precyzyjny link.
  • Wyświetli się okno z prośbą o rozstrzygnięcie, w której użytkownik może wybrać aplikację, która otworzy adres URL.
  • Błąd ActivityNotFoundException występuje, ponieważ na urządzeniu nie ma zainstalowanej aplikacji, która mogłaby otworzyć adres URL. (To nietypowa sytuacja).

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

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

Sprawdzanie, czy przeglądarka jest dostępna

W niektórych przypadkach aplikacja może chcieć sprawdzić, czy na urządzeniu jest dostępna co najmniej 1 przeglądarka lub czy konkretna przeglądarka jest przeglądarką domyślną, zanim spróbuje otworzyć adres URL. W takich przypadkach w elemencie <queries> w pliku manifestu umieść ten element <intent>:

<!-- 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 przekazujesz jako argument intencję internetową, zwracana lista zawiera w niektórych przypadkach dostępne aplikacje przeglądarki. Lista nie zawiera aplikacji przeglądarki, jeśli użytkownik skonfigurował adres URL tak, aby otwierał się domyślnie w innej aplikacji.

Otwieranie adresów URL na kartach niestandardowych

Karty niestandardowe pozwalają aplikacji dostosować wygląd i działanie przeglądarki. Możesz otwierać adres URL na karcie niestandardowej bez konieczności dodawania lub zmieniania elementu <queries> w pliku manifestu aplikacji.

Warto jednak sprawdzić, czy na urządzeniu jest przeglądarka obsługująca karty niestandardowe, lub wybrać konkretną przeglądarkę do uruchamiania kart niestandardowych za pomocą CustomTabsClient.getPackageName(). W takich przypadkach dodaj element <intent> w ramach 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ła je aplikacja inna niż przeglądarka. Aby udostępnić tę funkcję w aplikacji, spróbuj wywołać startActivity() za pomocą intencji, która ustawia flagę intencji FLAG_ACTIVITY_REQUIRE_NON_BROWSER. Jeśli system zwróci wartość ActivityNotFoundException, aplikacja może otworzyć adres URL w karcie niestandardowej.

Jeśli intencja zawiera ten flag, wywołanie funkcji startActivity() powoduje wywołanie funkcji ActivityNotFoundException, gdy spełniony jest jeden z tych warunków:

  • Połączenie uruchamiałoby bezpośrednio aplikację przeglądarki.
  • W ramach tego wywołania użytkownik zobaczyłby okno rozróżniania, w którym jedynymi opcjami byłyby aplikacje przeglądarki.

Ten 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 rozstrzygnięcie wątpliwości

Jeśli chcesz uniknąć wyświetlania użytkownikom okna wyboru, które może się pojawić po otwarciu adresu URL, i zamiast tego chcesz 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 parametr, wywołanie funkcji startActivity() powoduje wywołanie funkcji ActivityNotFoundException, gdy wywołanie miało wyświetlić użytkownikowi okno rozróżniania.

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

  • Po wywołaniu aplikacja przeglądarki zostałaby uruchomiona bezpośrednio.
  • W ramach tego wywołania użytkownikowi wyświetliłoby się okno z prośbą o rozstrzygnięcie wątpliwości.

Ten fragment kodu pokazuje, jak używać flag FLAG_ACTIVITY_REQUIRE_NON_BROWSER i FLAG_ACTIVITY_REQUIRE_DEFAULT razem:

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 Twoja aplikacja obsługuje pliki lub załączniki, na przykład sprawdza, czy urządzenie może otworzyć dany plik, najłatwiej jest uruchomić działanie, które może obsłużyć plik. Aby to zrobić, użyj intencji zawierającej działanie intencji ACTION_VIEW i identyfikator URI reprezentujący konkretny plik. Jeśli na urządzeniu nie ma żadnej 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 wiedzieć z wyprzedzeniem, czy inna aplikacja może otworzyć dany plik, uwzględnij element <intent> w tym fragmencie kodu jako część elementu <queries> w pliku manifestu. Podaj typ pliku, jeśli znasz go już w momencie kompilacji.

<!-- 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łając resolveActivity() z intencją.

Przyznawanie dostępu do identyfikatora URI

Uwaga: zadeklarowanie uprawnień dostępu do identyfikatora URI zgodnie z tą sekcją jest wymagane w przypadku aplikacji kierowanych na Androida 11 (poziom interfejsu API 30) lub nowszego i zalecanych w przypadku wszystkich aplikacji, niezależnie od docelowej wersji pakietu SDK i tego, czy eksportują swoich dostawców treści.

W przypadku aplikacji kierowanych na Androida 11 lub nowszego w celu dostępu do identyfikatora URI treści intencja aplikacji musi zadeklarować uprawnienia dostępu z identyfikatorem URI przez ustawienie co najmniej 1 z tych flag intencji: FLAG_GRANT_READ_URI_PERMISSION i FLAG_GRANT_WRITE_URI_PERMISSION.

W Androidzie 11 i nowszych uprawnienia dostępu do adresu URI zapewniają aplikacji, która odbiera intencję, następujące możliwości:

  • W zależności od określonych uprawnień identyfikatora URI może odczytywać lub zapisywać dane reprezentowane przez identyfikator URI treści.
  • Widoczność aplikacji zawierającej dostawcę treści, który pasuje do autorytetu URI. Aplikacja zawierająca dostawcę treści może się różnić od aplikacji wysyłającej intencję.

Ten fragment kodu pokazuje, jak dodać flagę intencji uprawnień identyfikatora URI, aby inna aplikacja kierowana 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);

Połącz z usługami

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

Łączenie z mechanizmem zamiany tekstu na mowę

Jeśli Twoja aplikacja współpracuje z silnikiem zamiany tekstu na mowę, dodaj element <intent> w ramach elementu <queries> w pliku manifestu:

<!-- 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 współpracuje z usługą rozpoznawania mowy, w elemencie <queries> w pliku manifestu umieść ten element <intent>:

<!-- 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 to aplikacja przeglądarki multimediów klienta, w pliku manifestu dodaj element <intent> w ramach elementu <queries>:

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

Udostępnianie funkcji niestandardowych

Jeśli aplikacja musi wykonywać dostosowywalne działania lub wyświetlać dostosowywalne informacje na podstawie interakcji z innymi aplikacjami, możesz przedstawić to niestandardowe działanie za pomocą sygnatur filtru intencji w ramach elementu <queries> w pliku manifestu. W następnych sekcjach znajdziesz szczegółowe wskazówki dotyczące kilku typowych sytuacji.

Zapytanie o aplikacje do obsługi SMS-ów

Jeśli Twoja aplikacja potrzebuje informacji o zbiorze aplikacji do obsługi SMS-ów zainstalowanych na urządzeniu, na przykład aby sprawdzić, która aplikacja jest domyślnym modułem obsługi SMS-ów na urządzeniu, dodaj element <intent> w ramach elementu <queries> w pliku manifestu:

<!-- 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

W miarę możliwości używaj arkusza udostępniania udostępnianego przez system. Możesz też uwzględnić ten element <intent> w elemencie <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 karty udostępniania w logice aplikacji, np. wywołanie funkcji queryIntentActivities(), pozostaje niezmieniony w porównaniu z wersjami Androida starszymi niż 11.

Wyświetlanie działań niestandardowych dotyczących selekcji tekstu

Gdy użytkownicy zaznaczą tekst w aplikacji, pasek narzędzi do zaznaczania tekstu wyświetli zestaw możliwych operacji, które można wykonać na zaznaczonym tekście. Jeśli tą toolbar wyświetla działania niestandardowe z innych aplikacji, w pliku manifestu dodaj element <intent> w ramach elementu <queries>:

<!-- 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 usługi Kontakty. Aby aplikacja do obsługi kontaktów wyświetlała te dane niestandardowe, musi mieć możliwość:

  1. Przeczytaj plik contacts.xml z innych aplikacji.
  2. Załaduj ikonę odpowiadającą niestandardowemu typowi MIME.

Jeśli Twoja aplikacja to aplikacja do obsługi kontaktów, w pliku manifestu umieść te elementy <intent> w elemencie <queries>:

<!-- 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>