Obsługa klawiatury graficznej

Użytkownicy często chcą się komunikować przy użyciu emotikonów, naklejek i innych rodzajów bogatych treści. treści. W poprzednich wersjach Androida klawiatury ekranowe – nazywane też edytorów metod wprowadzania lub edytory IME – mogą wysyłać do aplikacji tylko emotikony w formacie Unicode. Do tworzenia treści multimedialnych interfejsów API przeznaczonych do określonych aplikacji, których nie można używać w innych aplikacjach, lub które obejmują obejścia, takie jak wysyłanie obrazów za pomocą prostego udostępniania, lub ze schowka.

Obraz przedstawiający klawiaturę, która obsługuje wyszukiwanie grafiki
Rysunek 1. Przykład obsługi klawiatury z obrazem.

Począwszy od Androida w wersji 7.1 (poziom interfejsu API 25) pakiet Android SDK zawiera zatwierdzenie Content API, który zapewnia uniwersalny sposób wysyłania obrazów i innych plików szczegółowe treści bezpośrednio do edytora tekstu w aplikacji. Ten interfejs API jest również dostępny w i Bibliotekę pomocy w wersji 13 od wersji 25.0.0. Zalecamy skorzystanie z pomocy Biblioteka, bo zawiera metody pomocnicze, które upraszczają implementację.

Za jego pomocą można tworzyć aplikacje do obsługi wiadomości, które akceptują treści multimedialne klawiatury, które umożliwiają wysyłanie szczegółowych treści do dowolnej aplikacji. Google Klawiatura i aplikacji takich jak Wiadomości firmy Google obsługiwać interfejsu Commit Content API na Androidzie 7.1, jak pokazano na ilustracji 1.

Z tego dokumentu dowiesz się, jak wdrożyć interfejs Commit Content API zarówno w edytorach IME, jak i aplikacji.

Jak to działa

Wstawianie obrazu klawiatury wymaga użycia edytora IME i aplikacji. Poniżej opisujemy każdy krok procesu wstawiania obrazu:

  1. Gdy użytkownik kliknie EditText, redaktor wysyła listę typów treści MIME, które akceptuje w EditorInfo.contentMimeTypes

  2. edytor IME odczytuje listę obsługiwanych typów i wyświetla zawartość akceptowanej przez edytor.

  3. Gdy użytkownik wybiera obraz, IME wywołuje commitContent() i wysyła InputContentInfo do redaktora. Wywołanie commitContent() jest analogiczne do wywołania commitText(), ale w przypadku szczegółowych treści. InputContentInfo zawiera identyfikator URI, który identyfikuje treść dostawcy usług.

Proces ten pokazano na rys. 2:

Obraz pokazujący sekwencję od aplikacji do IME i z powrotem do aplikacji
Rysunek 2. Zastosowanie IME do procesu aplikacji.

Dodawanie obsługi obrazów do aplikacji

Aby akceptować treści sformatowane za pomocą IME, aplikacja musi poinformować IME, jakiego typu treści dotyczy akceptuje i określa metodę wywołania zwrotnego, która jest wykonywana po odebraniu treści. Poniższy przykład pokazuje, jak utworzyć plik EditText, który akceptuje pliki PNG obrazy:

Kotlin

var editText: EditText = object : EditText(this) {
    override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection {
        var ic = super.onCreateInputConnection(outAttrs)
        EditorInfoCompat.setContentMimeTypes(outAttrs, arrayOf("image/png"))
        val mimeTypes = ViewCompat.getOnReceiveContentMimeTypes(this)
        if (mimeTypes != null) {
            EditorInfoCompat.setContentMimeTypes(outAttrs, mimeTypes)
            ic = InputConnectionCompat.createWrapper(this, ic, outAttrs)
        }
        return ic
    }
}

Java

EditText editText = new EditText(this) {
    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        InputConnection ic = super.onCreateInputConnection(outAttrs);
        EditorInfoCompat.setContentMimeTypes(outAttrs, new String[]{"image/png"});
        String[] mimeTypes = ViewCompat.getOnReceiveContentMimeTypes(this);
        if (mimeTypes != null) {
            EditorInfoCompat.setContentMimeTypes(outAttrs, mimeTypes);
            ic = InputConnectionCompat.createWrapper(this, ic, outAttrs);
        }
        return ic;
    }
};

Dalsze wyjaśnienie:

Oto zalecane metody:

  • Edytorzy, którzy nie obsługują szczegółowych treści, nie zadzwonią setContentMimeTypes() i opuszczają zestaw EditorInfo.contentMimeTypes do null.

  • Edytorzy ignorują treść, jeśli typ MIME jest określony w polu InputContentInfo nie pasuje do żadnego z akceptowanych typów.

  • Szczegółowe treści nie mają na nie wpływu i nie mają na nie wpływu kursora. Edytorzy mogą ignorować pozycję kursora podczas pracy z treścią.

  • W OnCommitContentListener.onCommitContent(), możesz zwrócić true asynchronicznie, nawet przed wczytaniem treści.

  • W przeciwieństwie do tekstu, który można edytować w IME przed zatwierdzeniem, bogatym od razu po publikacji. Jeśli chcesz zezwolić użytkownikom na edytowanie lub usuwanie treści, samodzielnie zaimplementuj daną logikę.

Aby przetestować aplikację, upewnij się, że urządzenie lub emulator ma klawiaturę, która może wysyłać szczegółowe treści. Klawiatury Google możesz używać w Androidzie 7.1 lub nowszym.

Dodawanie obsługi obrazów do IME

edytory IME, które chcą wysyłać do aplikacji szczegółowe treści, muszą zaimplementować zatwierdzanie treści API zgodnie z tym przykładem:

  • Zastąp onStartInput() lub onStartInputView() i przeczytaj listę obsługiwanych typów treści w środowisku docelowym redaktorem. Fragment kodu poniżej pokazuje, jak sprawdzić, czy element docelowy Edytor akceptuje obrazy GIF.

Kotlin

override fun onStartInputView(editorInfo: EditorInfo, restarting: Boolean) {
    val mimeTypes: Array<String> = EditorInfoCompat.getContentMimeTypes(editorInfo)

    val gifSupported: Boolean = mimeTypes.any {
        ClipDescription.compareMimeTypes(it, "image/gif")
    }

    if (gifSupported) {
        // The target editor supports GIFs. Enable the corresponding content.
    } else {
        // The target editor doesn't support GIFs. Disable the corresponding
        // content.
    }
}

Java

@Override
public void onStartInputView(EditorInfo info, boolean restarting) {
    String[] mimeTypes = EditorInfoCompat.getContentMimeTypes(editorInfo);

    boolean gifSupported = false;
    for (String mimeType : mimeTypes) {
        if (ClipDescription.compareMimeTypes(mimeType, "image/gif")) {
            gifSupported = true;
        }
    }

    if (gifSupported) {
        // The target editor supports GIFs. Enable the corresponding content.
    } else {
        // The target editor doesn't support GIFs. Disable the corresponding
        // content.
    }
}
  • Zatwierdzanie treści w aplikacji, gdy użytkownik wybiera obraz. Nie dzwoń commitContent(). może spowodować utratę zaznaczenia przez edytora. Fragment kodu poniżej pokazuje, aby zatwierdzić obraz GIF.

Kotlin

// Commits a GIF image.

// @param contentUri = Content URI of the GIF image to be sent.
// @param imageDescription = Description of the GIF image to be sent.

fun commitGifImage(contentUri: Uri, imageDescription: String) {
    val inputContentInfo = InputContentInfoCompat(
            contentUri,
            ClipDescription(imageDescription, arrayOf("image/gif")),
            null
    )
    val inputConnection = currentInputConnection
    val editorInfo = currentInputEditorInfo
    var flags = 0
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
        flags = flags or InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION
    }
    InputConnectionCompat.commitContent(inputConnection, editorInfo, inputContentInfo, flags, null)
}

Java

// Commits a GIF image.

// @param contentUri = Content URI of the GIF image to be sent.
// @param imageDescription = Description of the GIF image to be sent.

public static void commitGifImage(Uri contentUri, String imageDescription) {
    InputContentInfoCompat inputContentInfo = new InputContentInfoCompat(
            contentUri,
            new ClipDescription(imageDescription, new String[]{"image/gif"}),
            null
    );
    InputConnection inputConnection = getCurrentInputConnection();
    EditorInfo editorInfo = getCurrentInputEditorInfo();
    Int flags = 0;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
        flags |= InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION;
    }
    InputConnectionCompat.commitContent(
            inputConnection, editorInfo, inputContentInfo, flags, null);
}

Autor edytora IME musi najprawdopodobniej wdrożyć własnego dostawcę treści, odpowiadać na żądania URI treści. Wyjątkiem jest sytuacja, gdy edytor IME obsługuje treści od obecnych dostawców treści, takich jak MediaStore Informacje na temat: tworzenia dostawców treści, zobacz materiały dostawcy i file dla dostawcy.

Jeśli tworzysz własnego dostawcę treści, odradzamy jego eksportowanie. przez ustawienie android:exported do false Zamiast tego włącz przyznawanie uprawnień u dostawcy przez ustawienie android:grantUriPermission do true. Następnie edytor IME może przyznać uprawnienia dostępu do identyfikatora URI treści, że treści są objęte zasadą. Można to zrobić na dwa sposoby:

  • Na Androidzie 7.1 (poziom interfejsu API 25) i nowszych podczas wywoływania funkcji commitContent() ustaw parametr flagi na INPUT_CONTENT_GRANT_READ_URI_PERMISSION Następnie obiekt InputContentInfo odbierany przez aplikację może zażądać żądania i zwolnij tymczasowe uprawnienia do odczytu, wywołując requestPermission(). oraz releasePermission()

  • W Androidzie 7.0 (poziom interfejsu API 24) i starszych Pole INPUT_CONTENT_GRANT_READ_URI_PERMISSION jest ignorowane, więc przyznaj je ręcznie dostępu do treści. Można to zrobić na przykład za pomocą grantUriPermission(), ale możesz wdrożyć własny mechanizm, który który spełnia Twoje potrzeby.

Aby przetestować edytor IME, upewnij się, że na urządzeniu lub emulatorze jest aplikacja, która odbiera szczegółowe treści. Aplikacja Google Messenger działa na Androidzie 7.1 lub nowszym.