Użytkownicy lubią obrazy, filmy i inne treści, które przekazują emocje, ale wstawianie i przenoszenie tych treści do aplikacji nie zawsze jest łatwe. Aby ułatwić aplikacjom odbieranie treści multimedialnych, Android 12 (poziom interfejsu API 31) wprowadza ujednolicony interfejs API, który pozwala aplikacjom akceptować treści z dowolnego źródła: schowka, klawiatury lub przeciągania.
Możesz dołączyć interfejs, na przykład OnReceiveContentListener
, do komponentów interfejsu użytkownika i otrzymać wywołanie zwrotne, gdy treści zostaną wstawione za pomocą dowolnego mechanizmu. Funkcja wywołania zwrotnego staje się jedynym miejscem w kodzie, w którym można obsłużyć wszystkie treści, od zwykłego tekstu i tekstu stylizowanego po znaczniki, obrazy, filmy, pliki audio i inne.
Aby zapewnić zgodność wsteczną z poprzednimi wersjami Androida, ten interfejs API jest też dostępny w AndroidX, począwszy od wersji Core 1.7 i Appcompat 1.4, których zalecamy używanie podczas implementowania tej funkcji.
Omówienie
W przypadku innych istniejących interfejsów API każdy mechanizm interfejsu użytkownika, np. menu kliknij i przytrzymaj lub przeciąganie, ma swój odpowiedni interfejs API. Oznacza to, że musisz się integrować z każdym interfejsem API osobno, dodając podobny kod dla każdego mechanizmu, który wstawia treści:
Interfejs API OnReceiveContentListener
konsoliduje te różne ścieżki kodu, tworząc jeden interfejs API do wdrożenia, dzięki czemu możesz skupić się na logice aplikacji, a platforma zajmie się resztą:
Dzięki temu, gdy na platformie pojawią się nowe sposoby wstawiania treści, nie będziesz musiał wprowadzać dodatkowych zmian w kodzie, aby umożliwić obsługę w aplikacji. Jeśli aplikacja będzie wymagać pełnej personalizacji w przypadku konkretnego zastosowania, nadal możesz używać dotychczasowych interfejsów API, które działają w taki sam sposób.
Implementacja
.Interfejs API to interfejs detektora z pojedynczą metodą – OnReceiveContentListener
.
Aby zapewnić obsługę starszych wersji platformy Android, zalecamy użycie odpowiedniego interfejsu OnReceiveContentListener
w bibliotece AndroidX Core.
Aby korzystać z interfejsu API, zaimplementuj listenera, określając, jakie typy treści może obsługiwać Twoja aplikacja:
Kotlin
object MyReceiver : OnReceiveContentListener { val MIME_TYPES = arrayOf("image/*", "video/*") // ... override fun onReceiveContent(view: View, payload: ContentInfoCompat): ContentInfoCompat? { TODO("Not yet implemented") } }
Java
public class MyReceiver implements OnReceiveContentListener { public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"}; // ... }
Po określeniu wszystkich typów MIME treści obsługiwanych przez aplikację wdróż resztę detektora:
Kotlin
class MyReceiver : OnReceiveContentListener { override fun onReceiveContent(view: View, contentInfo: ContentInfoCompat): ContentInfoCompat { val split = contentInfo.partition { item: ClipData.Item -> item.uri != null } val uriContent = split.first val remaining = split.second if (uriContent != null) { // App-specific logic to handle the URI(s) in uriContent. } // Return anything that your app didn't handle. This preserves the // default platform behavior for text and anything else that you aren't // implementing custom handling for. return remaining } companion object { val MIME_TYPES = arrayOf("image/*", "video/*") } }
Java
public class MyReceiver implements OnReceiveContentListener { public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"}; @Override public ContentInfoCompat onReceiveContent(View view, ContentInfoCompat contentInfo) { Pair<ContentInfoCompat, ContentInfoCompat> split = contentInfo.partition( item -> item.getUri() != null); ContentInfo uriContent = split.first; ContentInfo remaining = split.second; if (uriContent != null) { // App-specific logic to handle the URI(s) in uriContent. } // Return anything that your app didn't handle. This preserves the // default platform behavior for text and anything else that you aren't // implementing custom handling for. return remaining; } }
Jeśli Twoja aplikacja obsługuje już udostępnianie z intencją, możesz ponownie użyć logiki specyficznej dla aplikacji do obsługi identyfikatorów URI treści. Zwróć pozostałe dane, aby przekazać obsługę ich do platformy.
Po zaimplementowaniu listenera ustaw go na odpowiednich elementach interfejsu w aplikacji:
Kotlin
class MyActivity : Activity() { public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... val myInput = findViewById(R.id.my_input) ViewCompat.setOnReceiveContentListener(myInput, MyReceiver.MIME_TYPES, MyReceiver()) } }
Java
public class MyActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { // ... AppCompatEditText myInput = findViewById(R.id.my_input); ViewCompat.setOnReceiveContentListener(myInput, MyReceiver.MIME_TYPES, new MyReceiver()); } }
Uprawnienia dotyczące identyfikatorów URI
Platforma automatycznie przyznaje i odblokowuje uprawnienia do odczytu w przypadku wszystkich identyfikatorów URI treści w danych przekazywanych do usługi OnReceiveContentListener
.
Zwykle aplikacja przetwarza identyfikatory URI treści w usłudze lub aktywności. W przypadku długotrwałego przetwarzania użyj WorkManagera. Podczas implementacji rozszerz uprawnienia do usługi docelowej lub działania, przekazując treść za pomocą polecenia Intent.setClipData
i ustawiając flagę FLAG_GRANT_READ_URI_PERMISSION
.
Możesz też użyć wątku w tle w bieżącym kontekście, aby przetworzyć dane. W takim przypadku musisz zachować odwołanie do obiektu payload
otrzymanego przez listenera, aby upewnić się, że uprawnienia nie zostaną przedwcześnie cofnięte przez platformę.
Widoki niestandardowe
Jeśli Twoja aplikacja korzysta z niestandardowej podklasy View
, upewnij się, że nie jest ona pomijana.
Jeśli klasa View
zastępuje metodę onCreateInputConnection
, skonfiguruj InputConnection
za pomocą interfejsu Jetpack API InputConnectionCompat.createWrapper
.
Jeśli klasa View
zastępuje metodę onTextContextMenuItem
, deleguj do super, gdy pozycja menu to R.id.paste
lub R.id.pasteAsPlainText
.
Porównanie z interfejsem API obrazów klawiatury
Interfejs API OnReceiveContentListener
można traktować jako kolejną wersję dotychczasowego interfejsu API obrazów klawiatury. Ten zintegrowany interfejs API obsługuje funkcje interfejsu API obrazów klawiatury oraz kilka dodatkowych funkcji. Kompatybilność z urządzeniami i funkcjami różni się w zależności od tego, czy używasz biblioteki Jetpack czy natywnych interfejsów API z pakietu SDK Androida.
Działanie lub funkcja | Obsługiwane przez interfejs API obrazów klawiatury | Obsługiwane przez zintegrowany interfejs API |
---|---|---|
Wstawianie z klawiatury | Tak (interfejs API w wersji 13 lub nowszej) | Tak (poziom API 13 lub wyższy) |
Wstawianie za pomocą wklejania z menu naciśnięcia i przytrzymania | Nie | Tak |
Wstawianie za pomocą przeciągania i upuszczania | Nie | Tak (poziom interfejsu API 24 lub wyższy) |
Działanie lub funkcja | Obsługiwane przez interfejs API obrazów klawiatury | Obsługiwane przez zintegrowany interfejs API |
---|---|---|
Wstawianie z klawiatury | Tak (poziom interfejsu API 25 lub wyższy) | Tak (Android 12 lub nowszy) |
Wstawianie za pomocą wklejania z menu naciśnięcia i przytrzymania | Nie | |
Wstawianie za pomocą przeciągania i upuszczania | Nie |