Gli utenti amano immagini, video e altri contenuti espressivi, ma inserendo e spostare questi contenuti nelle app non è sempre facile. Per semplificare la gestione delle ricevere contenuti avanzati, Android 12 (livello API 31) introduce un'API unificata che consente alla tua app di accettare contenuti da qualsiasi origine: appunti, tastiera o trascinamento.
Puoi collegare un'interfaccia, ad esempio
OnReceiveContentListener
,
ai componenti dell'interfaccia utente e ricevere un callback quando il contenuto viene inserito tramite
meccanismo di attenzione. Il callback diventa l'unica posizione da gestire per il codice
ricevere tutti i contenuti, da testo normale e con stili a markup, immagini, video
file audio e altri ancora.
Per la compatibilità con le versioni precedenti di Android, anche questa API disponibile su AndroidX, a partire da Core 1.7 e App compatibile 1.4, che ti consigliamo di usare quando implementi questa funzionalità.
Panoramica
Con altre API esistenti, ogni meccanismo dell'interfaccia utente, come il tocco e tieni premuto il menu o trascinamento, ha la propria API corrispondente. Ciò significa che devi si integrano con ogni API separatamente, aggiungendo codice simile per ogni meccanismo che inserisce contenuto:
L'API OnReceiveContentListener
consolida questi diversi percorsi di codice in
creando un'unica API da implementare, così potrai concentrarti sulla logica specifica dell'app
e lasciare che sia la piattaforma a occuparsi del resto:
Questo approccio implica anche che, quando vengono aggiunti nuovi modi di inserire contenuti piattaforma, non devi apportare ulteriori modifiche al codice per abilitare il supporto all'interno dell'app. E se la tua app deve implementare la personalizzazione completa per caso d'uso specifico, puoi comunque usare le API esistenti, che continuano allo stesso modo.
Implementazione
L'API è un'interfaccia listener con un singolo metodo,
OnReceiveContentListener
Per supportare le versioni precedenti della piattaforma Android, ti consigliamo di utilizzare
corrispondente
OnReceiveContentListener
nella libreria AndroidX Core.
Per utilizzare l'API, implementa il listener specificando i tipi di contenuti che l'app è in grado di gestire:
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/*"}; // ... }
Dopo aver specificato tutti i tipi MIME di contenuti supportati dall'app, implementa il resto di chi ascolta:
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; } }
Se la tua app supporta già la condivisione con intent, puoi riutilizzare i tuoi logica specifica dell'app per la gestione degli URI dei contenuti. Restituisci tutti i dati rimanenti a delega la gestione di questi dati alla piattaforma.
Dopo aver implementato il listener, impostalo sugli elementi dell'interfaccia utente appropriati in la tua app:
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()); } }
Autorizzazioni URI
Le autorizzazioni di lettura vengono concesse e rilasciate automaticamente dalla piattaforma per qualsiasi
URI contenuti nel
payload passato a OnReceiveContentListener
.
Di solito, la tua app elabora gli URI dei contenuti in un servizio o in un'attività. Per
l'elaborazione a lunga esecuzione,
WorkManager. Quando implementi
estendi le autorizzazioni al servizio o all'attività di destinazione passando il
contenuti con
Intent.setClipData
e impostando il flag
FLAG_GRANT_READ_URI_PERMISSION
.
In alternativa, puoi utilizzare un thread in background nel contesto corrente per
elaborare i contenuti. In questo caso, devi mantenere un riferimento
Oggetto payload
ricevuto dal listener per garantire che le autorizzazioni non vengano
revocati prematuramente dalla piattaforma.
Elementi View personalizzati
Se la tua app utilizza una sottoclasse View
personalizzata, assicurati che la classe
OnReceiveContentListener
non viene bypassato.
Se la tua classe View
sostituisce la
onCreateInputConnection
usa l'API Jetpack
InputConnectionCompat.createWrapper
per configurare InputConnection
.
Se la tua classe View
sostituisce la
onTextContextMenuItem
delega a super quando la voce di menu è
R.id.paste
o
R.id.pasteAsPlainText
Confronto con l'API Keyboard Image
Puoi considerare l'API OnReceiveContentListener
come la versione successiva di
API Keyboard Image esistente. Questo ha unificato
supporta la funzionalità dell'API Keyboard Image, nonché alcune
funzionalità aggiuntive. La compatibilità del dispositivo e delle funzionalità varia in base
che utilizzi la libreria Jetpack o le API native dell'SDK Android.
Azione o funzionalità | Supportato dall'API Keyboard Image | Supportato da un'API unificata |
---|---|---|
Inserisci dalla tastiera | Sì (livello API 13 e successivi) | Sì (livello API 13 e successivi) |
Inserisci usando incolla dal tocco e tieni premuto il menu | No | Sì |
Inserisci utilizzando la funzionalità di trascinamento | No | Sì (livello API 24 e successivi) |
Azione o funzionalità | Supportato dall'API Keyboard Image | Supportato da un'API unificata |
---|---|---|
Inserisci dalla tastiera | Sì (livello API 25 e successivi) | Sì (Android 12 e versioni successive) |
Inserisci usando incolla dal tocco e tieni premuto il menu | No | |
Inserisci utilizzando la funzionalità di trascinamento | No |