Daten an andere Apps senden

Android bietet Nutzern zwei Möglichkeiten, Daten zwischen Apps zu teilen:

  • Das Android-Freigabeblatt ist in erster Linie dafür gedacht, Inhalte außerhalb Ihrer App oder direkt an einen anderen Nutzer zu senden. Beispiel: Eine URL mit einem Freund teilen.
  • Der Android-Intent-Resolver eignet sich am besten, um Daten an die nächste Phase einer genau definierten Aufgabe zu übergeben. Beispiel: Eine PDF-Datei aus Ihrer App öffnen und Nutzer ihren bevorzugten Viewer auswählen lassen.

Warum das Android-Freigabeblatt verwenden?

Abbildung 1 Das Android-Freigabeblatt

Verwenden Sie das Android-Freigabeblatt, um für Ihre Nutzer eine einheitliche Erfahrung in allen Apps zu schaffen. Zeigen Sie nicht die eigene Liste der Freigabeziele Ihrer App an und erstellen Sie keine eigenen Sharesheet-Varianten.

Mit dem Android-Freigabeblatt können Nutzer Informationen mit der richtigen Person teilen und erhalten relevante App-Vorschläge – alles mit einem einzigen Tippen. Das Sharesheet kann Ziele vorschlagen, die für benutzerdefinierte Lösungen nicht verfügbar sind, und verwendet eine einheitliche Rangfolge. Das liegt daran, dass das Freigabeblatt Informationen zu App- und Nutzeraktivitäten berücksichtigen kann, die nur dem System zur Verfügung stehen.

Das Android-Freigabeblatt bietet auch viele praktische Funktionen für Entwickler. Beispielsweise können Sie Folgendes tun:

Das Android-Freigabeblatt verwenden

Erstellen Sie für alle Arten der Freigabe einen Intent und legen Sie die Aktion auf Intent.ACTION_SEND fest. Rufen Sie Intent.createChooser(), auf und übergeben Sie das Intent Objekt, um das Android-Freigabeblatt anzuzeigen. Dadurch wird eine Version Ihres Intents zurückgegeben, in der immer das Android-Freigabeblatt angezeigt wird.

Textinhalte senden

Die einfachste und häufigste Verwendung des Android-Freigabeblatts ist das Senden von Textinhalten von einer Aktivität zu einer anderen. Die meisten Browser können beispielsweise die URL der aktuell angezeigten Seite als Text mit einer anderen App teilen. Das ist nützlich, um einen Artikel oder eine Website per E-Mail oder über soziale Netzwerke mit Freunden zu teilen. Rufen Sie in Jetpack Compose den aktuellen Kontext mit LocalContext.current ab und rufen Sie context.startActivity() auf. Hier ein Beispiel:

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

Optional können Sie Extras hinzufügen, um weitere Informationen wie E-Mail-Empfänger (EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC) oder den E-Mail-Betreff (EXTRA_SUBJECT) einzufügen.

Hinweis:Einige E-Mail-Apps wie Gmail erwarten für Extras wie EXTRA_EMAIL und EXTRA_CC ein String[]. Verwenden Sie putExtra(String, String[]), um diese Ihrem Intent hinzuzufügen.

Binäre Inhalte senden

Teilen Sie binäre Daten mit der Aktion ACTION_SEND. Legen Sie den entsprechenden MIME-Typ fest und platzieren Sie einen URI zu den Daten im Extra EXTRA_STREAM, wie im folgenden Beispiel gezeigt. Dies wird häufig verwendet, um ein Bild zu teilen, kann aber auch für jede Art von binären Inhalten verwendet werden.

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

Die empfangende Anwendung benötigt die Berechtigung, auf die Daten zuzugreifen, auf die der Uri verweist. Es gibt zwei empfohlene Möglichkeiten:

  • Speichern Sie die Daten in Ihrem eigenen ContentProvider und achten Sie darauf, dass andere Apps die richtige Berechtigung haben, auf Ihren Provider zuzugreifen. Der bevorzugte Mechanismus für die Bereitstellung des Zugriffs sind Berechtigungen pro URI, die temporär sind und nur der empfangenden Anwendung Zugriff gewähren. Verwenden Sie die Hilfsklasse FileProvider, um einen solchen ContentProvider zu erstellen.
  • Verwenden Sie den System-MediaStore. Der MediaStore ist in erster Linie für Video-, Audio- und Bild-MIME-Typen vorgesehen. Ab Android 3.0 (API-Level 11) können jedoch auch Nicht-Medientypen gespeichert werden. Weitere Informationen finden Sie unter MediaStore.Files. Dateien können mit scanFile() in den MediaStore eingefügt werden. Anschließend wird ein content://-ähnlicher Uri übergeben, der für die Freigabe geeignet ist, an den bereitgestellten onScanCompleted()-Callback. Sobald die Inhalte dem System-MediaStore hinzugefügt wurden, sind sie für jede App auf dem Gerät zugänglich.

Den richtigen MIME-Typ verwenden

Geben Sie den spezifischsten MIME-Typ an, der für die von Ihnen gesendeten Daten verfügbar ist. Verwenden Sie beispielsweise text/plain, wenn Sie Nur-Text teilen. Hier sind einige gängige MIME-Typen für das Senden von Daten in Android:

Empfänger registrieren sich für Absender senden
text/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
image/*
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
Unterstützte Dateiendungen application/pdf

Wenn Sie den MIME-Typ dynamisch zur Laufzeit bestimmen möchten, anstatt ihn fest zu codieren, verwenden Sie die folgenden Methoden:

Wenn Sie keinen bestimmten MIME-Typ ermitteln können, verwenden Sie application/octet-stream für generische binäre Daten oder als letzten Ausweg */*.

Weitere Informationen zu MIME-Typen finden Sie im IANA offiziellen Register der MIME-Medientypen.

Je nach angegebenem MIME-Typ wird im Android-Freigabeblatt möglicherweise eine Vorschau des Inhalts angezeigt. Einige Vorschaufunktionen sind nur für bestimmte Typen verfügbar.

Mehrere Inhalte teilen

Verwenden Sie die Aktion ACTION_SEND_MULTIPLE zusammen mit einer Liste von URIs, die auf die Inhalte verweisen, um mehrere Inhalte zu teilen. Der MIME-Typ variiert je nach Art der Inhalte, die Sie teilen. Wenn Sie beispielsweise drei JPEG-Bilder teilen, verwenden Sie den Typ "image/jpg". Verwenden Sie für eine Mischung aus Bildtypen "image/*", um eine Aktivität zu finden, die alle Arten von Bildern verarbeitet. Es ist zwar möglich, eine Mischung aus Typen zu teilen, aber Sie sollten dies vermeiden, da der Empfänger nicht weiß, was gesendet werden soll. Wenn Sie mehrere Typen senden müssen, verwenden Sie "*/*". Es liegt an der empfangenden Anwendung, Ihre Daten zu parsen und zu verarbeiten. Hier ein Beispiel:

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

Achten Sie darauf, dass die angegebenen Uri-Objekte auf Daten verweisen, auf die eine empfangende Anwendung zugreifen kann.

Textvorschauen Rich-Content hinzufügen

Ab Android 10 (API-Level 29) wird im Android-Freigabeblatt eine Vorschau des geteilten Texts angezeigt. In einigen Fällen ist der geteilte Text schwer zu verstehen. Beispiel: Eine komplizierte URL wie https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4. Eine umfassendere Vorschau kann Nutzern versichern, was geteilt wird.

Wenn Sie eine Vorschau des Texts anzeigen, können Sie einen Titel, ein Miniaturbild oder beides festlegen. Fügen Sie Intent.EXTRA_TITLE eine Beschreibung hinzu, bevor Sie Intent.createChooser() aufrufen, und fügen Sie mit ClipData ein relevantes Miniaturbild hinzu.

Hinweis: Der URI des Bildinhalts wird von einem FileProvider, in der Regel von einem konfigurierten <cache-path> bereitgestellt. Weitere Informationen finden Sie unter Dateien freigeben. Geben Sie dem Sharesheet die richtigen Berechtigungen, um alle Bilder zu lesen, die Sie als Miniaturbild verwenden möchten. Weitere Informationen finden Sie unter Intent.FLAG_GRANT_READ_URI_PERMISSION.

Hier ein Beispiel:

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

Die Vorschau sieht ungefähr so aus:

Abbildung 2. Vorschau von Textinhalten im Android-Freigabeblatt

Dem Freigabeblatt benutzerdefinierte Aktionen hinzufügen

Abbildung 3. Benutzerdefinierte Aktionen im Android-Freigabeblatt

Unter Android 14 (API-Level 34) und höher können Apps dem Android-Freigabeblatt benutzerdefinierte Aktionen hinzufügen. Die benutzerdefinierten Aktionen werden als kleine Aktionssymbole oben im Android-Freigabeblatt angezeigt. Apps können jeden Intent als Aktion angeben, die aufgerufen wird, wenn auf das Symbol geklickt wird.

Erstellen Sie zuerst eine ChooserAction mit ChooserAction.Builder, um dem Android-Freigabeblatt benutzerdefinierte Aktionen hinzuzufügen. Sie können einen PendingIntent als Aktion angeben, die aufgerufen wird, wenn auf das Symbol geklickt wird. Erstellen Sie ein Array mit allen benutzerdefinierten Aktionen und geben Sie es als EXTRA_CHOOSER_CUSTOM_ACTIONS des Freigabe-Intent an.

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

Benutzerdefinierte Ziele hinzufügen

Mit dem Android-Freigabeblatt können Sie mit Intent.EXTRA_INITIAL_INTENTS bis zu zwei benutzerdefinierte Aktivitäts-Intents angeben, die vor den App-Vorschlägen aufgeführt werden. Veröffentlichen Sie für Ziele für die direkte Freigabe (z. B. Unterhaltungen oder Kontakte) stattdessen dynamische Verknüpfungen mit ShortcutManagerCompat (siehe Ziele für die direkte Freigabe bereitstellen):

Abbildung 4 Benutzerdefinierte Ziele im Android-Freigabeblatt

Fügen Sie Intent.EXTRA_INITIAL_INTENTS Ihrem Freigabe-Intent nachdem Sie Intent.createChooser() aufgerufen haben hinzu:

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)

Verwenden Sie diese Funktion mit Bedacht. Jeder benutzerdefinierte Intent, den Sie hinzufügen, verringert die Anzahl der vom System vorgeschlagenen Intents. Im Allgemeinen sollten Sie keine benutzerdefinierten Ziele hinzufügen. Ein häufiges Beispiel für die Verwendung von Intent.EXTRA_INITIAL_INTENTS ist die Bereitstellung zusätzlicher Aktionen, die Nutzer für geteilte Inhalte ausführen können. Beispiel: Ein Nutzer teilt Bilder und Intent.EXTRA_INITIAL_INTENTS wird verwendet, damit er stattdessen einen Link senden kann.

Bestimmte Ziele nach Komponente ausschließen

Sie können bestimmte Ziele ausschließen, indem Sie Intent.EXTRA_EXCLUDE_COMPONENTS angeben. Tun Sie dies nur, um Ziele zu entfernen, über die Sie die Kontrolle haben. Ein häufiger Anwendungsfall ist das Ausblenden der Freigabeziele Ihrer App, wenn Ihre Nutzer Inhalte aus Ihrer App heraus teilen, da sie wahrscheinlich Inhalte außerhalb Ihrer App teilen möchten.

Fügen Sie Ihrem Intent Intent.EXTRA_EXCLUDE_COMPONENTS hinzu, nachdem Sie Intent.createChooser() aufgerufen haben:

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

Informationen zur Freigabe abrufen

Es kann nützlich sein zu wissen, wann Ihre Nutzer Inhalte teilen und welches Ziel sie auswählen. Mit dem Android-Freigabeblatt können Sie diese Informationen abrufen, indem Sie den ComponentName der Ziele angeben, die Ihre Nutzer mit einem IntentSender auswählen.

Erstellen Sie zuerst einen PendingIntent für einen BroadcastReceiver und geben Sie den IntentSender in Intent.createChooser() an:

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

Empfangen Sie den Callback in MyBroadcastReceiver und suchen Sie 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")
}

Weitere Informationen finden Sie im Beispiel für die Plattformfreigabe.

Den Android-Intent-Resolver verwenden

Abbildung 5 Der ACTION_SEND-Intent-Resolver

Der Android-Intent-Resolver eignet sich am besten, um Daten im Rahmen eines genau definierten Aufgabenablaufs an eine andere App zu senden.

Erstellen Sie einen Intent und fügen Sie Extras hinzu, wie Sie es tun würden, um das Android-Freigabeblatt aufzurufen. Rufen Sie jedoch nicht auf Intent.createChooser().

Wenn mehrere installierte Anwendungen mit Filtern vorhanden sind, die mit ACTION_SEND und dem MIME-Typ übereinstimmen, zeigt das System ein Dialogfeld zur Mehrdeutigkeitsauflösung an, das als Intent-Resolver bezeichnet wird. Dort kann der Nutzer ein Ziel für die Freigabe auswählen. Wenn nur eine Anwendung übereinstimmt, wird sie ausgeführt.

Hier ein Beispiel für die Verwendung des Android-Intent-Resolvers zum Senden von Text:

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

Weitere Informationen

Weitere Informationen zum Senden von Daten finden Sie unter Intents und Intent-Filter.