Unterstützung für Bildtastatur

Nutzer möchten oft Emojis, Sticker und andere Inhalte. In früheren Android-Versionen wurden Eingabemethoden-Editoren oder IMEs: Es können nur Unicode-Emojis an Apps gesendet werden. Für Rich Content, Apps, App-spezifische APIs, die nicht in anderen Apps verwendet werden konnten, oder Problemumgehungen verwendet haben, z. B. Senden von Bildern mit einer einfachen Aktion zum Teilen oder die Zwischenablage öffnen.

<ph type="x-smartling-placeholder">
</ph> Ein Bild, auf dem eine Tastatur zu sehen ist, die die Bildersuche unterstützt <ph type="x-smartling-placeholder">
</ph> Abbildung 1: Beispiel für Bildtastaturunterstützung

Ab Android 7.1 (API-Level 25) enthält das Android SDK das Commit Content API, mit der IMEs Bilder und andere Rich Content direkt in einen Texteditor in einer App exportieren. Die API ist auch verfügbar in der Support Library v13 ab Version 25.0.0. Wir empfehlen, den Support Bibliothek, da sie Hilfsmethoden enthält, die die Implementierung vereinfachen.

Mit dieser API können Sie Messaging-Apps erstellen, die Rich Content von beliebigen Tastaturen sowie Tastaturen, mit denen Rich Content an jede App gesendet werden kann. Die Google Tastatur und Apps wie Nachrichten von Google die Commit Content API in Android 7.1 unterstützen (siehe Abbildung 1).

In diesem Dokument erfahren Sie, wie Sie die Commit Content API sowohl in IMEs als auch in Apps.

Funktionsweise

Das Einfügen von Tastaturbildern muss über den IME und die App erfolgen. Die In der folgenden Reihenfolge werden die einzelnen Schritte zum Einfügen von Bildern beschrieben:

  1. Wenn der Nutzer auf EditText tippt, sendet der Editor eine Liste der MIME-Inhaltstypen, EditorInfo.contentMimeTypes

  2. Der IME liest die Liste der unterstützten Typen und zeigt die Inhalte in der Soft- die der Editor akzeptiert.

  3. Wenn der Nutzer ein Bild auswählt, ruft der IME commitContent() und sendet eine InputContentInfo an den Herausgeber. Der Aufruf commitContent() ist analog zum commitText()-Aufruf, aber für Rich Content. InputContentInfo enthält einen URI, der bezeichnet den Inhalt in einem Inhalt Dienstanbieter.

Dieser Vorgang wird in Abbildung 2 dargestellt:

<ph type="x-smartling-placeholder">
</ph> Ein Bild, auf dem die Abfolge von der App zu IME und zurück zur App zu sehen ist <ph type="x-smartling-placeholder">
</ph> Abbildung 2: Ablauf von Anwendung zu IME zu Anwendung.

Bildunterstützung zu Apps hinzufügen

Um Rich Content von IMEs zu akzeptieren, muss eine App den IMEs mitteilen, welche Inhaltstypen sie enthalten. akzeptiert eine Callback-Methode, die beim Empfang von Inhalten ausgeführt wird, und gibt diese an. Das folgende Beispiel zeigt, wie ein EditText erstellt wird, das PNG akzeptiert Bilder:

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;
    }
};

Im Folgenden finden Sie eine genauere Erklärung:

Folgende Vorgehensweisen werden empfohlen:

  • Editoren, die Rich Content nicht unterstützen, rufen keine setContentMimeTypes() und sie verlassen ihren EditorInfo.contentMimeTypes-Satz an null.

  • Editoren ignorieren den Inhalt, wenn der in InputContentInfo angegebene MIME-Typ stimmt mit keinem der akzeptierten Typen überein.

  • Der Rich Content wirkt sich nicht auf die Position des Textes aus und wird auch nicht davon beeinflusst. Cursor. Bearbeiter können die Cursorposition beim Arbeiten mit Inhalten ignorieren.

  • Im Editor- OnCommitContentListener.onCommitContent() können Sie true asynchron zurückgeben, auch wenn bevor der Inhalt geladen wird.

  • Im Gegensatz zu Text, der vor dem Commit im IME bearbeitet werden kann, wird sofort ein Commit für die Inhalte übernommen. Wenn Sie Nutzern erlauben möchten, Elemente zu bearbeiten oder zu löschen implementieren Sie die Logik selbst.

Zum Testen Ihrer App muss Ihr Gerät oder Emulator über eine Tastatur verfügen, die Rich Content enthalten. Die Google-Tastatur ist ab Android 7.1 verfügbar.

Image-Unterstützung zu IMEs hinzufügen

IMEs, die Rich Content an Apps senden möchten, müssen den Commit-Inhalt implementieren. wie im folgenden Beispiel gezeigt:

  • Überschreiben onStartInput() oder onStartInputView() und lies die Liste der unterstützten Inhaltstypen aus der Ziel- Editor. Im folgenden Code-Snippet sehen Sie, wie Sie prüfen, akzeptiert der Editor GIF-Bilder.

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

  • Sie übernehmen das Commit von Inhalten in der App, wenn der Nutzer ein Bild auswählt. Anrufe vermeiden commitContent(), wenn ein Text geschrieben wird, weil Dadurch verliert der Editor den Fokus. Das folgende Code-Snippet zeigt, um ein GIF-Image festzuschreiben.

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);
}

Als IME-Autor müssen Sie höchstwahrscheinlich Ihren eigenen Contentanbieter implementieren, auf Inhalts-URI-Anfragen antworten. Dies gilt nicht, wenn Ihr IME Inhalte unterstützt von bestehenden Contentanbietern wie MediaStore Informationen zur der Erstellung von Content-Providern, siehe Content-Provider Anbieter und Datei finden Sie in der Dokumentation des Anbieters.

Wenn Sie Ihren eigenen Contentanbieter erstellen, raten wir davon ab, ihn zu exportieren. indem Sie android:exported bis false. Aktivieren Sie stattdessen die Erteilung von Berechtigungen beim Anbieter, indem Sie Folgendes festlegen: android:grantUriPermission an true. Ihr IME kann dann Berechtigungen für den Zugriff auf den Inhalts-URI gewähren, wenn dass die Inhalte verpflichtet sind. Dafür gibt es zwei Möglichkeiten:

  • Wenn Sie unter Android 7.1 (API-Level 25) und höher commitContent() aufrufen, geschieht Folgendes: Flag-Parameter festlegen auf INPUT_CONTENT_GRANT_READ_URI_PERMISSION Dann kann das InputContentInfo-Objekt, das die App empfängt, temporäre Leseberechtigungen durch folgenden Aufruf freigeben requestPermission() und releasePermission()

  • Unter Android 7.0 (API-Level 24) und niedriger INPUT_CONTENT_GRANT_READ_URI_PERMISSION wird ignoriert. Erteilen Sie deshalb manuell Genehmigung der Inhalte. Eine Möglichkeit, dies zu tun, grantUriPermission(), aber Sie können einen eigenen Mechanismus implementieren, Ihre eigenen Anforderungen erfüllt.

Um Ihren IME zu testen, muss Ihr Gerät oder Emulator über eine App verfügen, die den IME Rich Content enthalten. Sie können die Google Messenger App mit Android 7.1 oder höher verwenden.