Użytkownicy uwielbiają obrazy, filmy i inne ekspresyjne treści, ale wstawianie i przenoszenie tych treści w aplikacjach 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.
Do komponentów interfejsu możesz podłączyć interfejs, np. OnReceiveContentListener
, i otrzymywać wywołanie zwrotne, gdy treść zostanie wstawiona za pomocą dowolnego mechanizmu. Wywołanie zwrotne staje się miejscem, w którym Twój kod odbiera całą zawartość – od zwykłego i stylowanego tekstu po znaczniki, obrazy, filmy, pliki audio i inne.
Aby zapewnić zgodność wsteczną z poprzednimi wersjami Androida, ten interfejs API jest też dostępny w AndroidzieX, począwszy od Core 1.7 i Appcompat 1.4. Zalecamy korzystanie z niego przy implementowaniu tej funkcji.
Omówienie
W przypadku innych istniejących interfejsów API każdy mechanizm interfejsu – taki jak menu naciśnięcia i przytrzymania lub przeciągnięcie – ma swój własny interfejs API. Musisz więc zintegrować go z każdym interfejsem API oddzielnie, dodając podobny kod do każdego mechanizmu wstawiającego treści:
Interfejs API OnReceiveContentListener
konsoliduje te różne ścieżki kodu, tworząc pojedynczy interfejs API do zaimplementowania, dzięki czemu możesz skupić się na logice konkretnej aplikacji, a platforma zajmie się resztą:
Oznacza to również, że po dodaniu do platformy nowych sposobów wstawiania treści nie trzeba wprowadzać dodatkowych zmian w kodzie, aby zapewnić obsługę aplikacji. A jeśli aplikacja musi wdrożyć pełne dostosowanie do konkretnego przypadku użycia, możesz nadal korzystać z istniejących interfejsów API, które działają w ten sam sposób.
Implementacja
Interfejs API to interfejs detektora z pojedynczą metodą – OnReceiveContentListener
.
Do obsługi starszych wersji platformy Androida zalecamy używanie interfejsu dopasowywania OnReceiveContentListener
z biblioteki AndroidX Core.
Aby korzystać z interfejsu API, zaimplementuj odbiornik, określając typy treści, które może obsługiwać 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) { Pairsplit = 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 za pomocą intencji, możesz ponownie wykorzystać logikę tej aplikacji do obsługi identyfikatorów URI treści. Zwróć pozostałe dane, aby przekazać obsługę ich do platformy.
Po zaimplementowaniu detektora ustaw go na odpowiednich elementach interfejsu w swojej 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 identyfikatora URI
Platforma automatycznie przyznaje i zwalnia do odczytu uprawnienia do odczytu dla wszystkich identyfikatorów URI treści w ładunku przekazywanym do OnReceiveContentListener
.
Zwykle aplikacja przetwarza identyfikatory URI treści w usłudze lub działaniu. Jeśli chcesz przeprowadzać długotrwałe przetwarzanie, użyj WorkManagera. Podczas wdrażania tej opcji 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
.
Do przetworzenia treści możesz też użyć wątku w tle w bieżącym kontekście. W takim przypadku musisz zachować odniesienie do obiektu payload
otrzymanego przez detektor, aby mieć pewność, że uprawnienia nie zostaną przedwcześnie unieważnione przez platformę.
Widoki niestandardowe
Jeśli aplikacja używa niestandardowej podklasy View
, upewnij się, że nie zostanie pominięta klasa OnReceiveContentListener
.
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
, przekaż działanie funkcji super, gdy pozycja menu to R.id.paste
lub R.id.pasteAsPlainText
.
Porównanie z interfejsem API Obraz klawiatury
Interfejs OnReceiveContentListener
API to następna wersja istniejącego keyboard Image API. Ten ujednolicony interfejs API obsługuje funkcje Content API z obrazem klawiatury, a także kilka dodatkowych funkcji. Zgodność urządzeń i funkcji różni się w zależności od tego, czy korzystasz z biblioteki Jetpack czy natywnych interfejsów API z pakietu Android SDK.
Działanie lub funkcja | Obsługiwane przez interfejs klawiatury Image API | Obsługiwane przez ujednolicony interfejs API |
---|---|---|
Wstawianie z klawiatury | Tak (poziom API 13 lub wyższy) | Tak (poziom API 13 lub wyższy) |
Wstaw przez wklejenie z menu naciśnięcia i przytrzymania | Nie | Tak |
Wstaw za pomocą przeciągania i upuszczania | Nie | Tak (poziom API 24 lub wyższy) |
Działanie lub funkcja | Obsługiwane przez interfejs klawiatury Image API | Obsługiwane przez ujednolicony interfejs API |
---|---|---|
Wstawianie z klawiatury | Tak (poziom API 25 lub wyższy) | Tak (Android 12 lub nowszy) |
Wstaw przez wklejenie z menu naciśnięcia i przytrzymania | Nie | |
Wstaw za pomocą przeciągania i upuszczania | Nie |