Android umożliwia użytkownikom udostępnianie danych między aplikacjami na 2 sposoby:
- Arkusz udostępniania w Androidzie jest przeznaczony głównie do wysyłania treści poza aplikację lub bezpośrednio do innego użytkownika. Może to być na przykład udostępnienie adresu URL znajomemu.
- Narzędzie do rozpoznawania intencji na Androidzie najlepiej nadaje się do przekazywania danych do następnego etapu dobrze zdefiniowanego zadania. Na przykład otwieranie pliku PDF z aplikacji i umożliwianie użytkownikom wybrania preferowanej przeglądarki.
Dlaczego warto korzystać z arkusza udostępniania w Androidzie
Używaj arkusza udostępniania w Androidzie, aby zapewnić użytkownikom spójne działanie w różnych aplikacjach. Nie wyświetlaj własnej listy celów udostępniania aplikacji ani nie twórz własnych odmian arkusza udostępniania.
Arkusz udostępniania w Androidzie umożliwia użytkownikom udostępnianie informacji właściwej osobie i wyświetla odpowiednie sugestie aplikacji – wszystko to za pomocą jednego kliknięcia. Arkusz udostępniania może sugerować miejsca docelowe niedostępne dla rozwiązań niestandardowych i używa spójnego rankingu. Dzieje się tak, ponieważ arkusz udostępniania może uwzględniać informacje o aktywności w aplikacji i aktywności użytkownika, które są dostępne tylko dla systemu.
Arkusz udostępniania w Androidzie ma też wiele przydatnych funkcji dla deweloperów. Możesz na przykład:
- Dowiedz się, kiedy i gdzie użytkownicy udostępniają treści
- Dodawanie kierowania niestandardowego i celów aplikacji
- Podglądy treści w formacie tekstu sformatowanego, począwszy od Androida 10 (poziom interfejsu API 29)
- Wykluczanie elementów docelowych pasujących do określonych nazw komponentów
Korzystanie z arkusza udostępniania w Androidzie
W przypadku wszystkich typów udostępniania utwórz intencję i ustaw jej działanie na Intent.ACTION_SEND.
Aby wyświetlić arkusz udostępniania w Androidzie, wywołaj Intent.createChooser(), przekazując obiekt Intent.
Zwraca wersję intencji, która zawsze wyświetla arkusz udostępniania w Androidzie.
Wysyłanie treści tekstowych
Najprostszym i najczęstszym zastosowaniem arkusza udostępniania w Androidzie jest wysyłanie treści tekstowych z jednej aktywności do innej. Na przykład większość przeglądarek może udostępniać adres URL aktualnie wyświetlanej strony jako tekst innej aplikacji. Jest to przydatne do udostępniania artykułu lub witryny znajomym przez e-mail lub sieć społecznościową. W Jetpack Compose pobierz bieżący kontekst za pomocą LocalContext.current i wywołaj context.startActivity().
Oto przykład, jak to zrobić:
fun shareText(context: Context) { val sendIntent: Intent = Intent().apply { action = ACTION_SEND putExtra(Intent.EXTRA_TEXT, "This is my text to send.") type = "text/plain" } val shareIntent = Intent.createChooser(sendIntent, null) context.startActivity(shareIntent) }
Opcjonalnie możesz dodać dodatkowe informacje, takie jak adresaci e-maila (EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC) lub temat e-maila (EXTRA_SUBJECT).
Uwaga: niektóre aplikacje do poczty e-mail, takie jak Gmail, oczekują String[] w przypadku dodatków takich jak EXTRA_EMAIL i EXTRA_CC. Użyj putExtra(String, String[]), aby dodać je do intencji.
Wysyłanie treści binarnych
Udostępnij dane binarne za pomocą działania ACTION_SEND.
Ustaw odpowiedni typ MIME i umieść identyfikator URI danych w dodatkowym elemencie EXTRA_STREAM, jak pokazano w tym przykładzie.
Zwykle służy do udostępniania obrazu, ale można go używać do udostępniania dowolnego typu treści binarnych.
fun shareBinaryContent(context: Context) { val shareIntent: Intent = Intent().apply { action = ACTION_SEND // Example: content://com.google.android.apps.photos.contentprovider/... val imageUri: Uri = Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/1") putExtra(Intent.EXTRA_STREAM, imageUri) type = "image/jpeg" } context.startActivity(Intent.createChooser(shareIntent, null)) }
Aplikacja odbierająca musi mieć uprawnienia dostępu do danych, na które wskazuje Uri. Możesz to zrobić na 2 zalecane sposoby:
- Przechowuj dane we własnym
ContentProvider, upewniając się, że inne aplikacje mają odpowiednie uprawnienia dostępu do Twojego dostawcy. Preferowanym mechanizmem zapewniania dostępu jest używanie uprawnień na identyfikator URI, które są tymczasowe i przyznają dostęp tylko aplikacji odbierającej. Aby utworzyć taki obiektContentProvider, użyj klasy pomocniczejFileProvider. - Użyj systemu
MediaStore. AtrybutMediaStorejest przeznaczony głównie dla typów MIME plików wideo, audio i obrazów. Jednak od Androida 3.0 (poziom interfejsu API 11) może on też przechowywać typy inne niż multimedia. Więcej informacji:MediaStore.Files. Pliki można wstawiać doMediaStoreza pomocąscanFile(), po czym do podanego wywołania zwrotnegoonScanCompleted()przekazywany jestUriw stylucontent://, który można udostępniać. Pamiętaj, że po dodaniu do systemuMediaStoretreści są dostępne dla każdej aplikacji na urządzeniu.
Używanie odpowiedniego typu MIME
Podaj najbardziej szczegółowy typ MIME dostępny dla wysyłanych danych. Na przykład użyj text/plain, gdy udostępniasz zwykły tekst. Oto kilka typowych typów MIME używanych podczas wysyłania danych na Androidzie:
| Odbiorcy rejestrują się w usłudze | Nadawcy wysyłają |
|---|---|
text/* |
|
image/* |
|
video/* |
|
| Obsługiwane rozszerzenia plików | application/pdf |
Aby określić typ MIME dynamicznie w czasie działania, zamiast kodować go na stałe, użyj tych metod:
- W przypadku identyfikatorów URI
content://(takich jak te dostarczane przezFileProviderlubMediaStore) wywołajContentResolver.getType(). - W przypadku rozszerzeń plików wywołaj
MimeTypeMap.getSingleton().getMimeTypeFromExtension(). - Jeśli używasz platformy Storage Access Framework, możesz też wysyłać zapytania do
DocumentFile.getType().
Jeśli nie możesz określić konkretnego typu MIME, użyj application/octet-stream w przypadku ogólnych danych binarnych lub */* jako ostatniej opcji.
Więcej informacji o typach MIME znajdziesz w oficjalnym rejestrze typów MIME IANA.
Arkusz udostępniania w Androidzie może wyświetlać podgląd treści w zależności od podanego typu MIME. Niektóre funkcje w wersji testowej są dostępne tylko w przypadku określonych typów.
Udostępnianie wielu treści
Aby udostępnić wiele treści, użyj działania ACTION_SEND_MULTIPLE wraz z listą identyfikatorów URI wskazujących te treści. Typ MIME różni się w zależności od udostępnianych treści. Jeśli na przykład udostępniasz 3 obrazy JPEG, użyj typu "image/jpg". W przypadku różnych typów obrazów użyj "image/*", aby dopasować aktywność, która obsługuje dowolny typ obrazu. Można udostępniać różne typy, ale lepiej tego unikać, ponieważ odbiorca może nie wiedzieć, co ma zostać wysłane. Jeśli musisz wysłać kilka typów, użyj "*/*". To aplikacja odbierająca dane odpowiada za ich analizę i przetwarzanie. Oto przykład:
fun shareMultiple(context: Context) { val imageUris: ArrayList<Uri> = arrayListOf( Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/1"), Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/2") ) val shareIntent = Intent().apply { action = Intent.ACTION_SEND_MULTIPLE putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris) type = "image/*" } context.startActivity(Intent.createChooser(shareIntent, null)) }
Upewnij się, że podane obiekty Uri wskazują dane, do których aplikacja odbierająca ma dostęp.
Dodawanie szczegółowych treści do podglądów tekstu
Od Androida 10 (poziom API 29) arkusz udostępniania w Androidzie wyświetla podgląd udostępnianego tekstu. W niektórych przypadkach udostępniany tekst może być trudny do zrozumienia. Wyobraź sobie, że chcesz udostępnić skomplikowany adres URL, taki jak https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4. Bardziej rozbudowany podgląd może upewnić użytkowników, co jest udostępniane.
Jeśli wyświetlasz podgląd tekstu, możesz ustawić tytuł, miniaturę lub oba te elementy. Dodaj opis do Intent.EXTRA_TITLE przed wywołaniem Intent.createChooser() i dodaj odpowiednią miniaturę za pomocą ClipData.
Uwaga: identyfikator URI treści obrazu jest dostarczany z FileProvider, zwykle ze skonfigurowanego <cache-path>.
Więcej informacji znajdziesz w artykule Udostępnianie plików. Pamiętaj, aby przyznać arkuszowi udostępniania odpowiednie uprawnienia do odczytu obrazu, którego chcesz użyć jako miniatury. Więcej informacji znajdziesz tutaj: Intent.FLAG_GRANT_READ_URI_PERMISSION.
Oto przykład:
fun richContentToTextPreviewShares(context: Context) { val share = Intent.createChooser( Intent().apply { action = ACTION_SEND putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/") // (Optional) Here you're setting the title of the content putExtra(Intent.EXTRA_TITLE, "Introducing content previews") // (Optional) Here you're passing a content URI to an image to be displayed data = Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/A123456789") flags = Intent.FLAG_GRANT_READ_URI_PERMISSION }, null ) context.startActivity(share) }
Podgląd będzie wyglądać mniej więcej tak:
Dodawanie działań niestandardowych do arkusza udostępniania
Na Androidzie 14 (API na poziomie 34) i nowszych aplikacje mogą dodawać działania niestandardowe do arkusza udostępniania w Androidzie.
Działania niestandardowe są wyświetlane jako małe ikony działań u góry arkusza udostępniania w Androidzie, a aplikacje mogą określić dowolny obiekt Intent jako działanie wywoływane po kliknięciu ikony.
Aby dodać działania niestandardowe w arkuszu udostępniania w Androidzie, najpierw utwórz ChooserAction z ChooserAction.Builder.
Możesz określić PendingIntent jako działanie wywoływane po kliknięciu ikony. Utwórz tablicę zawierającą wszystkie działania niestandardowe i określ ją jako EXTRA_CHOOSER_CUSTOM_ACTIONS elementu Intent.
fun sharesheetCustomActions(context: Context, previewText: String) { val sendIntent = Intent(ACTION_SEND) .setType("text/plain") .putExtra(Intent.EXTRA_TEXT, previewText) val shareIntent = Intent.createChooser(sendIntent, null) val customActions = arrayOf( ChooserAction.Builder( Icon.createWithResource(context, R.drawable.ic_logo), "Custom", PendingIntent.getBroadcast( context, 1, Intent(Intent.ACTION_VIEW), PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT ) ).build() ) shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions) context.startActivity(shareIntent) }
Dodawanie kierowania niestandardowego
Arkusz udostępniania w Androidzie umożliwia określenie maksymalnie 2 niestandardowych intencji aktywności, które są wyświetlane przed sugestiami aplikacji, za pomocą Intent.EXTRA_INITIAL_INTENTS.
W przypadku elementów docelowych udostępniania bezpośredniego (takich jak rozmowy lub kontakty) opublikuj skróty dynamiczne za pomocą ShortcutManagerCompat (patrz Udostępnianie bezpośrednie):
Dodaj Intent.EXTRA_INITIAL_INTENTS do intencji udostępniania po wywołaniu Intent.createChooser():
val sendIntent = Intent(ACTION_SEND).apply { type = "text/plain" putExtra(Intent.EXTRA_TEXT, previewText) } val customIntent = Intent().apply { component = ComponentName(context.packageName, "${context.packageName}.CustomActivity") } val shareIntent = Intent.createChooser(sendIntent, null).apply { putExtra( Intent.EXTRA_INITIAL_INTENTS, arrayOf(customIntent) ) } context.startActivity(shareIntent)
Używaj tej funkcji z rozwagą. Każdy dodany przez Ciebie niestandardowy element Intent zmniejsza liczbę elementów sugerowanych przez system. Zasadniczo unikaj dodawania niestandardowych wartości docelowych. Typowym przykładem dodawania Intent.EXTRA_INITIAL_INTENTS jest udostępnianie dodatkowych działań, które użytkownicy mogą wykonywać na udostępnionych treściach. Na przykład użytkownik udostępnia obrazy, a Intent.EXTRA_INITIAL_INTENTS służy do umożliwienia mu wysłania linku.
Wykluczanie określonych celów według komponentu
Możesz wykluczyć określone cele, podając Intent.EXTRA_EXCLUDE_COMPONENTS.
Zrób to tylko wtedy, gdy chcesz usunąć cele, nad którymi masz kontrolę. Typowym przypadkiem użycia jest ukrywanie celów udostępniania aplikacji, gdy użytkownicy udostępniają treści z poziomu aplikacji, ponieważ ich intencją jest prawdopodobnie udostępnienie treści poza aplikacją.
Dodaj Intent.EXTRA_EXCLUDE_COMPONENTS do intencji po wywołaniu Intent.createChooser():
fun excludeSpecificTargets(context: Context) { val share = Intent.createChooser(Intent(ACTION_SEND), null).apply { // Only use for components you have control over val excludedComponentNames = arrayOf(ComponentName("com.example.android", "ExampleClass")) putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames) } context.startActivity(share) }
Uzyskiwanie informacji o udostępnianiu
Warto wiedzieć, kiedy użytkownicy udostępniają treści i jakie miejsce docelowe wybierają. Arkusz udostępniania w Androidzie umożliwia uzyskanie tych informacji, podając ComponentName elementów docelowych, które użytkownicy wybierają za pomocą IntentSender.
Najpierw utwórz PendingIntent dla BroadcastReceiver i podaj jego IntentSender w Intent.createChooser():
fun infoAboutSharing(context: Context, requestCode: Int) { var share = Intent(ACTION_SEND) // ... val pi = PendingIntent.getBroadcast( context, requestCode, Intent(context, ShareBroadcastReceiver::class.java), PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) share = Intent.createChooser(share, null, pi.intentSender) context.startActivity(share) }
Odbierz wywołanie zwrotne w MyBroadcastReceiver i sprawdź w Intent.EXTRA_CHOOSER_RESULT:
override fun onReceive(context: Context?, intent: Intent) { val TAG = ShareBroadcastReceiver::class.simpleName val chooserResult: ChooserResult? = IntentCompat.getParcelableExtra( intent, Intent.EXTRA_CHOOSER_RESULT, ChooserResult::class.java, ) chooserResult?.let { Log.i(TAG, "Share callback: isShortcut: ${it.isShortcut}, type: ${typeToString(it.type)}, componentName: ${it.selectedComponent}", ) } ?: Log.i(TAG, "chooserResult is null") }
Więcej informacji znajdziesz w przykładzie udostępniania na platformie.
Używanie selektora intencji na Androidzie
ACTION_SEND.Mechanizm rozpoznawania intencji na Androidzie najlepiej sprawdza się podczas wysyłania danych do innej aplikacji w ramach dobrze zdefiniowanego przepływu zadań.
Aby użyć selektora intencji Androida, utwórz intencję i dodaj dodatkowe elementy, tak jak w przypadku wywołania arkusza udostępniania w Androidzie. Nie dzwoń jednak pod numer Intent.createChooser().
Jeśli jest kilka zainstalowanych aplikacji z filtrami, które pasują do ACTION_SEND i typu MIME, system wyświetla okno uściślania o nazwie rozpoznawanie intencji, które pozwala użytkownikowi wybrać miejsce docelowe udostępniania. Jeśli pasuje tylko jedna aplikacja, zostanie uruchomiona.
Oto przykład użycia mechanizmu rozpoznawania intencji w Androidzie do wysyłania tekstu:
fun intentResolver(context: Context) { val sendIntent: Intent = Intent().apply { action = ACTION_SEND putExtra(Intent.EXTRA_TEXT, "This is my text to send.") type = "text/plain" } context.startActivity(sendIntent) }
Więcej informacji
Więcej informacji o wysyłaniu danych znajdziesz w artykule Intencje i filtry intencji.