相片挑選工具

Stay organized with collections Save and categorize content based on your preferences.
顯示相片挑選工具對話方塊,其中出現您裝置上的媒體檔案。選取要與應用程式分享的相片。
圖 1. 相片挑選工具提供直覺易用的使用者介面,方便您與應用程式分享相片。

相片挑選工具會提供可瀏覽且可供搜尋的介面,向使用者顯示媒體庫,並由新到舊為檔案排序。這項工具提供安全的內建功能讓使用者選取圖片和影片,而不必授予應用程式整個媒體庫的存取權。

如果您允許系統設定相片挑選工具,系統會開放所有符合以下條件的裝置使用這項工具 (Android Go 裝置除外):

此外,如果您允許系統設定相片挑選工具,工具會自動更新,以便持續為應用程式使用者提供更多功能,而無需變更任何程式碼。

您也可以在搭載 Android 13 以上版本的裝置上自訂相片挑選工具啟動體驗

允許系統設定相片挑選工具

相片挑選工具支援資料庫可讓您透過下列任一 Activity Result 合約,由應用程式啟動相片挑選工具:

如果裝置上沒有相片挑選工具,支援資料庫會改為自動叫用 ACTION_OPEN_DOCUMENT 意圖動作。搭載 Android 4.4 (API 級別 19) 以上版本的裝置支援這個意圖。您可以呼叫 isPhotoPickerAvailable(),確認特定裝置是否支援相片挑選工具。

選取單一媒體項目

如要選取單一媒體項目,請使用 PickVisualMedia Activity Result 合約,如以下程式碼片段所示:

Kotlin

// 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 allow the user to choose from.

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

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

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

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

Java

// 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 allow the user to choose from.

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

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

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

// Launch the photo picker and allow the user to 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());

選取多個媒體項目

如要選取多個媒體項目,請設定可選取的媒體檔案數量上限,如以下程式碼片段所示。

Kotlin

// Registers a photo picker activity launcher in multi-select mode.
// In this example, the app allows the user to 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 allow the user to 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))

Java

// Registering Photo Picker activity launcher with multiple selects (5 max in this example)
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 allow the user to 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());

自訂相片挑選工具的啟動體驗

以下各節說明如何使用架構程式庫來自訂啟動相片挑選工具的意圖。

確認相片挑選工具是否可用

如要確認特定裝置是否能使用相片挑選器,請加入以下程式碼片段中顯示的邏輯:

Kotlin

import android.os.ext.SdkExtensions.getExtensionVersion

fun isPhotoPickerAvailable(): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        true
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        getExtensionVersion(Build.VERSION_CODES.R) >= 2
    } else {
        false
    }
}

Java

import android.os.ext.SdkExtensions.getExtensionVersion;

private boolean isPhotoPickerAvailable() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        return true;
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        return getExtensionVersion(Build.VERSION_CODES.R) >= 2;
    } else
        return false;
    }
}

定義分享限制

應用程式可以宣告 EXTRA_PICK_IMAGES_MAX 的值,這個值是指系統向使用者顯示相片挑選工具時,工具中可顯示的媒體檔案數量上限。舉例來說,如果您提示使用者為帳戶選取必要的個人資料相片,請將分享上限規定設為一張相片

選取單一媒體項目

如要以單選模式啟動相片挑選工具,請按照下列步驟操作:

Kotlin

// Launches photo picker in single-select mode.
// This means that the user can select one photo or video.
val intent = Intent(MediaStore.ACTION_PICK_IMAGES)
startActivityForResult(intent, PHOTO_PICKER_REQUEST_CODE)

Java

// Launches photo picker in single-select mode.
// This means that the user can select one photo or video.
Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES);
startActivityForResult(intent, PHOTO_PICKER_REQUEST_CODE);

選取多個媒體項目

如果應用程式的用途需要使用者選取多張相片或多部影片,您可以使用 EXTRA_PICK_IMAGES_MAX 額外功能指定在相片挑選工具中顯示的圖片數量上限,如以下程式碼片段所示:

Kotlin

// Launches photo picker in multi-select mode.
// This means that user can select multiple photos/videos, up to the limit
// specified by the app in the extra (10 in this example).
val maxNumPhotosAndVideos = 10
val intent = Intent(MediaStore.ACTION_PICK_IMAGES)
intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxNumPhotosAndVideos)
startActivityForResult(intent, PHOTO_PICKER_MULTI_SELECT_REQUEST_CODE)

Java

// Launches photo picker in multi-select mode.
// This means that user can select multiple photos/videos, up to the limit
// specified by the app in the extra (10 in this example).
final int maxNumPhotosAndVideos = 10;
Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES);
intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxNumPhotosAndVideos);
startActivityForResult(intent, PHOTO_PICKER_MULTI_SELECT_REQUEST_CODE);

請注意,平台本身會限制您可指定為檔案數量上限的最大數值。如要存取這項限制,請呼叫 getPickImagesMaxLimit()

處理相片挑選工具結果

啟動相片挑選工具後,請使用 ACTION_PICK_IMAGES 意圖動作來處理結果。挑選工具會傳回一組 URI:

Kotlin

// onActivityResult() handles callbacks from the photo picker.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode != Activity.RESULT_OK) {
        // Handle error
        return
    }
    when (requestCode) {
        REQUEST_PHOTO_PICKER_SINGLE_SELECT -> {
            // Get photo picker response for single select.
            val currentUri: Uri = data.data!!

            // Do stuff with the photo/video URI.
            return
    }
        REQUEST_PHOTO_PICKER_MULTI_SELECT -> {
            // Get photo picker response for multi select.
            var i = 0
            var currentUri: Uri

            while (i < data.clipData!!.itemCount) {
                currentUri = data.clipData!!.getItemAt(i).uri
                // Do stuff with each photo/video URI.
                i++
            }
            return
    }
}

Java

// onActivityResult() handles callbacks from the photo picker.
@Override
protected void onActivityResult(
    int requestCode, int resultCode, final Intent data) {

    if (resultCode != Activity.RESULT_OK) {
        // Handle error
        return;
    }

    switch(requestCode) {
        case REQUEST_PHOTO_PICKER_SINGLE_SELECT:
            // Get photo picker response for single select.
            Uri currentUri = data.getData();

            // Do stuff with the photo/video URI.
            return;
        case REQUEST_PHOTO_PICKER_MULTI_SELECT:
            // Get photo picker response for multi select
            for (int i = 0; i < data.getClipData().getItemCount(); i++) {
                Uri currentUri = data.getClipData().getItemAt(i).getUri();

                // Do stuff with each photo/video URI.
            }
            return;
    }
}

根據預設,相片挑選工具會顯示相片和影片。您也可以在 setType() 方法中設定 MIME 類型,讓系統只篩選出相片或影片其中一種。舉例來說,如果只想在相片挑選工具中顯示影片,請將 video/* 傳遞至 setType()

Kotlin

// Launches photo picker for videos only in single select mode.
val intent = Intent(MediaStore.ACTION_PICK_IMAGES)
intent.type = "video/*"
startActivityForResult(intent, PHOTO_PICKER_VIDEO_SINGLE_SELECT_REQUEST_CODE)

// Apps can also change the mimeType to allow users to select
// images only - intent.type = "images/*"

Java

// Launches photo picker for videos only in single select mode.
Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES);
intent.setType("video/*");
startActivityForResult(intent, PHOTO_PICKER_VIDEO_SINGLE_SELECT_REQUEST_CODE);

// Apps can also change the mimeType to allow users to select
// images only - intent.setType("image/*");
// or a specific mimeType - intent.setType("image/gif");