从 android 图库中选择多个图像

所以基本上我要做的就是在 Android 中打开 Gallery,让用户选择 multiple images。现在这个问题已经问 经常,但我不满意的答案。主要是因为我在 IDE 的 de docs 中发现了一些有趣的东西(稍后我会回来讨论这个问题) ,因此我不想使用自定义适配器,只想使用普通的适配器。

现在我选择一张图片的代码是:

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), 1);

现在 SO 和其他网站上的人会告诉你有两个选择:

1)不要使用 ACTION_GET_CONTENT而是使用 ACTION_SEND_MULTIPLE
这个不管用。这是根据文件的 sending文件,而不是 retrieving,这正是它所做的。当使用 ACTION _ SEND _ MULTIPLE 时,我在设备上打开了一个窗口,在那里我必须选择一个应用程序来发送数据。那不是我想要的,所以我想知道人们是如何用这个方法达到这个目的的。.我错过什么了吗?

2)实施 custom Gallery。现在这是我最后的选择,我会考虑,因为 imho 它不是什么我正在寻找,因为我必须自己设计它,为什么你只是不能选择香草图片库的多个图片?

肯定还有别的选择. . 现在有趣的是我发现了这个:
我在 ACTION_GET_CONTENT的文件描述里找到了这个。

如果调用方可以处理多个返回项(用户执行 ) ,然后它可以指定 EXTRA _ ALLOW _ MULTIPLE 到 显示这个。

这是非常有趣的。在这里,他们引用它的用例,一个用户可以选择多个项目?

后来他们在文件中说:

您可以使用 EXTRA _ ALLOW _ MULTIPLE 允许用户选择多个 物品。

这很明显,对吧?这就是我需要的。但是我接下来的问题是: 我可以把这个 EXTRA_ALLOW_MULTIPLE放在哪里?可悲的是,我在 开发者,机器人指南中找不到这个,在 INTENT 类中也没有定义为常量。

有人能帮我解决这个 EXTRA_ALLOW_MULTIPLE吗?

205126 次浏览

EXTRA _ ALLOW _ MULTIPLE 选项是通过 Inent.putUltra ()方法对意图进行设置的:

intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);

上面的代码应该是这样的:

Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), 1);

注意: EXTRA_ALLOW_MULTIPLE选项仅在 Android API 18及更高版本中可用。

我希望这个回答不会太迟。因为画廊小部件默认情况下不支持多重选择,但是您可以定制接受您的多重选择意图的网格视图。另一种选择是扩展画廊视图并添加您自己的代码以允许多个选择。
这是一个简单的图书馆可以做到这一点: < a href = “ https://github.com/lumousman/MultipleImagepick”rel = “ nofollow norefrer”> https://github.com/luminousman/multipleimagepick

更新 :
根据@ilsy 的注释,这个库中的 海关美术馆活动使用 manageQuery,这是不推荐的,所以它应该像 这个答案一样改为 getContentResolver().query()cursor.close()

您好,下面的代码工作正常。

 Cursor imagecursor1 = managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null,
null, orderBy + " DESC");


this.imageUrls = new ArrayList<String>();
imageUrls.size();


for (int i = 0; i < imagecursor1.getCount(); i++) {
imagecursor1.moveToPosition(i);
int dataColumnIndex = imagecursor1
.getColumnIndex(MediaStore.Images.Media.DATA);
imageUrls.add(imagecursor1.getString(dataColumnIndex));
}


options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.stub_image)
.showImageForEmptyUri(R.drawable.image_for_empty_url)
.cacheInMemory().cacheOnDisc().build();


imageAdapter = new ImageAdapter(this, imageUrls);


gridView = (GridView) findViewById(R.id.PhoneImageGrid);
gridView.setAdapter(imageAdapter);

你想要更多的澄清。 Http://mylearnandroid.blogspot.in/2014/02/multiple-choose-custom-gallery.html

我也有同样的问题。我也希望这样用户可以轻松地拍摄照片,同时从画廊挑选照片。因为找不到一种本地化的方法,所以我决定做一个开源项目。它很像 MultipleImagepick,但只是更好的实现方式。

Https://github.com/giljulio/android-multiple-image-picker

private static final RESULT_CODE_PICKER_IMAGES = 9000;




Intent intent = new Intent(this, SmartImagePicker.class);
startActivityForResult(intent, RESULT_CODE_PICKER_IMAGES);




@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case RESULT_CODE_PICKER_IMAGES:
if(resultCode == Activity.RESULT_OK){
Parcelable[] parcelableUris = data.getParcelableArrayExtra(ImagePickerActivity.TAG_IMAGE_URI);


//Java doesn't allow array casting, this is a little hack
Uri[] uris = new Uri[parcelableUris.length];
System.arraycopy(parcelableUris, 0, uris, 0, parcelableUris.length);


//Do something with the uris array
}
break;


default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}

在类中定义这些变量:

int PICK_IMAGE_MULTIPLE = 1;
String imageEncoded;
List<String> imagesEncodedList;

让我们假设 onClick 在一个按钮上,它应该打开图库来选择图像

 Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), PICK_IMAGE_MULTIPLE);

然后应重写 onActivityResult 方法

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
// When an Image is picked
if (requestCode == PICK_IMAGE_MULTIPLE && resultCode == RESULT_OK
&& null != data) {
// Get the Image from data


String[] filePathColumn = { MediaStore.Images.Media.DATA };
imagesEncodedList = new ArrayList<String>();
if(data.getData()!=null){


Uri mImageUri=data.getData();


// Get the cursor
Cursor cursor = getContentResolver().query(mImageUri,
filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();


int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imageEncoded  = cursor.getString(columnIndex);
cursor.close();


} else {
if (data.getClipData() != null) {
ClipData mClipData = data.getClipData();
ArrayList<Uri> mArrayUri = new ArrayList<Uri>();
for (int i = 0; i < mClipData.getItemCount(); i++) {


ClipData.Item item = mClipData.getItemAt(i);
Uri uri = item.getUri();
mArrayUri.add(uri);
// Get the cursor
Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();


int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imageEncoded  = cursor.getString(columnIndex);
imagesEncodedList.add(imageEncoded);
cursor.close();


}
Log.v("LOG_TAG", "Selected Images" + mArrayUri.size());
}
}
} else {
Toast.makeText(this, "You haven't picked Image",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
.show();
}


super.onActivityResult(requestCode, resultCode, data);
}

请注意: 画廊不给你选择多图像的能力,所以我们在这里打开所有的图像工作室,你可以选择多图像从他们。 并且不要忘记向您的清单添加权限

非常重要: GetData () ; 获取一个图像,并将其存储在 image 编码字符串中 如果用户选择多个图像,然后 它们应该存储在列表中

所以你必须检查哪个是 null 才能使用另一个

希望你有一个很好的尝试和其他人

试试这一个 意向选择者。只要添加一些代码行,我为你做了其余的。

private void startImageChooserActivity() {
Intent intent = ImageChooserMaker.newChooser(MainActivity.this)
.add(new ImageChooser(true))
.create("Select Image");
startActivityForResult(intent, REQUEST_IMAGE_CHOOSER);
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CHOOSER && resultCode == RESULT_OK) {
List<Uri> imageUris = ImageChooserMaker.getPickMultipleImageResultUris(this, data);
}
}

附注: 正如上面的答案所提到的,EXTRA _ ALLOW _ MULTIPLE 仅适用于 API > = 18。而且一些画廊应用程序不支持这个功能(谷歌照片和文档(com.android.documentsui))。

这些答案有很多相似之处,但都缺少最重要的部分是在 onActivityResult,检查 data.getClipData是否为空 之前检查 data.getData

调用文件选择器的代码:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*"); //allows any image file type. Change * to specific extension to limit it
//**The following line is the important one!
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURES); //SELECT_PICTURES is simply a global int used to check the calling intent in onActivityResult

获取所选图像的 所有的代码:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == SELECT_PICTURES) {
if(resultCode == Activity.RESULT_OK) {
if(data.getClipData() != null) {
int count = data.getClipData().getItemCount(); //evaluate the count before the for loop --- otherwise, the count is evaluated every loop.
for(int i = 0; i < count; i++) {
Uri imageUri = data.getClipData().getItemAt(i).getUri();
//do something with the image (save it to some directory or whatever you need to do with it here)
}
}
} else if(data.getData() != null) {
String imagePath = data.getData().getPath();
//do something with the image (save it to some directory or whatever you need to do with it here)
}
}
}

注意,Android 的选择器在一些设备上提供了照片和图片库。照片允许选择多个图像。画廊一次只允许一个人。

初始化实例:

private String imagePath;
private List<String> imagePathList;

OnActivityResult中,你必须写这个,If-else 2块。一个用于单个图像,另一个用于多个图像。

if (requestCode == GALLERY_CODE && resultCode == RESULT_OK  && data != null) {


imagePathList = new ArrayList<>();


if (data.getClipData() != null) {


int count = data.getClipData().getItemCount();
for (int i=0; i<count; i++) {
Uri imageUri = data.getClipData().getItemAt(i).getUri();
getImageFilePath(imageUri);
}
}
else if (data.getData() != null) {
Uri imgUri = data.getData();
getImageFilePath(imgUri);
}
}

最重要的部分,从 uri 获取图像路径:

public void getImageFilePath(Uri uri) {


File file = new File(uri.getPath());
String[] filePath = file.getPath().split(":");
String image_id = filePath[filePath.length - 1];


Cursor cursor = getContentResolver().query(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{image_id}, null);
if (cursor!=null) {
cursor.moveToFirst();
imagePath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
imagePathList.add(imagePath);
cursor.close();
}
}

希望这个能帮到你。

我从 Cursor得到了无效信息。 然后找到了一个解决方案,将 Uri转换成 Bitmap的工作完美。

以下是对我有效的解决方案:

@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
{


if (resultCode == Activity.RESULT_OK) {


if (requestCode == YOUR_REQUEST_CODE) {


if (data != null) {


if (data.getData() != null) {


Uri contentURI = data.getData();
ex_one.setImageURI(contentURI);


Log.d(TAG, "onActivityResult: " + contentURI.toString());
try {


Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), contentURI);


} catch (IOException e) {
e.printStackTrace();
}


} else {


if (data.getClipData() != null) {
ClipData mClipData = data.getClipData();
ArrayList<Uri> mArrayUri = new ArrayList<Uri>();
for (int i = 0; i < mClipData.getItemCount(); i++) {


ClipData.Item item = mClipData.getItemAt(i);
Uri uri = item.getUri();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}


}
}


}


}


}


}


}
     // for choosing multiple images declare variables
int PICK_IMAGE_MULTIPLE = 2;
String realImagePath;


// After requesting FILE READ PERMISSION may be on button click
Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Images"), PICK_IMAGE_MULTIPLE);




public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);// FOR CHOOSING MULTIPLE IMAGES
try {
// When an Image is picked
if (requestCode == PICK_IMAGE_MULTIPLE && resultCode == RESULT_OK
&& null != data) {
if (data.getClipData() != null) {
int count = data.getClipData().getItemCount(); //evaluate the count before the for loop --- otherwise, the count is evaluated every loop.
for (int i = 0; i < count; i++) {
Uri imageUri = data.getClipData().getItemAt(i).getUri();
realImagePath = getPath(this, imageUri);
//do something with the image (save it to some directory or whatever you need to do with it here)
Log.e("ImagePath", "onActivityResult: " + realImagePath);
}
} else if (data.getData() != null) {
Uri imageUri = data.getData();
realImagePath = getPath(this, imageUri);
//do something with the image (save it to some directory or whatever you need to do with it here)
Log.e("ImagePath", "onActivityResult: " + realImagePath);
}
}
} catch (Exception e) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
.show();
}
}
     



public static String getPath(final Context context, final Uri uri) {
// DocumentProvider
if (DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
    

if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
    

// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
    

final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.parseLong(id));
    

return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
    

Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
    

final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
    

return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
    

return null;
}
    

/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context       The context.
* @param uri           The Uri to query.
* @param selection     (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
public static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
    

Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
    

try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
    

    

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
    

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
    

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}

这对我来说是完美的工作信用: 从 URI 获取真实路径,Android KitKat 新的存储访问框架

用于从画廊中选择多个图像

i.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true);

一个终极解决方案的多个图像上传与相机选项,也为 Android Lollipop 安卓10,SDK 30。

private static final int FILECHOOSER_RESULTCODE   = 1;
private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> mUploadMessages;
private Uri mCapturedImageURI = null;

将此添加到 MainActivity 的 OnCreate

mWebView.setWebChromeClient(new WebChromeClient() {


// openFileChooser for Android 3.0+


public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType){
mUploadMessage = uploadMsg;
openImageChooser();
}


// For Lollipop 5.0+ Devices


public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
mUploadMessages = filePathCallback;
openImageChooser();
return true;
}


// openFileChooser for Android < 3.0


public void openFileChooser(ValueCallback<Uri> uploadMsg){
openFileChooser(uploadMsg, "");
}


//openFileChooser for other Android versions


public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg, acceptType);
}


private void openImageChooser() {
try {
File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "FolderName");
if (!imageStorageDir.exists()) {
imageStorageDir.mkdirs();
}
File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
mCapturedImageURI = Uri.fromFile(file);


final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);


Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
i.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true);
Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});


startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
} catch (Exception e) {
e.printStackTrace();
}
}


});

OnActivityResult

public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {




super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILECHOOSER_RESULTCODE) {


if (null == mUploadMessage && null == mUploadMessages) {
return;
}


if (null != mUploadMessage) {
handleUploadMessage(requestCode, resultCode, data);


} else if (mUploadMessages != null) {
handleUploadMessages(requestCode, resultCode, data);
}
}










}


private void handleUploadMessage(final int requestCode, final int resultCode, final Intent data) {
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null


result = data == null ? mCapturedImageURI : data.getData();
}
} catch (Exception e) {
e.printStackTrace();
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;


// code for all versions except of Lollipop
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {


result = null;


try {
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null
result = data == null ? mCapturedImageURI : data.getData();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "activity :" + e, Toast.LENGTH_LONG).show();
}


mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}


} // end of code for all versions except of Lollipop












private void handleUploadMessages(final int requestCode, final int resultCode, final Intent data) {
Uri[] results = null;
try {
if (resultCode != RESULT_OK) {
results = null;
} else {
if (data != null) {
String dataString = data.getDataString();
ClipData clipData = data.getClipData();
if (clipData != null) {
results = new Uri[clipData.getItemCount()];
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
results[i] = item.getUri();
}
}
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
} else {
results = new Uri[]{mCapturedImageURI};
}
}
} catch (Exception e) {
e.printStackTrace();
}
mUploadMessages.onReceiveValue(results);
mUploadMessages = null;
}

这个工程的多个图像选择。也测试了 API 29,30在谷歌照片。

private static final int PICK_IMAGE = 2;


Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(Intent.createChooser(intent, "Select
images"),PICK_IMAGE);


public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE && resultCode == RESULT_OK) {
if(data.getClipData() != null) {
int count = data.getClipData().getItemCount();
for(int i = 0; i < count; i++) {
Uri imageUri = data.getClipData().getItemAt(i).getUri();
//do what do you want to do
}
}
else if(data.getData() != null) {
Uri selectedImageUri = data.getData();
//do what do you want to do
}
}

对于多图像选择和选择限制功能,使用 Chintan369/MultiImagePicker库,这是最新的2021年,并支持 Android 11。这是很好的文档,也演示解释了 Youtube的使用。这是非常容易添加到项目中,很容易使用调用图像库选择和获得结果的选定图像作为 Uri 名单,也可以请求结果列表作为 绝对文件路径列表

如下定义 getContent;

val getContent =
registerForActivityResult(ActivityResultContracts.GetMultipleContents())
{ uriList ->
// todo
}

授予相关权限后运行以下代码

getContent.launch("images/*")

2022年-安卓喷气背包的构图方式

用 Android Jetpack Compose 在图库中选择多个图像。

val launcherMultipleImages = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetMultipleContents(),
) { uriList: List<Uri> ->
// TODO
}

然后使用 launcherMultipleImages.launch("image/*")开始选择图像。

例如:

Button(onClick = { launcherMultipleImages.launch("image/*") }) {
Text(text = "Select images")
}