Użytkownicy uwielbiają obrazy, filmy i inne ekspresyjne treści, Przeniesienie takich treści do aplikacji nie zawsze jest łatwe. Aby ułatwić aplikacjom o treściach multimedialnych. Android 12 (poziom interfejsu API 31) wprowadza ujednolicony interfejs API, umożliwia aplikacji przyjmowanie 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życie 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 przez
tworząc pojedynczy interfejs API do wdrożenia, dzięki czemu możesz skupić się na logice swojej 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
.API to interfejs detektora
z jedną 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 odbiornik, określając typy treści aplikacja obsługuje:
object MyReceiver : OnReceiveContentListener { val MIME_TYPES = arrayOf("image/*", "video/*") // ... override fun onReceiveContent(view: View, payload: ContentInfoCompat): ContentInfoCompat? { TODO("Not yet implemented") } }
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ę zaimplementuj reszta słuchacza:
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/*") } }
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. zwracać pozostałe dane, aby zlecić ich obsługę platformie.
Po zaimplementowaniu detektora ustaw go na odpowiednich elementach interfejsu w aplikacji:
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()) } }
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
Uprawnienia do odczytu są przyznawane i uwalniane automatycznie przez platformę dla dowolnego
identyfikatory URI treści w
ładunek został przekazany do funkcji OnReceiveContentListener
.
Zwykle aplikacja przetwarza identyfikatory URI treści w usłudze lub działaniu. W przypadku długotrwałego przetwarzania użyj WorkManagera. Podczas implementacji rozszerz uprawnienia do usługi docelowej lub aktywności, przekazując treści za pomocą parametru Intent.setClipData
i ustawiając flagę FLAG_GRANT_READ_URI_PERMISSION
.
Możesz też użyć wątku działającego w bieżącym kontekście, aby
przetwarzać treści. 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
, użyj interfejsu Jetpack API InputConnectionCompat.createWrapper
, aby skonfigurować InputConnection
.
Jeśli klasa View
zastępuje
onTextContextMenuItem
, przekaż funkcji super, gdy element menu to
R.id.paste
lub
R.id.pasteAsPlainText
.
Porównanie z interfejsem API Obraz klawiatury
Interfejs API OnReceiveContentListener
można traktować jako kolejną wersję dotychczasowego interfejsu API obrazów klawiatury. To ujednolicone
API obsługuje funkcje interfejsu API obrazów klawiatury, a także niektóre
funkcje dodatkowe. 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 klawiatury Image API | 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 |
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 zintegrowany interfejs API |
---|---|---|
Wstawianie z klawiatury | Tak (poziom interfejsu API 25 lub wyższy) | Tak (Android 12 lub nowszy) |
Wstawianie przy użyciu opcji wklejania za pomocą dotyku & menu wstrzymania | Nie | |
Wstaw za pomocą przeciągania i upuszczania | Nie |