Android offre agli utenti due modi per condividere dati tra le app:
- Android Sharesheet è progettato principalmente per l'invio di contenuti al di fuori della tua app o direttamente a un altro utente. Ad esempio, la condivisione di un URL con un amico.
- Il resolver degli intent Android è più adatto per passare i dati alla fase successiva di un'attività ben definita. Ad esempio, l'apertura di un PDF dalla tua app e la possibilità per gli utenti di scegliere il visualizzatore che preferiscono.
Perché utilizzare Android Sharesheet
Utilizza Android Sharesheet per creare coerenza per gli utenti tra le app. Non mostrare l'elenco di destinazioni di condivisione della tua app e non creare varianti di Sharesheet.
Android Sharesheet consente agli utenti di condividere informazioni con la persona giusta, con suggerimenti di app pertinenti, il tutto con un solo tocco. Lo Sharesheet può suggerire destinazioni non disponibili per le soluzioni personalizzate e utilizza un ranking coerente. Questo perché il foglio di condivisione può tenere conto delle informazioni sull'attività dell'app e dell'utente che sono disponibili solo per il sistema.
Android Sharesheet offre anche molte funzionalità utili per gli sviluppatori. Ad esempio, puoi:
- Scopri quando gli utenti completano una condivisione e dove
- Aggiungi target personalizzati e target delle app
- Fornire anteprime di contenuti RTF, a partire da Android 10 (livello API 29)
- Escludi i target corrispondenti a nomi di componenti specifici
Utilizza Android Sharesheet
Per tutti i tipi di condivisione, crea un intent e imposta la relativa azione su Intent.ACTION_SEND.
Per visualizzare Android Sharesheet, chiama
Intent.createChooser(),
passando l'oggetto Intent.
Restituisce una versione dell'intent che mostra sempre Android Sharesheet.
Invia contenuti di testo
L'utilizzo più semplice e comune di Android Sharesheet è l'invio di contenuti di testo da un'attività a un'altra. Ad esempio, la maggior parte dei browser può condividere l'URL della pagina attualmente visualizzata come testo con un'altra app. Questa funzionalità è utile per condividere un articolo o un sito web con gli amici tramite email o social network. In Jetpack Compose, recupera il contesto corrente utilizzando LocalContext.current e chiama context.startActivity().
Ecco un esempio di come fare:
fun shareText(context: Context) { val sendIntent: Intent = Intent().apply { action = ACTION_SEND putExtra(Intent.EXTRA_TEXT, "This is my text to send.") type = "text/plain" } val shareIntent = Intent.createChooser(sendIntent, null) context.startActivity(shareIntent) }
Se vuoi, puoi aggiungere extra per includere ulteriori informazioni, come i destinatari dell'email
(EXTRA_EMAIL,
EXTRA_CC,
EXTRA_BCC)
o l'oggetto dell'email
(EXTRA_SUBJECT).
Nota: alcune app email, come Gmail, prevedono un
String[] per extra come
EXTRA_EMAIL e EXTRA_CC. Utilizza putExtra(String, String[]) per aggiungerli al tuo intent.
Invia contenuti binari
Condividi i dati binari utilizzando l'azione ACTION_SEND.
Imposta il tipo MIME appropriato e inserisci un URI per i dati nell'extra EXTRA_STREAM, come mostrato nell'esempio seguente.
Viene comunemente utilizzata per condividere un'immagine, ma può essere usata per condividere qualsiasi tipo di contenuto binario.
fun shareBinaryContent(context: Context) { val shareIntent: Intent = Intent().apply { action = ACTION_SEND // Example: content://com.google.android.apps.photos.contentprovider/... val imageUri: Uri = Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/1") putExtra(Intent.EXTRA_STREAM, imageUri) type = "image/jpeg" } context.startActivity(Intent.createChooser(shareIntent, null)) }
L'applicazione di destinazione deve avere l'autorizzazione per accedere ai dati a cui punta Uri. Esistono due modi consigliati per farlo:
- Archivia i dati nel tuo
ContentProvider, assicurandoti che altre app dispongano dell'autorizzazione corretta per accedere al tuo provider. Il meccanismo preferito per fornire l'accesso è l'utilizzo delle autorizzazioni per URI, che sono temporanee e concedono l'accesso solo all'applicazione ricevente. Per creare unContentProvidercome questo, utilizza la classe helperFileProvider. - Utilizza il sistema
MediaStore.MediaStoreè destinato principalmente ai tipi MIME di video, audio e immagini. Tuttavia, a partire da Android 3.0 (livello API 11), può memorizzare anche tipi non multimediali. Per saperne di più, consultaMediaStore.Files. I file possono essere inseriti inMediaStoreutilizzandoscanFile(), dopodiché unUriin stilecontent://adatto alla condivisione viene passato al callbackonScanCompleted()fornito. Tieni presente che, una volta aggiunti al sistemaMediaStore, i contenuti sono accessibili a qualsiasi app sul dispositivo.
Utilizza il tipo MIME corretto
Fornisci il tipo MIME più specifico disponibile per i dati che stai inviando. Ad esempio, utilizza text/plain quando condividi testo normale. Ecco alcuni tipi MIME comuni per l'invio di dati in Android:
| I destinatari si registrano | I mittenti inviano |
|---|---|
text/* |
|
image/* |
|
video/* |
|
| Estensioni dei file supportate | application/pdf |
Per determinare il tipo MIME in modo dinamico in fase di runtime anziché impostarlo come hardcoded, utilizza i seguenti metodi:
- Per gli URI
content://(come quelli forniti daFileProvideroMediaStore), chiamaContentResolver.getType(). - Per le estensioni del file, chiama
MimeTypeMap.getSingleton().getMimeTypeFromExtension(). - Se utilizzi Storage Access Framework, puoi anche eseguire query su
DocumentFile.getType().
Se non riesci a determinare un tipo MIME specifico, utilizza application/octet-stream per i dati binari generici o */* come ultima risorsa.
Per saperne di più sui tipi MIME, consulta il registro ufficiale dei tipi di media MIME di IANA.
Android Sharesheet potrebbe mostrare un'anteprima dei contenuti, a seconda del tipo MIME fornito. Alcune funzionalità in anteprima sono disponibili solo per tipi specifici.
Condividi più contenuti
Per condividere più contenuti, utilizza l'azione ACTION_SEND_MULTIPLE insieme a un elenco di URI che rimandano ai contenuti. Il tipo MIME varia in base alla combinazione di contenuti che stai condividendo. Ad esempio, se condividi tre immagini JPEG, utilizzi il tipo "image/jpg". Per una combinazione di tipi di immagini, utilizza "image/*" per trovare un'attività che gestisce qualsiasi tipo di immagine. Sebbene sia possibile condividere un mix di tipi, evita di farlo, perché non è chiaro al destinatario cosa si intende inviare. Se è necessario inviare più tipi, utilizza "*/*". Spetta all'applicazione di destinazione analizzare ed elaborare i dati. Ecco un esempio:
fun shareMultiple(context: Context) { val imageUris: ArrayList<Uri> = arrayListOf( Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/1"), Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/2") ) val shareIntent = Intent().apply { action = Intent.ACTION_SEND_MULTIPLE putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris) type = "image/*" } context.startActivity(Intent.createChooser(shareIntent, null)) }
Assicurati che gli oggetti Uri forniti puntino a dati a cui un'applicazione di destinazione può accedere.
Aggiungi contenuti avanzati alle anteprime di testo
A partire da Android 10 (livello API 29), Android Sharesheet mostra un'anteprima del testo condiviso. In alcuni casi, il testo condiviso può essere difficile da comprendere. Ad esempio, se condividi un URL complicato come https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4, Un'anteprima più completa può rassicurare gli utenti su ciò che viene condiviso.
Se visualizzi l'anteprima del testo, puoi impostare un titolo, un'immagine in miniatura o entrambi. Aggiungi una descrizione a Intent.EXTRA_TITLE prima di chiamare Intent.createChooser() e aggiungi una miniatura pertinente utilizzando ClipData.
Nota: l'URI contenuto dell'immagine viene fornito da un FileProvider, di solito da un <cache-path> configurato.
Per ulteriori informazioni, consulta Condivisione di file. Assicurati di concedere
al Sharesheet le autorizzazioni corrette per leggere qualsiasi immagine che vuoi utilizzare come miniatura. Per saperne di più, consulta Intent.FLAG_GRANT_READ_URI_PERMISSION.
Ecco un esempio:
fun richContentToTextPreviewShares(context: Context) { val share = Intent.createChooser( Intent().apply { action = ACTION_SEND putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/") // (Optional) Here you're setting the title of the content putExtra(Intent.EXTRA_TITLE, "Introducing content previews") // (Optional) Here you're passing a content URI to an image to be displayed data = Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/A123456789") flags = Intent.FLAG_GRANT_READ_URI_PERMISSION }, null ) context.startActivity(share) }
L'anteprima ha il seguente aspetto:
Aggiungi azioni personalizzate al foglio di condivisione
Su Android 14 (livello API 34) e versioni successive, le app possono aggiungere azioni personalizzate ad Android Sharesheet.
Le azioni personalizzate vengono visualizzate come piccole icone di azione nella parte superiore di Android Sharesheet e le app possono specificare qualsiasi Intent come azione richiamata quando si fa clic sull'icona.
Per aggiungere azioni personalizzate ad Android Sharesheet, crea prima un
ChooserAction con ChooserAction.Builder.
Puoi specificare un PendingIntent come azione richiamata quando si fa clic sull'icona. Crea un array contenente tutte le tue azioni personalizzate e specificalo come EXTRA_CHOOSER_CUSTOM_ACTIONS della condivisione Intent.
fun sharesheetCustomActions(context: Context, previewText: String) { val sendIntent = Intent(ACTION_SEND) .setType("text/plain") .putExtra(Intent.EXTRA_TEXT, previewText) val shareIntent = Intent.createChooser(sendIntent, null) val customActions = arrayOf( ChooserAction.Builder( Icon.createWithResource(context, R.drawable.ic_logo), "Custom", PendingIntent.getBroadcast( context, 1, Intent(Intent.ACTION_VIEW), PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT ) ).build() ) shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions) context.startActivity(shareIntent) }
Aggiungi target personalizzati
Android Sharesheet ti consente di specificare fino a due intent di attività personalizzati che vengono elencati prima dei suggerimenti di app utilizzando Intent.EXTRA_INITIAL_INTENTS.
Per i target di condivisione diretta (come conversazioni o contatti), pubblica scorciatoie dinamiche utilizzando
ShortcutManagerCompat
(consulta Fornisci target di condivisione diretta):
Aggiungi Intent.EXTRA_INITIAL_INTENTS all'intent di condivisione dopo aver chiamato Intent.createChooser():
val sendIntent = Intent(ACTION_SEND).apply { type = "text/plain" putExtra(Intent.EXTRA_TEXT, previewText) } val customIntent = Intent().apply { component = ComponentName(context.packageName, "${context.packageName}.CustomActivity") } val shareIntent = Intent.createChooser(sendIntent, null).apply { putExtra( Intent.EXTRA_INITIAL_INTENTS, arrayOf(customIntent) ) } context.startActivity(shareIntent)
Utilizza questa funzionalità con attenzione. Ogni Intent personalizzato che aggiungi riduce il numero di quelli suggeriti dal sistema. In generale, evita di aggiungere target personalizzati. Un esempio comune e appropriato di aggiunta di Intent.EXTRA_INITIAL_INTENTS è fornire azioni aggiuntive che gli utenti possono eseguire sui contenuti condivisi. Ad esempio, un utente condivide immagini e viene utilizzato Intent.EXTRA_INITIAL_INTENTS per consentirgli di inviare un link.
Escludi target specifici per componente
Puoi escludere target specifici fornendo Intent.EXTRA_EXCLUDE_COMPONENTS.
Esegui questa operazione solo per rimuovere i target su cui hai il controllo. Un caso d'uso comune è nascondere i target di condivisione della tua app quando gli utenti condividono contenuti dall'interno dell'app, poiché la loro intenzione è probabilmente quella di condividere contenuti all'esterno dell'app.
Aggiungi Intent.EXTRA_EXCLUDE_COMPONENTS all'intent dopo aver chiamato Intent.createChooser():
fun excludeSpecificTargets(context: Context) { val share = Intent.createChooser(Intent(ACTION_SEND), null).apply { // Only use for components you have control over val excludedComponentNames = arrayOf(ComponentName("com.example.android", "ExampleClass")) putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames) } context.startActivity(share) }
Ricevi informazioni sulla condivisione
Può essere utile sapere quando gli utenti condividono e quale target selezionano. Android Sharesheet ti consente di ottenere queste informazioni fornendo il ComponentName dei target selezionati dagli utenti utilizzando un IntentSender.
Innanzitutto, crea un PendingIntent per un BroadcastReceiver e fornisci il relativo IntentSender in Intent.createChooser():
fun infoAboutSharing(context: Context, requestCode: Int) { var share = Intent(ACTION_SEND) // ... val pi = PendingIntent.getBroadcast( context, requestCode, Intent(context, ShareBroadcastReceiver::class.java), PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) share = Intent.createChooser(share, null, pi.intentSender) context.startActivity(share) }
Ricevi il callback in MyBroadcastReceiver e cerca in Intent.EXTRA_CHOOSER_RESULT:
override fun onReceive(context: Context?, intent: Intent) { val TAG = ShareBroadcastReceiver::class.simpleName val chooserResult: ChooserResult? = IntentCompat.getParcelableExtra( intent, Intent.EXTRA_CHOOSER_RESULT, ChooserResult::class.java, ) chooserResult?.let { Log.i(TAG, "Share callback: isShortcut: ${it.isShortcut}, type: ${typeToString(it.type)}, componentName: ${it.selectedComponent}", ) } ?: Log.i(TAG, "chooserResult is null") }
Per saperne di più, consulta l'esempio di condivisione della piattaforma.
Utilizza l'intent resolver di Android
ACTION_SEND.Il resolver degli intent Android è ideale per l'invio di dati a un'altra app nell'ambito di un flusso di attività ben definito.
Per utilizzare il resolver di intent Android, crea un intent e aggiungi gli extra come faresti per chiamare Android Sharesheet. Tuttavia, non chiamare
Intent.createChooser().
Se sono installate più applicazioni con filtri che corrispondono a
ACTION_SEND
e al tipo MIME, il sistema visualizza una finestra di dialogo di disambiguazione chiamata risolutore di intent
che consente all'utente di scegliere un target con cui condividere. Se una singola applicazione corrisponde, viene eseguita.
Ecco un esempio di come utilizzare il resolver degli intent Android per inviare testo:
fun intentResolver(context: Context) { val sendIntent: Intent = Intent().apply { action = ACTION_SEND putExtra(Intent.EXTRA_TEXT, "This is my text to send.") type = "text/plain" } context.startActivity(sendIntent) }
Scopri di più
Per saperne di più sull'invio di dati, consulta Intent e filtri per intent.