Otrzymuj szczegółowe treści

Rysunek 1. Ujednolicony interfejs API zapewnia jedno miejsce do obsługiwania treść przychodząca niezależnie od konkretnego mechanizmu interfejsu (np. wklejania). po dotknięciu i przytrzymaj menu lub przeciągnij i upuść.

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, taki jak OnReceiveContentListener do komponentów interfejsu i otrzymywać wywołanie zwrotne, gdy treść zostanie wstawiona . Wywołanie zwrotne staje się jedynym miejscem przetwarzania kodu wszystkie treści – od zwykłego i z określonymi stylami po znaczniki, obrazy, filmy pliki audio i inne.

Aby zapewnić zgodność wsteczną z poprzednimi wersjami Androida, ten interfejs API został również dostępne na Androidzie X, od Core 1.7 i Appcompat 1.4 które zalecamy przy wdrażaniu tej funkcji.

Omówienie

W przypadku innych istniejących interfejsów API każdy mechanizm interfejsu – taki jak dotyk i menu wstrzymania ma własny interfejs API. Oznacza to, że musisz: integrować je osobno z każdym interfejsem API, dodając podobny kod do każdego mechanizmu, wstawia treść:

Obraz przedstawiający różne działania i względny interfejs API do wdrożenia
Rysunek 2. Wcześniej w aplikacjach każdy interfejs API stosował inny interfejs API. 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ą:

Obraz przedstawiający uproszczony ujednolicony interfejs API
Rysunek 3. Ujednolicony interfejs API umożliwia implementację pojedynczego Interfejs API, który obsługuje wszystkie mechanizmy interfejsu użytkownika.

To podejście oznacza też, że dodanie nowych sposobów wstawiania treści do na platformie, nie musisz wprowadzać dodatkowych zmian w kodzie, aby włączyć w aplikacji. A jeśli aplikacja wymaga pełnego dostosowania możesz używać istniejących interfejsów API, które nadal działają tak samo.

Implementacja

API to interfejs detektora z jedną metodą, OnReceiveContentListener Do obsługi starszych wersji platformy Android zalecamy korzystanie z dopasowywanie OnReceiveContentListener w bibliotece AndroidX Core.

Aby korzystać z interfejsu API, zaimplementuj odbiornik, określając typy treści aplikacja obsługuje:

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ę zaimplementuj reszta słuchacza:

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 intencjami, możesz użyć logikę obsługi identyfikatorów URI treści w poszczególnych aplikacjach. Zwróć pozostałe dane do delegować obsługę tych danych do platformy.

Po zaimplementowaniu detektora 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 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. Dla: długotrwałe przetwarzanie, użyj funkcji WorkManager. Po wdrożeniu rozszerz uprawnienia do docelowej usługi lub działania, przekazując treści za pomocą Intent.setClipData i ustawić 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ć odniesienie do payload obiekt odebrał detektor, aby upewnić się, że uprawnienia nie są przedwcześnie odwołany przez platformę.

Widoki niestandardowe

Jeśli Twoja aplikacja używa niestandardowej podklasy View, upewnij się, że podklasa: OnReceiveContentListener nie jest pomijany.

Jeśli klasa View zastępuje 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

Można powiedzieć, że OnReceiveContentListener to następna wersja interfejsu API keyboard Image API. To ujednolicone API obsługuje funkcje interfejsu API Obrazów klawiatury, a także niektóre funkcje dodatkowe. Zgodność urządzenia i funkcji różni się w zależności od niezależnie od tego, czy używasz biblioteki Jetpack czy natywnych interfejsów API z pakietu Android SDK.

Tabela 1. Obsługiwane funkcje i poziomy interfejsu API w przypadku Jetpack.
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)
Wstawianie przy użyciu opcji wklejania za pomocą dotyku & menu wstrzymania 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 ujednolicony interfejs API
Wstawianie z klawiatury Tak (poziom 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