Teilzugriff auf Fotos und Videos gewähren

Mit Android 14 wird der Zugriff auf ausgewählte Fotos eingeführt. Damit können Nutzer Apps Zugriff auf bestimmte Bilder und Videos in ihrer Fotogalerie gewähren, anstatt Zugriff auf alle Medien eines bestimmten Typs zu gewähren.

Diese Änderung ist nur aktiviert, wenn deine App auf Android 14 (API-Level 34) oder höher ausgerichtet ist. Wenn Sie die Bildauswahl noch nicht verwenden, empfehlen wir, sie in Ihrer App zu implementieren. So können Sie Bilder und Videos einheitlich auswählen und die Privatsphäre der Nutzer verbessern, ohne Speicherberechtigungen anfordern zu müssen.

Wenn Sie eine eigene Galerieauswahl mit Speicherberechtigungen verwenden und die volle Kontrolle über Ihre Implementierung haben müssen, passen Sie Ihre Implementierung an, um die neue Berechtigung READ_MEDIA_VISUAL_USER_SELECTED zu verwenden. Wenn Ihre App die neue Berechtigung nicht verwendet, führt das System die App im Kompatibilitätsmodus aus.

Ziel-SDK READ_MEDIA_VISUAL_USER_SELECTED deklariert Zugriff auf ausgewählte Fotos aktiviert UX-Verhalten
SDK 33 Nein Nein
Ja Ja Über die App gesteuert
SDK 34 Nein Ja Vom System gesteuert (Kompatibilität)
Ja Ja Über die App gesteuert

Das Erstellen einer eigenen Galerieauswahl erfordert umfangreiche Entwicklungs- und Wartung und Ihre App muss Speicherberechtigungen anfordern, um die ausdrückliche Nutzereinwilligung einzuholen. Nutzer können diese Anfragen ablehnen oder den Zugriff auf ausgewählte Medien beschränken, wenn deine App auf einem Gerät mit Android 14 ausgeführt wird und auf Android 14 (API-Level 34) oder höher ausgerichtet ist. Die folgende Abbildung zeigt ein Beispiel für das Anfordern von Berechtigungen und das Auswählen von Medien mit den neuen Optionen.

Die
Abbildung 1: Im neuen Dialogfeld können Nutzer zusätzlich zu den üblichen Optionen zum Gewähren eines vollständigen Zugriffs oder zum Verweigern des gesamten Zugriffs bestimmte Fotos und Videos auswählen, die sie für deine App verfügbar machen möchten.

In diesem Abschnitt wird der empfohlene Ansatz zum Erstellen einer eigenen Galerieauswahl mit MediaStore gezeigt. Wenn Sie bereits eine Galerieauswahl für Ihre App verwenden und die volle Kontrolle behalten müssen, können Sie diese Beispiele zur Anpassung Ihrer Implementierung verwenden. Wenn Sie Ihre Implementierung nicht für den Zugriff auf ausgewählte Fotos aktualisieren, führt das System die App in einem Kompatibilitätsmodus aus.

Berechtigungen anfordern

Fordern Sie zuerst die korrekten Speicherberechtigungen im Android-Manifest an, je nach Betriebssystemversion:

<!-- Devices running Android 12L (API level 32) or lower  -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

<!-- Devices running Android 13 (API level 33) or higher -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

<!-- To handle the reselection within the app on devices running Android 14
     or higher if your app targets Android 14 (API level 34) or higher.  -->
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />

Fordern Sie dann die korrekten Laufzeitberechtigungen an, auch je nach Betriebssystemversion:

// Register ActivityResult handler
val requestPermissions = registerForActivityResult(RequestMultiplePermissions()) { results ->
    // Handle permission requests results
    // See the permission example in the Android platform samples: https://github.com/android/platform-samples
}

// Permission request logic
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
    requestPermissions.launch(arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_VISUAL_USER_SELECTED))
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    requestPermissions.launch(arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO))
} else {
    requestPermissions.launch(arrayOf(READ_EXTERNAL_STORAGE))
}

Einige Apps benötigen keine Berechtigungen

Ab Android 10 (API-Level 29) benötigen Apps keine Speicherberechtigungen mehr, um dem freigegebenen Speicher Dateien hinzuzufügen. Das bedeutet, dass Apps Bilder zur Galerie hinzufügen, Videos aufzeichnen und im freigegebenen Speicher speichern oder PDF-Rechnungen herunterladen können, ohne Speicherberechtigungen anfordern zu müssen. Wenn Ihre Anwendung dem freigegebenen Speicher nur Dateien hinzufügt und keine Bilder oder Videos abfragt, sollten Sie keine Speicherberechtigungen mehr anfordern und ein maxSdkVersion von API 28 in Ihrer AndroidManifest.xml festlegen:

<!-- No permission is needed to add files to shared storage on Android 10 (API level 29) or higher  -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="28" />

Neuauswahl von Medien verarbeiten

Mit der Funktion „Ausgewählter Fotozugriff“ in Android 14 sollte deine App die neue Berechtigung READ_MEDIA_VISUAL_USER_SELECTED zur Steuerung der erneuten Auswahl von Medien annehmen und die Benutzeroberfläche deiner App so aktualisieren, dass Nutzer deiner App Zugriff auf eine andere Gruppe von Bildern und Videos gewähren können. Die folgende Abbildung zeigt ein Beispiel für das Anfordern von Berechtigungen und das erneute Auswählen von Medien:

Die
Abbildung 2: Über das neue Dialogfeld können Nutzer auch noch einmal auswählen, welche Fotos und Videos in Ihrer App verfügbar sein sollen.

Beim Öffnen des Auswahldialogs werden je nach angeforderten Berechtigungen Fotos, Videos oder beides angezeigt. Wenn Sie beispielsweise die Berechtigung READ_MEDIA_VIDEO ohne die Berechtigung READ_MEDIA_IMAGES anfordern, werden auf der Benutzeroberfläche nur Videos angezeigt, über die Nutzer Dateien auswählen können.

// Allow the user to select only videos
requestPermissions.launch(arrayOf(READ_MEDIA_VIDEO, READ_MEDIA_VISUAL_USER_SELECTED))

Du kannst prüfen, ob deine App vollständigen, teilweisen oder abgelehnten Zugriff auf die Fotobibliothek des Geräts hat, und deine Benutzeroberfläche entsprechend aktualisieren. Fordern Sie diese Berechtigungen an, wenn die App Speicherzugriff benötigt, und nicht beim Start. Die Berechtigung kann zwischen den Lebenszyklus-Callbacks onStart und onResume geändert werden, da der Nutzer den Zugriff in den Einstellungen ändern kann, ohne die App zu schließen.

if (
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
    (
        ContextCompat.checkSelfPermission(context, READ_MEDIA_IMAGES) == PERMISSION_GRANTED ||
        ContextCompat.checkSelfPermission(context, READ_MEDIA_VIDEO) == PERMISSION_GRANTED
    )
) {
    // Full access on Android 13 (API level 33) or higher
} else if (
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
    ContextCompat.checkSelfPermission(context, READ_MEDIA_VISUAL_USER_SELECTED) == PERMISSION_GRANTED
) {
    // Partial access on Android 14 (API level 34) or higher
}  else if (ContextCompat.checkSelfPermission(context, READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
    // Full access up to Android 12 (API level 32)
} else {
    // Access denied
}

Gerätebibliothek abfragen

Nachdem Sie bestätigt haben, dass Sie Zugriff auf die richtigen Speicherberechtigungen haben, können Sie mit MediaStore interagieren, um die Gerätebibliothek abzufragen. Der gleiche Ansatz funktioniert unabhängig davon, ob der gewährte Zugriff teilweise oder vollständig ist:

data class Media(
    val uri: Uri,
    val name: String,
    val size: Long,
    val mimeType: String,
)

// Run the querying logic in a coroutine outside of the main thread to keep the app responsive.
// Keep in mind that this code snippet is querying only images of the shared storage.
suspend fun getImages(contentResolver: ContentResolver): List<Media> = withContext(Dispatchers.IO) {
    val projection = arrayOf(
        Images.Media._ID,
        Images.Media.DISPLAY_NAME,
        Images.Media.SIZE,
        Images.Media.MIME_TYPE,
    )

    val collectionUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        // Query all the device storage volumes instead of the primary only
        Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
    } else {
        Images.Media.EXTERNAL_CONTENT_URI
    }

    val images = mutableListOf<Media>()

    contentResolver.query(
        collectionUri,
        projection,
        null,
        null,
        "${Images.Media.DATE_ADDED} DESC"
    )?.use { cursor ->
        val idColumn = cursor.getColumnIndexOrThrow(Images.Media._ID)
        val displayNameColumn = cursor.getColumnIndexOrThrow(Images.Media.DISPLAY_NAME)
        val sizeColumn = cursor.getColumnIndexOrThrow(Images.Media.SIZE)
        val mimeTypeColumn = cursor.getColumnIndexOrThrow(Images.Media.MIME_TYPE)

        while (cursor.moveToNext()) {
            val uri = ContentUris.withAppendedId(collectionUri, cursor.getLong(idColumn))
            val name = cursor.getString(displayNameColumn)
            val size = cursor.getLong(sizeColumn)
            val mimeType = cursor.getString(mimeTypeColumn)

            val image = Media(uri, name, size, mimeType)
            images.add(image)
        }
    }

    return@withContext images
}

Dieses Code-Snippet wurde vereinfacht, um zu veranschaulichen, wie die Interaktion mit MediaStore funktioniert. Verwenden Sie in einer produktionsfertigen Anwendung die Paginierung mit Funktionen wie der Paging-Bibliothek, um eine gute Leistung zu gewährleisten.

Der Zugriff auf Fotos und Videos bleibt beim Upgrade des Geräts erhalten

Falls sich Ihre App auf einem Gerät befindet, das von einer früheren Android-Version auf Android 14 aktualisiert wird, behält das System vollen Zugriff auf die Fotos und Videos des Nutzers und gewährt Ihrer App automatisch einige Berechtigungen. Das genaue Verhalten hängt von den Berechtigungen ab, die Ihrer App gewährt werden, bevor das Gerät auf Android 14 aktualisiert wird.

Berechtigungen von Android 13

Stellen Sie sich folgende Situation vor:

  1. Deine App ist auf einem Gerät mit Android 13 installiert.
  2. Der Nutzer hat Ihrer App die Berechtigungen READ_MEDIA_IMAGES und READ_MEDIA_VIDEO gewährt.
  3. Während die App noch installiert ist, wird das Gerät auf Android 14 aktualisiert.
  4. Deine App ist ab sofort auf Android 14 (API-Level 34) oder höher ausgerichtet.

In diesem Fall hat die App weiterhin uneingeschränkten Zugriff auf die Fotos und Videos des Nutzers. Das System behält auch die Berechtigungen READ_MEDIA_IMAGES und READ_MEDIA_VIDEO bei, die Ihrer App automatisch gewährt werden.

Berechtigungen ab Android 12

Stellen Sie sich folgende Situation vor:

  1. Deine App ist auf einem Gerät mit Android 13 installiert.
  2. Der Nutzer hat Ihrer App die Berechtigung READ_EXTERNAL_STORAGE oder WRITE_EXTERNAL_STORAGE gewährt.
  3. Während die App noch installiert ist, wird das Gerät auf Android 14 aktualisiert.
  4. Deine App ist ab sofort auf Android 14 (API-Level 34) oder höher ausgerichtet.

In diesem Fall hat die App weiterhin uneingeschränkten Zugriff auf die Fotos und Videos des Nutzers. Außerdem erteilt das System Ihrer App automatisch die Berechtigungen READ_MEDIA_IMAGES und READ_MEDIA_VIDEO.

Best Practices

Dieser Abschnitt enthält mehrere Best Practices für die Verwendung der Berechtigung READ_MEDIA_VISUAL_USER_SELECTED. Weitere Informationen finden Sie in unseren Best Practices für Berechtigungen.

Berechtigungsstatus nicht dauerhaft speichern

Speichern Sie den Berechtigungsstatus nicht dauerhaft, einschließlich SharedPreferences oder DataStore. Der gespeicherte Status ist möglicherweise nicht mit dem tatsächlichen Status synchron. Der Berechtigungsstatus kann sich nach dem Zurücksetzen der Berechtigungen, dem Ruhezustand der App, einer vom Nutzer initiierten Änderung in den App-Einstellungen oder wenn die App in den Hintergrund versetzt wird, ändern. Prüfen Sie stattdessen mit ContextCompat.checkSelfPermission() nach Speicherberechtigungen.

Gehen Sie nicht davon aus, dass Sie vollen Zugriff auf Fotos und Videos haben.

Aufgrund der Änderungen in Android 14 hat deine App möglicherweise nur teilweisen Zugriff auf die Fotogalerie des Geräts. Wenn die Anwendung MediaStore-Daten im Cache speichert, wenn sie mit ContentResolver abgefragt wird, ist der Cache möglicherweise nicht aktuell.

  • Fragen Sie MediaStore immer mit ContentResolver ab, anstatt sich auf einen gespeicherten Cache zu verlassen.
  • Die Ergebnisse speichern, während die App im Vordergrund ausgeführt wird.
  • Aktualisieren Sie die Ergebnisse, wenn Ihre Anwendung den App-Lebenszyklus onResume durchläuft, da der Nutzer über die Berechtigungseinstellungen möglicherweise vom Vollzugriff zu Teilzugriff wechseln kann.

URI-Zugriff als temporär behandeln

Wenn der Nutzer im Dialogfeld für Systemberechtigungen Fotos und Videos auswählen auswählt, läuft der Zugriff Ihrer App auf die ausgewählten Fotos und Videos irgendwann ab. Ihre Anwendung sollte immer verarbeiten können, wenn sie keinen Zugriff auf Uri hat, unabhängig von ihren Befugnissen.

Auswählbaren Medientyp nach Berechtigung filtern

Im Auswahldialogfeld wird der angeforderte Berechtigungstyp berücksichtigt:

  • Wenn Sie nur READ_MEDIA_IMAGES anfordern, werden nur Bilder angezeigt, die ausgewählt werden können.
  • Wenn Sie nur READ_MEDIA_VIDEO anfordern, wird nur das Video angezeigt, das ausgewählt werden kann.
  • Wenn Sie sowohl READ_MEDIA_IMAGES als auch READ_MEDIA_VIDEO anfordern, kann die gesamte Fotobibliothek ausgewählt werden.

Sie sollten darauf achten, je nach den Anwendungsfällen Ihrer Anwendung die richtigen Berechtigungen anzufordern, um eine schlechte Nutzererfahrung zu vermeiden. Wenn für eine Funktion nur die Auswahl von Videos erwartet wird, fordern Sie nur READ_MEDIA_VIDEO an.

Berechtigungen in einem einzigen Vorgang anfordern

Damit Nutzer nicht mehrere Dialogfelder für Systemlaufzeiten sehen, fordern Sie die Berechtigungen READ_MEDIA_VISUAL_USER_SELECTED, ACCESS_MEDIA_LOCATION und „Medien lesen“ (READ_MEDIA_IMAGES, READ_MEDIA_VIDEO oder beides) in einem einzigen Vorgang an.

Nutzer dürfen ihre Auswahl verwalten

Wenn der Nutzer den Modus für den Teilzugriff auswählt, sollte Ihre App nicht davon ausgehen, dass die Fotobibliothek des Geräts leer ist, und dem Nutzer die Möglichkeit bieten, weitere Dateien zu gewähren.

Der Nutzer kann entscheiden, über die Berechtigungseinstellungen vom Vollzugriff auf den Teilzugriff zu wechseln, ohne Zugriff auf einige visuelle Mediendateien zu gewähren.

Kompatibilitätsmodus

Wenn Sie eine eigene Galerieauswahl mit Speicherberechtigungen verwenden, Ihre App aber nicht so angepasst haben, dass sie die neue Berechtigung READ_MEDIA_VISUAL_USER_SELECTED verwendet, führt das System Ihre App in einem Kompatibilitätsmodus aus, wenn der Nutzer Medien auswählen oder noch einmal auswählen muss.

Verhalten bei der anfänglichen Medienauswahl

Wenn ein Nutzer bei der ersten Auswahl „Fotos und Videos auswählen“ auswählt (siehe Abbildung 1), werden während der App-Sitzung die Berechtigungen READ_MEDIA_IMAGES und READ_MEDIA_VIDEO gewährt. So werden vorübergehend Berechtigungen und vorübergehender Zugriff auf die vom Nutzer ausgewählten Fotos und Videos gewährt. Wenn Ihre App in den Hintergrund verschoben oder der Nutzer sie aktiv beendet, werden diese Berechtigungen vom System möglicherweise abgelehnt. Dieses Verhalten entspricht anderen einmaligen Berechtigungen.

Verhalten bei der Medienauswahl

Wenn Ihre App später auf zusätzliche Fotos und Videos zugreifen muss, müssen Sie die Berechtigung READ_MEDIA_IMAGES oder READ_MEDIA_VIDEO noch einmal manuell anfordern. Das System folgt demselben Ablauf wie bei der ursprünglichen Berechtigungsanfrage und fordert Nutzer auf, Fotos und Videos auszuwählen (siehe Abbildung 2).

Wenn Ihre App den Best Practices für Berechtigungen entspricht, sollte diese Änderung für Ihre Anwendung weiterhin bestehen. Dies gilt insbesondere, wenn Ihre App nicht davon ausgeht, dass der URI-Zugriff beibehalten wird, den Systemberechtigungsstatus speichert oder den Satz angezeigter Bilder nach der Änderung der Berechtigung aktualisiert. Dieses Verhalten ist jedoch je nach Anwendungsfall Ihrer Anwendung möglicherweise nicht ideal. Wir empfehlen dir, die Bildauswahl zu implementieren oder die Galerieauswahl deiner App so anzupassen, dass dieses Verhalten direkt mit der Berechtigung READ_MEDIA_VISUAL_USER_SELECTED gehandhabt wird.