Bildauswahl

Das Dialogfeld „Bildauswahl“ mit den Mediendateien auf Ihrem Gerät wird 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 Bildauswahl bietet eine durchsuchbare Oberfläche, auf der die Medienbibliothek des Nutzers nach Datum sortiert angezeigt wird, beginnend mit dem neuesten. Wie im Codelab zu Best Practices für den Datenschutz gezeigt, bietet die Bildauswahl eine sichere, integrierte Möglichkeit für Nutzer, Ihrer App Zugriff auf ausgewählte Bilder und Videos statt auf die gesamte Mediathek zu gewähren.

Nutzer, die auf ihrem Gerät berechtigte Cloud-Medienanbieter haben, können auch aus per Fernzugriff gespeicherten Fotos und Videos auswählen. Weitere Informationen zu Cloud-Medienanbietern

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.

Verwende die folgenden Aktivitätsergebnisverträge, um die Bildauswahl zu starten:

Wenn die Bildauswahl auf einem Gerät nicht verfügbar ist, wird stattdessen automatisch die Intent-Aktion ACTION_OPEN_DOCUMENT aufgerufen. 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 Bildauswahl auf einem bestimmten Gerät verfügbar ist, indem Sie isPhotoPickerAvailable() aufrufen.

Einzelnes Medienelement auswählen

Wenn du ein einzelnes Medienelement auswählen möchtest, verwende den PickVisualMedia-Aktivitätsergebnisvertrag, 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 du mehrere Medienelemente auswählen möchtest, lege 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 Bildauswahl 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 zurückportierten Moduls für die Bildauswahl über Google Play-Dienste aktivieren möchten, fügen Sie dem <application>-Tag in der Manifestdatei Ihrer App 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, muss dieser Zugriff möglicherweise länger gespeichert werden. 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 Bildqualität, aber einige ältere Apps sind möglicherweise nicht für diese neueren Formate geeignet. Das kann zu Problemen wie unnatürlichen Farbwiedergaben während der Wiedergabe führen, z. B. zu grün getönten Gesichtern. Um diese Kompatibilitätslücke zu schließen, bietet die Bildauswahl eine Transcodierungsfunktion, mit der HDR-Videos automatisch in das Format „Standard Dynamic Range“ (SDR) konvertiert werden können, bevor sie an die anfragende App gesendet werden.

Das primäre Ziel der Transcodierung in der Bildauswahl besteht darin, für eine einheitliche und visuell korrekte Medienwiedergabe in einer größeren Bandbreite von Anwendungen zu sorgen, auch in solchen, die noch keine explizite HDR-Unterstützung haben. Durch das Transcodieren von HDR-Videos in SDR soll die App-Kompatibilität verbessert und die Nutzerfreundlichkeit optimiert werden.

So funktioniert das Transcodieren in der Bildauswahl

Die HDR-Transcodierung in der Bildauswahl ist standardmäßig nicht aktiviert. Wenn Sie diese Funktion aktivieren möchten, muss Ihre App beim Starten der Bildauswahl explizit ihre Fähigkeiten zur Verarbeitung von Medienformaten angeben.

Ihre App stellt die Medienverarbeitungsfunktionen der Bildauswahl zur Verfügung. Dazu fügen Sie beim Starten der Bildauswahl mit der AndroidX Activity Library mediaCapabilities zu PickVisualMediaRequest.Builder hinzu. Dazu wurde der PickVisualMediaRequest.Builder die neue API setMediaCapabilitiesForTranscoding(capabilities: MediaCapabilities?) hinzugefügt.

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

Wenn du die Transcodierung vollständig deaktivieren möchtest, gib null für MediaCapabilities ein. Alle HDR-Typen, die nicht in den 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 mit @RequiresApi(Build.VERSION_CODES.TIRAMISU) gekennzeichnet.

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 über die Bildauswahl basiert sowohl auf den Medienfunktionen der App als auch auf dem ausgewählten Video. Wenn eine Transcodierung durchgeführt wird, wird ein URI zum transcodierten Video zurückgegeben.

Wichtige Hinweise zum Transcodieren von HDR

  • Leistung und Speicherplatz:Das Transcodieren benötigt Verarbeitungszeit und es wird eine neue Datei erstellt, die Speicherplatz belegt.
  • Videolänge: Um die Nutzerfreundlichkeit und Speichereinschränkungen in Einklang zu bringen, ist die Videolänge auf 1 Minute begrenzt.
  • Verwaltung von im Cache gespeicherten Dateien:Im Cache gespeicherte transkodierte Dateien werden bei der Inaktivitätswartung regelmäßig gelöscht, um eine übermäßige Speichernutzung zu verhindern.
  • Geräteverfügbarkeit:Die Transcodierung der Bildauswahl wird unter Android 13 (API-Level 33) und höher unterstützt.
  • AndroidX-Aktivitätsintegration:Sie müssen Version 1.11.0-alpha01 oder eine spätere Alpha-/Beta-/RC-/stabile Version der AndroidX-Aktivitätsbibliothek verwenden, da diese die erforderliche setMediaCapabilitiesForTranscoding API enthält.