Otrzymuj szczegółowe treści

Rysunek 1. Ujednolicony interfejs API zapewnia jedno miejsce do obsługi treści przychodzących niezależnie od konkretnego mechanizmu interfejsu, takiego jak wklejanie z menu dotknij i przytrzymaj lub przeciąganie i upuszczanie.

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.7Appcompat 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:

Obraz przedstawiający różne działania i względny interfejs API do wdrożenia
Rysunek 2. Wcześniej aplikacje implementowały inne interfejsy API dla każdego mechanizmu wstawiania 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ą:

Ilustracja przedstawiająca uproszczony interfejs Unified API
Rysunek 3. Ujednolicony interfejs API umożliwia implementację jednego interfejsu API, który obsługuje wszystkie mechanizmy interfejsu użytkownika.

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:

KotlinJava
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:

KotlinJava
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:

KotlinJava
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.

Tabela 1. Obsługiwane funkcje i poziomy interfejsu API w Jetpacku.
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)
Tabela 2. Obsługiwane funkcje i poziomy interfejsu API w przypadku reklam natywnych API.
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