Daten von anderen Apps empfangen

So wie eine App Daten an andere Apps senden kann, kann sie auch Daten von anderen Apps empfangen. Überlegen Sie, wie Nutzer mit Ihrer Anwendung interagieren und welche Datentypen Sie von anderen Anwendungen empfangen möchten. Eine Social-Networking-Anwendung könnte beispielsweise Textinhalte wie eine interessante Web-URL von einer anderen App empfangen wollen.

In einer App mit Compose Navigation ist der Empfang von Daten, die von einer anderen App gesendet werden, ein dreistufiger Prozess:

  1. Deklarieren Sie einen <intent-filter> im Manifest: Sie müssen Ihrer Aktivität in der AndroidManifest.xml Datei weiterhin einen Intent Filter hinzufügen. Dadurch wird dem Android-Betriebssystem mitgeteilt, dass Ihre Anwendung bestimmte Aktionen (z. B. ACTION_SEND) und MIME-Typen (z. B. text/plain) empfangen kann.

  2. Definieren Sie einen navDeepLink in Ihrem Compose Navigation-Diagramm: Fügen Sie der zusammensetzbaren Zieladresse, in der der Inhalt angezeigt werden soll, direkt einen navDeepLink hinzu, der mit der Aktion und dem MIME-Typ übereinstimmt. Der NavController fängt den eingehenden Intent automatisch ab und leitet den Nutzer direkt zu diesem Bildschirm weiter.

  3. Extrahieren Sie die eingehende Daten-Payload: Greifen Sie auf dem Zielbildschirm auf die Intent-Extras zu (z. B. EXTRA_TEXT oder EXTRA_STREAM), um die freigegebenen Inhalte abzurufen und den UI-Status zu aktualisieren.

„Direct Share“-Ziele sind Deeplinks zu einer bestimmten Aktivität in Ihrer App. Sie stellen oft eine Person oder eine Gruppe dar und werden im Android-Freigabeblatt angezeigt. Eine Messaging-App kann beispielsweise ein „Direct Share“-Ziel für eine Person bereitstellen, das direkt zu einer Unterhaltung mit dieser Person verlinkt. Eine ausführliche Anleitung finden Sie unter „Direct Share“-Ziele bereitstellen.

MIME-Typen unterstützen

Im Idealfall muss eine App eine möglichst große Bandbreite an MIME-Typen empfangen können. Eine Messaging-App, die zum Senden von Text, Bildern und Videos entwickelt wurde, sollte idealerweise den Empfang von text/*, image/* und video/* unterstützen. Hier sind einige gängige MIME-Typen zum Senden und Empfangen 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

Offizielle IANA-Registrierung von MIME-Medientypen

Gute Freigabeziele erstellen

Wenn Nutzer auf ein Freigabeziel tippen, das mit einer bestimmten Aktivität verknüpft ist, lassen Sie sie die freigegebenen Inhalte bestätigen und bearbeiten, bevor Ihre App sie verwendet. Das ist besonders wichtig für Textdaten.

Daten in Ihrer App empfangen

Um weitergegebene Daten in einer App mit Compose zu empfangen, müssen Sie Intent-Filter in Ihrem Manifest deklarieren, eingehende Intents mit Deeplinks an den richtigen Bildschirm weiterleiten und die Nutzlast aus dem Intent extrahieren, um die UI zu aktualisieren.

Manifest aktualisieren

Intent-Filter informieren das System darüber, welche Intents eine App-Komponente akzeptiert. Ähnlich wie beim Erstellen eines Intents mit einer ACTION_SEND Aktion in der Lektion Daten an andere Apps senden erstellen Sie Intent-Filter, um Intents mit dieser Aktion zu empfangen. Sie definieren einen Intent-Filter in Ihrem Manifest mit dem <intent-filter> Element. Wenn Ihre App beispielsweise Textinhalte empfangen kann, sieht ein Manifest, das ein oder mehrere Bilder beliebigen Typs enthält, so aus:

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

Wenn eine andere App versucht, eines dieser Elemente freizugeben, indem sie einen Intent erstellt und ihn an startActivity() übergibt, wird Ihre Anwendung im Android-Freigabeblatt oder in der Intent-Auflösung als Option aufgeführt. Wenn der Nutzer Ihre App auswählt, wird die entsprechende Aktivität gestartet (.ui.MyActivity im vorherigen Beispiel). Anschließend müssen Sie die Inhalte in Ihrem Code und Ihrer UI entsprechend verarbeiten.

Fügen Sie in Compose Navigation der zusammensetzbaren Zieladresse, in der der Inhalt angezeigt werden soll, direkt einen navDeepLink hinzu. Wenn eine andere App weitergegebene Daten freigibt, die mit Ihrem Intent-Filter übereinstimmen, leitet Compose Navigation den Nutzer direkt zu diesem Ziel weiter:

Der navDeepLink stimmt mit der Aktion und dem MIME-Typ des eingehenden Intents überein, um zum richtigen Zielbildschirm zu navigieren. Sobald Sie sich an diesem Ziel befinden, prüft Ihr Handler den Intent, um zu ermitteln, welche Payload empfangen wurde (z. B. ein einzelnes Bild im Vergleich zu mehreren Bildern), und extrahiert die entsprechenden Extras.

Eingehende Inhalte verarbeiten

Um die Inhalte abzurufen, die von einem Intent bereitgestellt werden, lesen Sie die aktuelle Aktivität aus LocalActivity.current in Ihrer zusammensetzbaren Funktion und prüfen Sie dann den Intent, um zu ermitteln, was als Nächstes zu tun ist. Wenn diese Aktivität von anderen Teilen des Systems (z. B. dem Launcher) aus gestartet werden kann, berücksichtigen Sie dies bei der Prüfung des Intents.

Prüfen Sie eingehende Daten besonders sorgfältig: Möglicherweise ist der falsche MIME-Typ festgelegt oder ein gesendetes Bild ist extrem groß. Verarbeiten Sie Binärdaten oder umfangreiche E/A-Vorgänge (z. B. das Decodieren großer Bilder oder das Schreiben von Dateien) asynchron mit Coroutinen (z. B. Dispatchers.IO) und nicht im Haupt-UI-Thread.

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

Verwenden Sie beim Extrahieren von Binärdaten oder URIs aus Intent-Extras (z. B. EXTRA_STREAM), verwenden Sie IntentCompat.getParcelableExtra() oder IntentCompat.getParcelableArrayListExtra() aus der AndroidX Core-Bibliothek, wie in den vorherigen Funktionen handleSendImage und handleSendMultipleImages gezeigt. In Android 13 (API-Level 33) wird die nicht parametrisierte Methode Intent.getParcelableExtra(String) zugunsten typsicherer Methoden eingestellt, die den erwarteten Klassentyp verwenden.

Das Aktualisieren der UI nach dem Empfang der Daten kann so einfach sein wie das Aktualisieren von Status, um ein TextField zu füllen, oder so komplex wie das Anwenden eines Filters auf ein Bild. Was als Nächstes geschieht, hängt von Ihrer App ab.

URL-Freigabe für Screenshots

Wenn Sie einen Screenshot erstellen, können Sie ihn und alle zugehörigen URLs freigeben. Das sorgt für eine bessere Nutzererfahrung. Wenn Sie eine URL empfangen, müssen Sie das Feld EXTRA_TEXT aus dem Intent abrufen, wie im folgenden Beispiel gezeigt:

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
}

Sorgen Sie dafür, dass Nutzer Ihre App erkennen

Ihre App wird im Android-Freigabeblatt und in der Intent-Auflösung durch ihr Symbol und Label dargestellt. Beide werden im Manifest definiert. Sie können Aktivitäts- oder Intent-Filter-Labels festlegen, um mehr Kontext zu liefern.

Ab Android 10 (API-Level 29) werden im Android-Freigabeblatt nur Symbole verwendet, die im Manifest für das Tag application festgelegt sind. Android ignoriert Symbole, die für die Tags intent-filter und activity festgelegt sind.

Rich Content empfangen

Mit ACTION_SEND-Intents können Daten aus dem Android-Freigabeblatt und der Intent-Auflösung auf Aktivitäts- oder Navigationsebene empfangen werden. Apps können aber auch Rich Content (z. B. Bilder, Videos, Audiodateien und formatierter Text) durch direkte UI-Interaktionen empfangen. Zu diesen Mechanismen gehören:

  • Aus der Zwischenablage einfügen (Menü durch langes Drücken)
  • Medien direkt über die Softwaretastatur (IME) einfügen, z. B. Sticker oder GIFs
  • Inhalte im Mehrfenster- oder Splitscreen-Modus aus einer anderen App ziehen und ablegen

In View-basierten UIs wird mit Android 12 (API-Level 31) und AndroidX Core 1.7 die einheitliche OnReceiveContentListener API eingeführt. Dieser Listener fasst die Inhaltsverarbeitung aus der Zwischenablage, der Tastatur und per Drag-and-drop in einem einzigen Callback zusammen. Eine ausführliche Anleitung zur Implementierung in Views finden Sie unter Rich Content empfangen.

In Jetpack Compose können Sie den Empfang von Rich Content, der in UI Komponenten (z. B. Textfelder) eingefügt wird, mit dem Modifier.contentReceiver Modifikator oder Drag-and-drop-Modifikatoren verarbeiten.