Bildauswahl

Das Dialogfeld zur Auswahl von Fotos wird mit den Mediendateien auf Ihrem Gerät angezeigt. Wählen Sie ein Foto aus, das Sie für die App freigeben möchten.
Abbildung 1: Die Bildauswahl bietet eine intuitive Benutzeroberfläche zum Teilen von Fotos mit Ihrer App.

Die Fotoauswahl bietet eine durchsuchbare Benutzeroberfläche, in der die Mediathek des Nutzers nach Datum sortiert wird, beginnend mit dem neuesten. Wie im Codelab zu Datenschutz-Best Practices gezeigt, bietet die Bildauswahl Nutzern eine sichere, integrierte Möglichkeit, Ihrer App nur Zugriff auf ausgewählte Bilder und Videos statt auf die gesamte Mediathek zu gewähren.

Nutzer, die auf ihrem Gerät einen unterstützten Cloud-Media-Anbieter haben, können auch Fotos und Videos auswählen, die remote gespeichert sind. Weitere Informationen zu Cloud-Media-Anbietern

Das Tool wird automatisch aktualisiert. So erhalten Nutzer im Laufe der Zeit Zugriff auf zusätzliche Funktionen, ohne dass Änderungen am Code erforderlich sind.

Jetpack Activity-Verträge verwenden

Um die Integration der Bildauswahl zu vereinfachen, sollten Sie Version 1.7.0 oder höher der androidx.activity-Bibliothek verwenden.

Verwenden Sie die folgenden Aktivitätsergebnis-Contracts, um die Bildauswahl zu starten:

Wenn die Bildauswahl auf einem Gerät nicht verfügbar ist, ruft die Bibliothek stattdessen automatisch die Intent-Aktion ACTION_OPEN_DOCUMENT auf. Dieser Intent wird auf Geräten mit Android 4.4 (API-Level 19) oder höher unterstützt. Sie können prüfen, ob die Fotogalerie auf einem bestimmten Gerät verfügbar ist, indem Sie isPhotoPickerAvailable() aufrufen.

Einzelnes Medienelement auswählen

Wenn Sie ein einzelnes Media-Element auswählen möchten, verwenden Sie den PickVisualMedia-Aktivitätsergebnis-Contract, wie im folgenden Code-Snippet gezeigt:

Aufrufe

// Registers a photo picker activity launcher in single-select mode.
val pickMedia = registerForActivityResult(PickVisualMedia()) { uri ->
    // Callback is invoked after the user selects a media item or closes the
    // photo picker.
    if (uri != null) {
        Log.d("PhotoPicker", "Selected URI: $uri")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// Include only one of the following calls to launch(), depending on the types
// of media that you want to let the user choose from.

// Launch the photo picker and let the user choose images and videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

// Launch the photo picker and let the user choose only images.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageOnly))

// Launch the photo picker and let the user choose only videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.VideoOnly))

// Launch the photo picker and let the user choose only images/videos of a
// specific MIME type, such as GIFs.
val mimeType = "image/gif"
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.SingleMimeType(mimeType)))

Aufrufe

// Registers a photo picker activity launcher in single-select mode.
ActivityResultLauncher<PickVisualMediaRequest> pickMedia =
        registerForActivityResult(new PickVisualMedia(), uri -> {
    // Callback is invoked after the user selects a media item or closes the
    // photo picker.
    if (uri != null) {
        Log.d("PhotoPicker", "Selected URI: " + uri);
    } else {
        Log.d("PhotoPicker", "No media selected");
    }
});

// Include only one of the following calls to launch(), depending on the types
// of media that you want to let the user choose from.

// Launch the photo picker and let the user choose images and videos.
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageAndVideo.INSTANCE)
        .build());

// Launch the photo picker and let the user choose only images.
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageOnly.INSTANCE)
        .build());

// Launch the photo picker and let the user choose only videos.
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.VideoOnly.INSTANCE)
        .build());

// Launch the photo picker and let the user choose only images/videos of a
// specific MIME type, such as GIFs.
String mimeType = "image/gif";
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(new PickVisualMedia.SingleMimeType(mimeType))
        .build());

Schreiben

// Registers a photo picker activity launcher in single-select mode.
val pickMedia = rememberLauncherForActivityResult(PickVisualMedia()) { uri ->
    // Callback is invoked after the user selects a media item or closes the
    // photo picker.
    if (uri != null) {
        Log.d("PhotoPicker", "Selected URI: $uri")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// Include only one of the following calls to launch(), depending on the types
// of media that you want to let the user choose from.

// Launch the photo picker and let the user choose images and videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

// Launch the photo picker and let the user choose only images.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageOnly))

// Launch the photo picker and let the user choose only videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.VideoOnly))

// Launch the photo picker and let the user choose only images/videos of a
// specific MIME type, such as GIFs.
val mimeType = "image/gif"
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.SingleMimeType(mimeType)))

Mehrere Medienelemente auswählen

Wenn Sie mehrere Medienelemente auswählen möchten, legen Sie eine maximale Anzahl auswählbarer Mediendateien fest, wie im folgenden Code-Snippet gezeigt.

Aufrufe

// Registers a photo picker activity launcher in multi-select mode.
// In this example, the app lets the user select up to 5 media files.
val pickMultipleMedia =
        registerForActivityResult(PickMultipleVisualMedia(5)) { uris ->
    // Callback is invoked after the user selects media items or closes the
    // photo picker.
    if (uris.isNotEmpty()) {
        Log.d("PhotoPicker", "Number of items selected: ${uris.size}")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// For this example, launch the photo picker and let the user choose images
// and videos. If you want the user to select a specific type of media file,
// use the overloaded versions of launch(), as shown in the section about how
// to select a single media item.
pickMultipleMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

Aufrufe

// Registers a photo picker activity launcher in multi-select mode.
// In this example, the app lets the user select up to 5 media files.
ActivityResultLauncher<PickVisualMediaRequest> pickMultipleMedia =
        registerForActivityResult(new PickMultipleVisualMedia(5), uris -> {
    // Callback is invoked after the user selects media items or closes the
    // photo picker.
    if (!uris.isEmpty()) {
        Log.d("PhotoPicker", "Number of items selected: " + uris.size());
    } else {
        Log.d("PhotoPicker", "No media selected");
    }
});

// For this example, launch the photo picker and let the user choose images
// and videos. If you want the user to select a specific type of media file,
// use the overloaded versions of launch(), as shown in the section about how
// to select a single media item.
pickMultipleMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageAndVideo.INSTANCE)
        .build());

Schreiben

// Registers a photo picker activity launcher in multi-select mode.
// In this example, the app lets the user select up to 5 media files.
val pickMultipleMedia =
        rememberLauncherForActivityResult(PickMultipleVisualMedia(5)) { uris ->
    // Callback is invoked after the user selects media items or closes the
    // photo picker.
    if (uris.isNotEmpty()) {
        Log.d("PhotoPicker", "Number of items selected: ${uris.size}")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// For this example, launch the photo picker and let the user choose images
// and videos. If you want the user to select a specific type of media file,
// use the overloaded versions of launch(), as shown in the section about how
// to select a single media item.
pickMultipleMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

Die Plattform begrenzt die maximale Anzahl von Dateien, die der Nutzer in der Bildauswahl auswählen kann. Rufen Sie getPickImagesMaxLimit() auf, um auf dieses Limit zuzugreifen. Auf Geräten, auf denen die Bildauswahl nicht unterstützt wird, wird dieses Limit ignoriert.

Geräteverfügbarkeit

Die Fotogalerie ist auf Geräten verfügbar, die die folgenden Kriterien erfüllen:

Auf älteren Geräten mit Android 4.4 (API-Level 19) bis Android 10 (API-Level 29) und Android Go-Geräten mit Android 11 oder 12, die Google Play-Dienste unterstützen, kann eine rückkompatible Version der Bildauswahl installiert werden. Wenn Sie die automatische Installation des backportierten Fotogalerie-Moduls über Google Play Services aktivieren möchten, fügen Sie der Datei <application> in Ihrem App-Manifest den folgenden Eintrag hinzu:

<!-- Trigger Google Play services to install the backported photo picker module. -->
<service android:name="com.google.android.gms.metadata.ModuleDependencies"
         android:enabled="false"
         android:exported="false"
         tools:ignore="MissingClass">
    <intent-filter>
        <action android:name="com.google.android.gms.metadata.MODULE_DEPENDENCIES" />
    </intent-filter>
    <meta-data android:name="photopicker_activity:0:required" android:value="" />
</service>

Zugriff auf Mediendateien beibehalten

Standardmäßig gewährt das System Ihrer App Zugriff auf Mediendateien, bis das Gerät neu gestartet wird oder Ihre App beendet wird. Wenn Ihre App lang andauernde Aufgaben ausführt, z. B. das Hochladen einer großen Datei im Hintergrund, benötigen Sie möglicherweise einen längeren Zugriff. Rufen Sie dazu die Methode takePersistableUriPermission() auf:

Kotlin

val flag = Intent.FLAG_GRANT_READ_URI_PERMISSION
context.contentResolver.takePersistableUriPermission(uri, flag)

Java

int flag = Intent.FLAG_GRANT_READ_URI_PERMISSION;
context.contentResolver.takePersistableUriPermission(uri, flag);

HDR-Videos mit Transcodierung verarbeiten

Mit Android 13 (API 33) wurde die Möglichkeit eingeführt, HDR-Videos (High Dynamic Range) aufzunehmen. HDR bietet zwar eine bessere visuelle Darstellung, aber einige ältere Apps sind möglicherweise nicht für diese neueren Formate ausgelegt. Das kann zu Problemen wie einer unnatürlichen Farbwiedergabe bei der Wiedergabe führen (z. B. grün getönte Gesichter). Um diese Kompatibilitätslücke zu schließen, bietet die Bildauswahl eine Transcodierungsfunktion, mit der HDR-Videos automatisch in das SDR-Format (Standard Dynamic Range) konvertiert werden können, bevor sie der anfragenden App zur Verfügung gestellt werden.

Das primäre Ziel der Transcodierung des Foto-Pickers ist es, eine einheitliche und visuell genaue Medienwiedergabe in einer Vielzahl von Anwendungen zu gewährleisten, auch in solchen, die noch keine explizite HDR-Unterstützung bieten. Durch die Transcodierung von HDR-Videos in SDR soll die App-Kompatibilität verbessert und eine nahtlose Nutzererfahrung ermöglicht werden.

So funktioniert die Transcodierung in der Bildauswahl

Die HDR-Transcodierung für die Bildauswahl ist nicht standardmäßig aktiviert. Damit diese Funktion aktiviert werden kann, muss Ihre App beim Starten der Bildauswahl explizit angeben, welche Medienformate sie verarbeiten kann.

Ihre App stellt ihre Medienverarbeitungsfunktionen für die Bildauswahl zur Verfügung. Dies geschieht beim Starten der Bildauswahl über die AndroidX Activity-Bibliothek, indem mediaCapabilities zu PickVisualMediaRequest.Builder hinzugefügt wird. Dazu wurde eine neue API, setMediaCapabilitiesForTranscoding(capabilities: MediaCapabilities?), in PickVisualMediaRequest.Builder eingeführt.

Sie können das HDR-Transcodierungsverhalten mit der Klasse MediaCapabilities steuern. Geben Sie ein MediaCapabilities-Objekt an, in dem genau angegeben wird, welche HDR-Typen Ihre App unterstützt (z.B. TYPE_HLG10, TYPE_HDR10, TYPE_HDR10_PLUS, TYPE_DOLBY_VISION).

Wenn Sie die Transcodierung vollständig deaktivieren möchten, übergeben Sie null für MediaCapabilities. Alle HDR-Typen, die nicht explizit in den von Ihnen angegebenen Funktionen aufgeführt sind, werden als nicht unterstützt betrachtet. Diese API wird unter Android 13 (API‑Level 33) und höher unterstützt und ist mit @RequiresApi(Build.VERSION_CODES.TIRAMISU) annotiert.

import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia
import androidx.annotation.RequiresApi
import android.os.Build
import android.util.Log
import android.provider.MediaStore

// Registers a photo picker activity launcher.
val pickMedia = registerForActivityResult(PickVisualMedia()) { uri ->
    // Callback invoked after media selected or picker activity closed.
    if (uri != null) {
        Log.d("photo picker", "Selected URI: $uri")
    } else {
        Log.d("photo picker", "No media selected")
    }
}

@RequiresApi(Build.VERSION_CODES.TIRAMISU)
fun launchPhotoPickerWithTranscodingSupport() {
    val mediaCapabilities = MediaCapabilities.Builder()
        .addSupportedHdrType(MediaCapabilities.HdrType.TYPE_HLG10)
        .build()

    // Launch the photo picker and let the user choose only videos with
    // transcoding enabled.
    pickMedia.launch(PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.VideoOnly)
        .setMediaCapabilitiesForTranscoding(mediaCapabilities)
        .build())
}

Die Transcodierung durch die Bildauswahl basiert sowohl auf den Media-Funktionen der App als auch auf dem ausgewählten Video. Wenn die Transcodierung erfolgt, wird ein URI zum transcodierten Video zurückgegeben.

Wichtige Hinweise zur HDR-Transcodierung

  • Leistung und Speicherplatz:Die Transcodierung benötigt Rechenzeit und es wird eine neue Datei erstellt, die Speicherplatz belegt.
  • Videolängenbeschränkung:Um die Nutzerfreundlichkeit und die Speicherbeschränkungen in Einklang zu bringen, gilt eine Videolängenbeschränkung von 1 Minute.
  • Verwaltung von im Cache gespeicherten Dateien:Im Cache gespeicherte transkodierte Dateien werden regelmäßig bei der Wartung im Leerlauf gelöscht, um eine übermäßige Speichernutzung zu verhindern.
  • Verfügbarkeit auf Geräten:Die Transcodierung der Bildauswahl wird unter Android 13 (API-Level 33) und höher unterstützt.
  • AndroidX-Aktivitätsintegration:Achten Sie darauf, dass Sie Version 1.11.0-alpha01 oder eine spätere Alpha-/Beta-/RC-/stabile Version der AndroidX Activity-Bibliothek verwenden, da diese die erforderliche setMediaCapabilitiesForTranscoding-API enthält.