从android库中选择多个图像

Dio*_*ijn 98 android image-gallery

所以基本上我想要实现的是Gallery在Android中打开并让用户选择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);
Run Code Online (Sandbox Code Playgroud)

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

1)不要使用ACTION_GET_CONTENT而是使用ACTION_SEND_MULTIPLE.
这个不起作用.这个是根据文件的sending文件,而不是retrieving,这正是它的作用.当使用ACTION_SEND_MULTIPLE时,我在我的设备上打开了一个窗口,我必须选择一个应用程序来发送我的数据.这不是我想要的,所以我想知道人们是如何通过这个解决方案实现这一目标的.我想念一些东西吗?

2)实施custom Gallery.现在这是我将考虑的最后一个选项,因为我不是我要搜索的东西,因为我必须自己设计风格以及为什么你不能在香草画廊中选择多个图像?

必须有一个选项..现在我发现的有趣的是这个:
我在文档描述中找到了这个ACTION_GET_CONTENT.

如果调用者可以处理多个返回的项(用户执行多个选择),那么它可以指定EXTRA_ALLOW_MULTIPLE来指示这一点.

这非常有趣.在这里,他们将其引用到用户可以选择多个项目的用例?

后来他们在文档中说:

您可以使用EXTRA_ALLOW_MULTIPLE来允许用户选择多个项目.

所以这很明显吧?这就是我需要的.但我的以下问题是:我可以把它放在哪里EXTRA_ALLOW_MULTIPLE?令人遗憾的是,我无法在developers.android指南中找到它,也没有在INTENT类中将其定义为常量.

有人可以帮我解决这个问题EXTRA_ALLOW_MULTIPLE吗?

小智 101

通过Intent.putExtra()方法在intent上设置EXTRA_ALLOW_MULTIPLE选项:

intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
Run Code Online (Sandbox Code Playgroud)

您上面的代码应如下所示:

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);
Run Code Online (Sandbox Code Playgroud)

注意:该EXTRA_ALLOW_MULTIPLE选项仅适用于Android API 18及更高版本.

  • 它选择了多个图像.但如何从活动结果中获取图像网址???? (7认同)
  • 我无法使用EXTRA_ALLOW_MULTIPLE选择多个图像.请帮助我,我在18+ api运行应用程序. (5认同)
  • @Cheerag这不会让你选择多个文件,我不知道所有人都同意这个. (5认同)
  • 您可以在结果"Intent.getClipData"中获取URL.它有ClipData Item数组. (5认同)
  • 这将启动图像选择器并允许我选择多个图像,但我不知道如何获取onActivityResult中的URL. (4认同)
  • 如何获取多个图像uri的值? (3认同)
  • @TomKincaid ....我也面临同样的问题.我无法获得多个图像的uri (2认同)

小智 63

在类中定义这些变量:

int PICK_IMAGE_MULTIPLE = 1; 
String imageEncoded;    
List<String> imagesEncodedList;
Run Code Online (Sandbox Code Playgroud)

让我们假设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);
Run Code Online (Sandbox Code Playgroud)

然后你应该覆盖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);
}
Run Code Online (Sandbox Code Playgroud)

注意: 图库不能让您选择多图像,所以我们在这里打开所有图像工作室,您可以从中选择多图像.并且不要忘记向清单添加权限

非常重要: getData(); 得到一个单一的图像,我把它存储在imageEncoded String中,如果用户选择多个图像,那么它们应该存储在列表中

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

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

  • Uri uri = content://com.android.providers.media.documents/document/image%3A772 uri有数据,但是cursor.getString对我返回null imageEncoded = cursor.getString(columnIndex); (8认同)
  • 它很有用,但我必须补充getPath的这些函数:http://stackoverflow.com/a/20559175/6141959 (2认同)

R4j*_*R4j 20

我希望这个答案不会迟到.因为图库窗口小部件默认情况下不支持多选,但您可以自定义接受多选意图的gridview.另一个选项是扩展库视图并添加您自己的代码以允许多个选择.
这是简单的库可以做到的:https://github.com/luminousman/MultipleImagePick

更新:
来自@ ilsy的评论,这个库中的CustomGalleryActivity使用manageQuery,不推荐使用,所以它应该改为getContentResolver().query()并且cursor.close()喜欢这个答案

  • 回答问题永远不会太迟; 你帮了我! (7认同)

Mir*_*ole 17

很多这些答案有相似之处,但都缺少这是最重要的部分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
Run Code Online (Sandbox Code Playgroud)

获取所有图像的代码:

@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)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,Android的选择器在某些设备上提供了照片和图库.照片允许选择多个图像.Gallery一次只允许一个.

  • 在某些三星设备中,结果将与非三星设备不同。如果用户选择多个文件,“getData()”有时不会为空,但只有一个 Uri。如果您想在用户选择多个文件时进行处理,请在“getData()”之前检查“getClipData()”——如果剪辑数据不为空,则用户可能选择了多个图像。在 getData 之前处理 getClipData 但处理两种情况对于支持不同设备同时仍允许多个 Uris 非常重要。 (2认同)

Has*_*ter 7

初始化实例:

private String imagePath;
private List<String> imagePathList;
Run Code Online (Sandbox Code Playgroud)

onActivityResult你要写这个,If-else 2 块。一个用于单个图像,另一个用于多个图像。

private String imagePath;
private List<String> imagePathList;
Run Code Online (Sandbox Code Playgroud)

最重要的部分,从 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮到你。


Vin*_*nce 6

2022 - Android Jetpack Compose 方式

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

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

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

例如 :

Button(onClick = { launcherMultipleImages.launch("image/*") }) {
    Text(text = "Select images")
}
Run Code Online (Sandbox Code Playgroud)