Daten von anderen Apps empfangen

Genauso 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 erhalten möchten. Eine Anwendung für soziale Netzwerke könnte beispielsweise daran interessiert sein, Textinhalte wie eine interessante Web-URL von einer anderen App zu erhalten.

In einer App, die Compose Navigation verwendet, werden Daten, die von einer anderen App gesendet wurden, in drei Schritten empfangen:

  1. <intent-filter> im Manifest deklarieren: Sie müssen Ihrer Aktivität in der Datei AndroidManifest.xml 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. Definiere einen navDeepLink in deinem Compose Navigation-Diagramm: Hänge einen navDeepLink, der der Aktion und dem MIME-Typ entspricht, direkt an das zusammensetzbare Ziel an, das den Inhalt anzeigen soll. Der NavController fängt den eingehenden Intent automatisch ab und leitet den Nutzer direkt zu diesem Bildschirm weiter.

  3. Eingehende Datennutzlast extrahieren: Greifen Sie auf dem Zielbildschirm auf die Intent-Extras (z. B. EXTRA_TEXT oder EXTRA_STREAM) zu, um die geteilten 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-Sharesheet angezeigt. Beispielsweise kann eine Messaging-App ein Direktfreigabeziel für eine Person bereitstellen, das direkt mit einer Unterhaltung mit dieser Person verknüpft ist. Eine ausführliche Anleitung finden Sie unter Ziele für Direct Share angeben.

Unterstützte MIME-Typen

Idealerweise sollte eine App möglichst viele MIME-Typen empfangen können. Eine Messaging-App, die für das Senden von Text, Bildern und Videos entwickelt wurde, sollte beispielsweise 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

Weitere Informationen finden Sie im offiziellen IANA-Register für MIME-Medientypen.

Gute Freigabeziele erstellen

Wenn Nutzer auf ein Freigabeziel tippen, das mit einer bestimmten Aktivität verknüpft ist, sollten sie die freigegebenen Inhalte bestätigen und bearbeiten können, bevor sie von Ihrer App verwendet werden. Dies ist besonders wichtig für Textdaten.

Daten in Ihrer App empfangen

Wenn Sie freigegebene Daten in einer App mit Compose empfangen möchten, 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 Benutzeroberfläche 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 Element <intent-filter>. Wenn deine App beispielsweise Textinhalte empfängt, sieht ein Manifest, das ein oder mehrere Bilder eines 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 zu teilen, indem sie einen Intent erstellt und an startActivity() übergibt, wird deine App als Option im Android-Sharesheet oder Intent-Resolver aufgeführt. Wenn der Nutzer deine App auswählt, wird die entsprechende Aktivität gestartet (.ui.MyActivity im vorherigen Beispiel). Es liegt dann an Ihnen, die Inhalte in Ihrem Code und Ihrer Benutzeroberfläche entsprechend zu verarbeiten.

In Compose Navigation hängst du einen navDeepLink direkt an das zusammensetzbare Ziel an, das den Inhalt anzeigen soll. Wenn eine andere App Daten teilt, die mit Ihrem Intent-Filter übereinstimmen, leitet Compose Navigation den Nutzer direkt zu diesem Ziel weiter:

Die navDeepLink gleicht die Aktion und den MIME-Typ des eingehenden Intents ab, um zum richtigen Zielbildschirm zu navigieren. Am Zielort prüft der Handler den Intent, um festzustellen, welche Nutzlast empfangen wurde (z. B. ein einzelnes Bild oder mehrere Bilder), und extrahiert die entsprechenden Extras.

Eingehende Inhalte verarbeiten

Wenn du die von einem Intent bereitgestellten Inhalte abrufen möchtest, lies die aktuelle Aktivität aus LocalActivity.current in deiner zusammensetzbaren Funktion und prüfe dann den Intent, um zu entscheiden, was als Nächstes zu tun ist. Wenn diese Aktivität von anderen Teilen des Systems (z. B. dem Launcher) gestartet werden kann, berücksichtige dies bei der Prüfung des Intents.

Achten Sie besonders darauf, eingehende Daten zu prüfen: Möglicherweise ist der falsche MIME-Typ festgelegt oder ein gesendetes Bild ist extrem groß. Verarbeite Binärdaten oder umfangreiche E/A-Vorgänge (z. B. das Decodieren großer Bilder oder das Schreiben von Dateien) asynchron mit Koroutinen (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
    }
}

Wenn Sie Binärdaten oder URIs aus Intent-Extras (z. B. EXTRA_STREAM) extrahieren, 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.

Die Aktualisierung der Benutzeroberfläche nach dem Empfang der Daten kann so einfach sein wie die Aktualisierung des Status, um eine TextField zu füllen, oder so komplex wie die Anwendung eines Filters auf ein Bild. Was als Nächstes passiert, hängt von Ihrer App ab.

Screenshot-URL-Freigabe

Wenn Sie einen Screenshot erstellen, können Sie ihn und alle zugehörigen URLs teilen. So können Sie die Nutzerfreundlichkeit verbessern. Wenn Sie eine URL erhalten, rufen Sie das Feld EXTRA_TEXT aus dem Intent ab, 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-Sharesheet und im Intent-Resolver durch ihr Symbol und ihr Label dargestellt. Beide sind im Manifest definiert. Sie können Aktivitäts- oder Intent-Filterlabels festlegen, um mehr Kontext bereitzustellen.

Ab Android 10 (API-Level 29) werden im Android-Sharesheet nur Symbole verwendet, die im Manifest im application-Tag 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 vom Android-Sharesheet und Intent-Resolver auf Aktivitäts- oder Navigationsebene empfangen werden. Apps können aber auch Rich Content wie Bilder, Videos, Audiodateien und formatierten Text über direkte UI-Interaktionen empfangen. Zu diesen Mechanismen gehören:

  • Aus der Zwischenablage einfügen (Menü „Berühren & halten“)
  • Medien wie Sticker oder GIFs direkt über die Softwaretastatur (IME) einfügen
  • Inhalte aus einer anderen App im Multi-Fenster- oder Splitscreen-Modus per Drag & Drop verschieben

In ansichtsbasierten Benutzeroberflächen werden mit Android 12 (API-Level 31) und AndroidX Core 1.7 die einheitliche OnReceiveContentListener API eingeführt. Dieser Listener fasst die Verarbeitung von Inhalten aus der Zwischenablage, der Tastatur und Drag-and-drop in einem einzigen Callback zusammen. Eine ausführliche Anleitung zur Implementierung in Ansichten finden Sie unter Rich Content empfangen.

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