Envoyer des données à d'autres applications

Android propose deux façons de partager des données entre les applications :

  • La fonctionnalité Android Sharesheet est principalement conçue pour envoyer du contenu en dehors de votre application ou directement à un autre utilisateur. Par exemple, partager une URL avec un ami.
  • Le résolveur d'intent Android est idéal pour transmettre des données à l'étape suivante d'une tâche bien définie. Par exemple, ouvrir un PDF à partir de votre application et laisser les utilisateurs choisir leur visionneuse préférée.

Pourquoi utiliser Android Sharesheet ?

Figure 1. La feuille de partage Android.

Utilisez Android Sharesheet pour offrir une expérience cohérente à vos utilisateurs dans toutes les applications. N'affichez pas la liste des cibles de partage de votre application et ne créez pas vos propres variantes de Sharesheet.

La feuille de partage Android permet aux utilisateurs de partager des informations avec la bonne personne, avec des suggestions d'applications pertinentes, d'un simple geste. La Sharesheet peut suggérer des cibles qui ne sont pas disponibles pour les solutions personnalisées et utilise un classement cohérent. En effet, la Sharesheet peut prendre en compte des informations sur l'activité de l'application et de l'utilisateur qui ne sont disponibles que pour le système.

Android Sharesheet propose également de nombreuses fonctionnalités pratiques pour les développeurs. Par exemple, vous pouvez effectuer les opérations suivantes :

Utiliser Android Sharesheet

Pour tous les types de partage, créez un intent et définissez son action sur Intent.ACTION_SEND. Pour afficher l'Android Sharesheet, appelez Intent.createChooser() en lui transmettant votre objet Intent. Elle renvoie une version de votre intent qui affiche toujours l'Android Sharesheet.

Envoyer du contenu textuel

L'utilisation la plus simple et la plus courante d'Android Sharesheet consiste à envoyer du contenu textuel d'une activité à une autre. Par exemple, la plupart des navigateurs peuvent partager l'URL de la page actuellement affichée sous forme de texte avec une autre application. Cela est utile pour partager un article ou un site Web avec des amis par e-mail ou sur les réseaux sociaux. Dans Jetpack Compose, récupérez le contexte actuel à l'aide de LocalContext.current et appelez context.startActivity(). Voici un exemple :

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

Vous pouvez éventuellement ajouter des extras pour inclure plus d'informations, telles que les destinataires de l'e-mail (EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC) ou l'objet de l'e-mail (EXTRA_SUBJECT).

Remarque : Certaines applications de messagerie, comme Gmail, attendent un String[] pour les extras tels que EXTRA_EMAIL et EXTRA_CC. Utilisez putExtra(String, String[]) pour les ajouter à votre intent.

Envoyer du contenu binaire

Partagez des données binaires à l'aide de l'action ACTION_SEND. Définissez le type MIME approprié et placez un URI vers les données dans l'extra EXTRA_STREAM, comme illustré dans l'exemple suivant. Cette méthode est généralement utilisée pour partager une image, mais elle peut l'être pour partager n'importe quel type de contenu binaire.

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'application de réception doit être autorisée à accéder aux données vers lesquelles pointe l'Uri. Il existe deux méthodes recommandées pour ce faire :

  • Stockez les données dans votre propre ContentProvider, en vous assurant que les autres applications disposent des autorisations appropriées pour accéder à votre fournisseur. Le mécanisme d'accès privilégié consiste à utiliser des autorisations par URI, qui sont temporaires et n'accordent l'accès qu'à l'application réceptrice. Pour créer un ContentProvider de ce type, utilisez la classe d'assistance FileProvider.
  • Utilisez le MediaStore du système. MediaStore est principalement destiné aux types MIME vidéo, audio et image. Toutefois, à partir d'Android 3.0 (niveau d'API 11), il peut également stocker des types non multimédias. Pour en savoir plus, consultez MediaStore.Files. Les fichiers peuvent être insérés dans MediaStore à l'aide de scanFile(), après quoi un Uri de style content:// adapté au partage est transmis au rappel onScanCompleted() fourni. Notez qu'une fois ajouté au système MediaStore, le contenu est accessible à n'importe quelle application de l'appareil.

Utiliser le bon type MIME

Indiquez le type MIME le plus spécifique disponible pour les données que vous envoyez. Par exemple, utilisez text/plain lorsque vous partagez du texte brut. Voici quelques types MIME courants pour l'envoi de données dans Android :

Les récepteurs s'enregistrent pour Les expéditeurs envoient
text/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
image/*
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
Extensions de fichier compatibles application/pdf

Pour déterminer le type MIME de manière dynamique au moment de l'exécution au lieu de le coder en dur, utilisez les méthodes suivantes :

Si vous ne parvenez pas à déterminer un type MIME spécifique, utilisez application/octet-stream pour les données binaires génériques ou */* en dernier recours.

Pour en savoir plus sur les types MIME, consultez le registre officiel des types de médias MIME de l'IANA.

L'Android Sharesheet peut afficher un aperçu du contenu, en fonction du type MIME fourni. Certaines fonctionnalités en preview ne sont disponibles que pour des types spécifiques.

Partager plusieurs contenus

Pour partager plusieurs éléments de contenu, utilisez l'action ACTION_SEND_MULTIPLE avec une liste d'URI pointant vers le contenu. Le type MIME varie en fonction du mélange de contenus que vous partagez. Par exemple, si vous partagez trois images JPEG, vous utilisez le type "image/jpg". Pour un mélange de types d'images, utilisez "image/*" pour qu'il corresponde à une activité qui gère n'importe quel type d'image. Bien qu'il soit possible de partager un mélange de types, évitez de le faire, car le destinataire ne sait pas exactement ce qui est censé être envoyé. Si vous devez envoyer plusieurs types, utilisez "*/*". C'est à l'application de réception d'analyser et de traiter vos données. Exemple :

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

Assurez-vous que les objets Uri fournis pointent vers des données auxquelles une application de réception peut accéder.

Ajouter du contenu enrichi aux aperçus de texte

À partir d'Android 10 (niveau d'API 29), Android Sharesheet affiche un aperçu du texte partagé. Dans certains cas, le texte partagé peut être difficile à comprendre. Imaginons que vous souhaitiez partager une URL complexe comme https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4. Un aperçu plus riche peut rassurer vos utilisateurs sur ce qui est partagé.

Si vous prévisualisez du texte, vous pouvez définir un titre, une miniature ou les deux. Ajoutez une description à Intent.EXTRA_TITLE avant d'appeler Intent.createChooser(), puis ajoutez une miniature pertinente à l'aide de ClipData.

Remarque : L'URI du contenu de l'image est fourni à partir d'un FileProvider, généralement à partir d'un <cache-path> configuré. Pour en savoir plus, consultez Partager des fichiers. Assurez-vous d'accorder à Sharesheet les autorisations appropriées pour lire l'image que vous souhaitez utiliser comme miniature. Pour en savoir plus, consultez Intent.FLAG_GRANT_READ_URI_PERMISSION.

Exemple :

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'aperçu ressemble à ceci :

Figure 2. Aperçu du contenu textuel sur l'Android Sharesheet.

Ajouter des actions personnalisées à la feuille de partage

Figure 3. Actions personnalisées sur Android Sharesheet

Sur Android 14 (niveau d'API 34) ou version ultérieure, les applications peuvent ajouter des actions personnalisées à la Sharesheet Android. Les actions personnalisées sont affichées sous forme de petites icônes d'action en haut de l'Android Sharesheet, et les applications peuvent spécifier n'importe quel Intent comme action appelée lorsque l'utilisateur clique sur l'icône.

Pour ajouter des actions personnalisées sur Android Sharesheet, commencez par créer un ChooserAction avec ChooserAction.Builder. Vous pouvez spécifier un PendingIntent comme action appelée lorsque l'utilisateur clique sur l'icône. Créez un tableau contenant toutes vos actions personnalisées et spécifiez-le en tant que EXTRA_CHOOSER_CUSTOM_ACTIONS de l'Intent de partage.

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

Ajouter des cibles personnalisées

La feuille de partage Android vous permet de spécifier jusqu'à deux intents d'activité personnalisés qui sont listés avant les suggestions d'applications à l'aide de Intent.EXTRA_INITIAL_INTENTS. Pour les cibles de partage direct (comme les conversations ou les contacts), publiez des raccourcis dynamiques à l'aide de ShortcutManagerCompat (voir Spécifier des cibles de partage direct) :

Figure 4. Cibles personnalisées sur Android Sharesheet.

Ajoutez Intent.EXTRA_INITIAL_INTENTS à votre intent de partage après l'appel de 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)

Utilisez cette fonctionnalité avec précaution. Chaque Intent personnalisé que vous ajoutez réduit le nombre de suggestions du système. En général, évitez d'ajouter des cibles personnalisées. Un exemple courant d'ajout de Intent.EXTRA_INITIAL_INTENTS consiste à fournir des actions supplémentaires que les utilisateurs peuvent effectuer sur le contenu partagé. Par exemple, un utilisateur partage des images et Intent.EXTRA_INITIAL_INTENTS est utilisé pour lui permettre d'envoyer un lien à la place.

Exclure des cibles spécifiques par composant

Vous pouvez exclure des cibles spécifiques en fournissant Intent.EXTRA_EXCLUDE_COMPONENTS. Ne le faites que pour supprimer des cibles que vous contrôlez. Un cas d'utilisation courant consiste à masquer les cibles de partage de votre application lorsque vos utilisateurs partagent du contenu depuis votre application, car leur intention est probablement de partager du contenu en dehors de votre application.

Ajoutez Intent.EXTRA_EXCLUDE_COMPONENTS à votre intent après avoir appelé 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)
}

Obtenir des informations sur le partage

Il peut être utile de savoir quand vos utilisateurs partagent des contenus et quelle cible ils sélectionnent. L'Android Sharesheet vous permet d'obtenir ces informations en fournissant le ComponentName des cibles que vos utilisateurs sélectionnent à l'aide d'un IntentSender.

Commencez par créer un PendingIntent pour un BroadcastReceiver et fournissez son IntentSender dans 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)
}

Recevez le rappel dans MyBroadcastReceiver et examinez 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")
}

Pour en savoir plus, consultez l'exemple de partage de plate-forme.

Utiliser le résolveur d'intent Android

Figure 5 : Le résolveur d'intent ACTION_SEND.

Le résolveur d'intent Android est particulièrement utile pour envoyer des données à une autre application dans le cadre d'un flux de tâches bien défini.

Pour utiliser le sélecteur d'intent Android, créez un intent et ajoutez des extras comme vous le feriez pour appeler l'Android Sharesheet. Toutefois, n'appelez pas Intent.createChooser().

Si plusieurs applications installées comportent des filtres correspondant à ACTION_SEND et au type MIME, le système affiche une boîte de dialogue de sélection d'application appelée résolveur d'intent, qui permet à l'utilisateur de choisir une cible de partage. Si une seule application correspond, elle s'exécute.

Voici un exemple d'utilisation du résolveur d'intent Android pour envoyer du texte :

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

En savoir plus

Pour en savoir plus sur l'envoi de données, consultez Intents et filtres d'intents.