Ricevere dati da altre app

Proprio come un'app può inviare dati ad altre app, può anche ricevere dati da altre app. Pensa a come gli utenti interagiscono con la tua applicazione e a quali tipi di dati vuoi ricevere da altre applicazioni. Ad esempio, un'applicazione di social network potrebbe essere interessata a ricevere contenuti di testo, come un URL web interessante, da un'altra app.

In un'app che utilizza Compose Navigation, la ricezione dei dati inviati da un'altra app è un processo in tre passaggi:

  1. Dichiara un <intent-filter> nel manifest: devi comunque aggiungere un filtro per intent alla tua attività nel file AndroidManifest.xml. In questo modo, il sistema operativo Android sa che la tua applicazione è in grado di ricevere azioni specifiche (come ACTION_SEND) e tipi MIME (come text/plain).

  2. Definisci un navDeepLink nel grafico di Compose Navigation: collega un navDeepLink che corrisponda all'azione e al tipo MIME direttamente alla destinazione componibile che deve visualizzare i contenuti. Il NavController intercetta automaticamente l'intent in entrata e indirizza l'utente direttamente a quella schermata.

  3. Estrai il payload dei dati in entrata: nella schermata di destinazione, accedi agli extra dell'intent (ad esempio EXTRA_TEXT o EXTRA_STREAM) per recuperare i contenuti condivisi e aggiornare lo stato dell'interfaccia utente.

I target di condivisione diretta sono deep link a un'attività specifica all'interno dell'app. Spesso rappresentano una persona o un gruppo e vengono visualizzati nell'Android Sharesheet. Ad esempio, un'app di messaggistica può fornire un target di condivisione diretta per una persona che rimanda direttamente a una conversazione con quella persona. Per istruzioni dettagliate, consulta Fornire target di condivisione diretta.

Supportare i tipi MIME

Idealmente, un'app deve essere in grado di ricevere la più ampia gamma possibile di tipi MIME. Ad esempio, un'app di messaggistica progettata per l'invio di testo, immagini e video supporta idealmente la ricezione di text/*, image/* e video/*. Ecco alcuni tipi MIME comuni per l'invio e la ricezione di dati in Android.

I destinatari si registrano per I mittenti inviano
text/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
image/*
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
Estensioni file supportate application/pdf

Consulta il registro ufficiale IANA dei tipi di media MIME.

Creare target di condivisione efficaci

Quando gli utenti toccano un target di condivisione associato a un'attività specifica, consenti loro di confermare e modificare i contenuti condivisi prima che la tua app li utilizzi. Questo è particolarmente importante per i dati di testo.

Ricevere dati nell'app

La ricezione di dati condivisi in un'app che utilizza Compose prevede la dichiarazione di filtri per intent nel manifest, l'indirizzamento degli intent in entrata alla schermata corretta con i deep link e l'estrazione del payload dall'intent per aggiornare l'interfaccia utente.

Aggiornare il manifest

I filtri per intent informano il sistema su quali intent accetta un componente dell'app. Analogamente a come hai creato un intent con un'azione ACTION_SEND nella lezione Invio di dati ad altre app, crei filtri per intent per ricevere intent con questa azione. Definisci un filtro per intent nel manifest utilizzando l'elemento <intent-filter>. Ad esempio, se la tua app gestisce la ricezione di contenuti di testo, un manifest che include una o più immagini di qualsiasi tipo avrà un aspetto simile al seguente snippet:

<activity android:name=".ui.MyActivity" android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND_MULTIPLE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>
</activity>

Quando un'altra app tenta di condividere uno di questi elementi creando un intent e passandolo a startActivity(), la tua applicazione viene elencata come opzione nell'Android Sharesheet o nel risolutore di intent. Se l'utente seleziona la tua app, viene avviata l'attività corrispondente (.ui.MyActivity nell'esempio precedente). A questo punto, devi gestire i contenuti in modo appropriato all'interno del codice e dell'interfaccia utente.

In Compose Navigation, collega un navDeepLink direttamente alla destinazione componibile che deve visualizzare i contenuti. Quando un'altra app condivide dati che corrispondono al tuo filtro per intent, Compose Navigation indirizza l'utente direttamente a questa destinazione:

Il navDeepLink corrisponde all'azione e al tipo MIME dell'intent in entrata per passare alla schermata di destinazione corretta. Una volta raggiunta la destinazione, il gestore esamina l'intent per determinare quale payload è stato ricevuto (ad esempio una singola immagine o più immagini) ed estrae gli extra corrispondenti.

Gestire i contenuti in entrata

Per recuperare i contenuti forniti da un Intent, leggi l'attività corrente da LocalActivity.current all'interno del componibile, quindi esamina l'intent per determinare l'azione successiva. Se questa attività può essere avviata da altre parti del sistema (ad esempio Avvio app), tienilo presente quando esamini l'intent.

Presta particolare attenzione al controllo dei dati in entrata: potrebbe essere impostato il tipo MIME errato o un'immagine inviata potrebbe essere estremamente grande. Elabora i dati binari o le operazioni di I/O pesanti (ad esempio la decodifica di immagini di grandi dimensioni o la scrittura di file) in modo asincrono utilizzando le coroutine (ad esempio Dispatchers.IO) anziché nel thread dell'interfaccia utente principale.

@Composable
fun SharesheetHandler() {
    val activity = LocalActivity.current
    val intent = activity?.intent

    when (intent?.action) {
        Intent.ACTION_SEND -> {
            if (intent.type == "text/plain") {
                handleSendText(intent) // Handle text being sent
            } else if (intent.type?.startsWith("image/") == true) {
                handleSendImage(intent) // Handle single image being sent
            }
        }

        Intent.ACTION_SEND_MULTIPLE -> {
            if (intent.type?.startsWith("image/") == true) {
                handleSendMultipleImages(intent) // Handle multiple images being sent
            }
        }

        else -> {
            // Handle other intents, such as being started from the home screen
        }
    }
}

private fun handleSendText(intent: Intent) {
    intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
        // Update UI state with the shared text
    }
}

private fun handleSendImage(intent: Intent) {
    val imageUri = IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java)
    imageUri?.let {
        // Update UI state with the shared image
    }
}

private fun handleSendMultipleImages(intent: Intent) {
    val imageUris =
        IntentCompat.getParcelableArrayListExtra(intent, Intent.EXTRA_STREAM, Uri::class.java)
    imageUris?.let {
        // Update UI state with the shared images
    }
}

Quando estrai dati binari o URI dagli extra dell'intent (ad esempio EXTRA_STREAM), utilizza IntentCompat.getParcelableExtra() o IntentCompat.getParcelableArrayListExtra() dalla libreria AndroidX Core, come mostrato nelle funzioni handleSendImage e handleSendMultipleImages precedenti. Android 13 (livello API 33) ha ritirato il metodo Intent.getParcelableExtra(String) senza parametri a favore di metodi type-safe che accettano il tipo di classe previsto.

L'aggiornamento dell'interfaccia utente dopo la ricezione dei dati può essere semplice come l'aggiornamento dello stato per popolare un TextField o complesso come l'applicazione di un filtro a un'immagine. La decisione su cosa accadrà dopo spetta alla tua app.

Condivisione dell'URL dello screenshot

Quando scatti uno screenshot, puoi condividere lo screenshot e qualsiasi URL associato. In questo modo, l'esperienza utente è più ricca. Quando ricevi un URL, assicurati di ottenere il campo EXTRA_TEXT dall'intent, come mostrato nell'esempio seguente:

IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java).let {
    // Handle the EXTRA_TEXT as well
    val extraText = intent.getCharSequenceExtra(Intent.EXTRA_TEXT)
    // Update UI state with the shared image and the EXTRA_TEXT if available
}

Assicurarsi che gli utenti riconoscano l'app

La tua app è rappresentata dalla sua icona e etichetta nell'Android Sharesheet e nel risolutore di intent. Entrambi sono definiti nel manifest. Puoi impostare le etichette dei filtri per attività o intent per fornire maggiori informazioni sul contesto.

A partire da Android 10 (livello API 29), Android Sharesheet utilizza solo le icone impostate nel manifest sul tag application. Android ignora le icone impostate sui tag intent-filter e activity.

Ricevere contenuti avanzati

Mentre gli intent ACTION_SEND consentono di ricevere dati dalla scheda di condivisione di Android e dal risolutore di intent a livello di attività o navigazione, le app possono anche ricevere contenuti avanzati (come immagini, video, file audio e testo con stili) tramite interazioni dirette dell'interfaccia utente. Questi meccanismi includono:

  • Incollare dagli appunti (menu tocca e tieni premuto)
  • Inserire contenuti multimediali direttamente dalla tastiera su schermo (IME), ad esempio adesivi o GIF
  • Trascinare e rilasciare contenuti da un'altra app in modalità multi-finestra o schermo diviso

Nelle interfacce utente basate su visualizzazioni, Android 12 (livello API 31) e AndroidX Core 1.7 introducono l' API OnReceiveContentListener unificata. Questo listener consolida la gestione dei contenuti dagli appunti, dalla tastiera e dal trascinamento in un singolo callback. Per istruzioni dettagliate sull'implementazione in Visualizzazioni, consulta Ricevere contenuti avanzati.

In Jetpack Compose, puoi gestire la ricezione di contenuti avanzati inseriti nei componenti dell'interfaccia utente (ad esempio i campi di testo) utilizzando il Modifier.contentReceiver modificatore o i modificatori di trascinamento.