Nutzer mögen Bilder, Videos und andere ausdrucksstarke Inhalte, aber das Einfügen und Es ist nicht immer einfach, diese Inhalte in Apps zu verschieben. Damit Apps Rich-Inhalte einfacher empfangen können, wird in Android 12 (API-Level 31) eine einheitliche API eingeführt, mit der Ihre App Inhalte aus beliebigen Quellen akzeptieren kann: Zwischenablage, Tastatur oder Ziehen.
Sie können eine Benutzeroberfläche wie OnReceiveContentListener
an UI-Komponenten anhängen und einen Rückruf erhalten, wenn Inhalte über einen beliebigen Mechanismus eingefügt werden. Der Callback wird zur einzigen Stelle, an der Ihr Code die
alle Inhalte empfangen, von einfachem Text bis hin zu Markup, Bildern, Videos
Audiodateien usw.
Aus Gründen der Abwärtskompatibilität mit früheren Android-Versionen ist diese API auch in AndroidX verfügbar, ab Core 1.7 und Appcompat 1.4 die wir für die Implementierung dieser Funktion empfehlen.
Übersicht
Bei anderen vorhandenen APIs hat jeder UI-Mechanismus – z. B. das Menü „Berühren und halten“ oder das Ziehen – eine eigene entsprechende API. Das bedeutet, dass Sie in jede API integriert werden, wobei für jeden Mechanismus ähnlicher Code fügt Inhalt ein:
Die OnReceiveContentListener
API konsolidiert diese verschiedenen Codepfade, indem
Sie brauchen nur eine API zu implementieren, damit Sie sich auf die App-spezifische Logik konzentrieren können.
Den Rest übernimmt die Plattform:
Dieser Ansatz bedeutet auch, dass Sie keine zusätzlichen Codeänderungen vornehmen müssen, wenn der Plattform neue Möglichkeiten zum Einfügen von Inhalten hinzugefügt werden, um die Unterstützung in Ihrer App zu aktivieren. Wenn in Ihrer App für einen bestimmten Anwendungsfall eine vollständige Anpassung implementiert werden muss, können Sie weiterhin die vorhandenen APIs verwenden, die weiterhin auf dieselbe Weise funktionieren.
Implementierung
Die API ist eine Listener-Schnittstelle mit einer einzigen Methode, OnReceiveContentListener
.
Für die Unterstützung älterer Versionen der Android-Plattform empfehlen wir die Verwendung der entsprechenden OnReceiveContentListener
-Schnittstelle in der AndroidX Core Library.
Wenn Sie die API verwenden möchten, implementieren Sie den Listener, indem Sie angeben, welche Arten von Inhalten Ihre App verarbeiten kann:
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/*"}; // ... }
Nachdem Sie alle von Ihrer App unterstützten Inhalts-MIME-Typen angegeben haben, implementieren Sie für den Rest des Listeners:
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; } }
Wenn Ihre App die Freigabe mit Intents bereits unterstützt, können Sie Ihre app-spezifische Logik für die Verarbeitung von Inhalts-URIs. Verbleibende Daten zurückgeben an die Verarbeitung dieser Daten an die Plattform delegieren.
Nachdem Sie den Listener implementiert haben, legen Sie ihn auf die entsprechenden UI-Elemente in Ihrer App fest:
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()); } }
URI-Berechtigungen
Leseberechtigungen werden automatisch von der Plattform für alle
content-URIs im Feld
an OnReceiveContentListener
übergebene Nutzlast.
Normalerweise verarbeitet Ihre App Inhalts-URIs in einem Dienst oder einer Aktivität. Für
lang andauernde Verarbeitung verwenden,
WorkManager Wenn Sie diese Funktion implementieren, erweitern Sie die Berechtigungen auf den Zieldienst oder die Zielaktivität, indem Sie die Inhalte mit Intent.setClipData
übergeben und das Flag FLAG_GRANT_READ_URI_PERMISSION
setzen.
Alternativ können Sie einen Hintergrundthread im aktuellen Kontext verwenden, um
um die Inhalte zu verarbeiten. In diesem Fall müssen Sie einen Verweis auf die
payload
-Objekt, das vom Listener empfangen wird, um sicherzustellen, dass Berechtigungen nicht
von der Plattform
frühzeitig widerrufen werden.
Benutzerdefinierte Ansichten
Wenn Ihre App eine benutzerdefinierte abgeleitete View
-Klasse verwendet, achten Sie darauf, dass die
OnReceiveContentListener
wird nicht umgangen.
Wenn Ihre View
-Klasse die
onCreateInputConnection
Jetpack API
InputConnectionCompat.createWrapper
um InputConnection
zu konfigurieren.
Wenn die View
-Klasse die Methode onTextContextMenuItem
überschreibt, delegieren Sie an super, wenn das Menüelement R.id.paste
oder R.id.pasteAsPlainText
ist.
Vergleich mit der Keyboard Image API
Die OnReceiveContentListener
API ist die nächste Version der bestehenden Tastaturbild-API. Diese einheitliche API unterstützt die Funktionen der Keyboard Image API sowie einige zusätzliche Funktionen. Die Kompatibilität von Geräten und Funktionen ist abhängig von
unabhängig davon, ob Sie die Jetpack-Bibliothek oder
die nativen APIs des Android SDK verwenden.
Aktion oder Funktion | Unterstützt von der Keyboard Image API | Von einheitlicher API unterstützt |
---|---|---|
Über die Tastatur einfügen | Ja (API-Level 13 und höher) | Ja (API-Level 13 und höher) |
Einfügen durch Tippen &Einfügen Menü „Halten“ | Nein | Ja |
Per Drag-and-drop einfügen | Nein | Ja (API-Level 24 und höher) |
Aktion oder Funktion | Unterstützt von der Keyboard Image API | Von einheitlicher API unterstützt |
---|---|---|
Über die Tastatur einfügen | Ja (API-Level 25 und höher) | Ja (Android 12 und höher) |
Einfügen durch Tippen &Einfügen Menü „Halten“ | Nein | |
Per Drag-and-drop einfügen | Nein |