从android库中选择多个图像

问题描述 投票:91回答:10

所以基本上我想要实现的是在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。现在这是我将考虑的最后一个选项,因为我不是我要搜索的东西,因为我必须自己设计风格以及为什么你不能在香草画廊中选择多个图像?

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

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

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

后来他们在文档中说:

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

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

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

android image-gallery
10个回答
96
投票

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

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及更高版本。


-2
投票

具有多个图像选择动作的智能android库。

Check the demo on my blog

首先制作动作按钮,你可以将它用于单个/多个

对于单个图像选择: - - luminous.ACTION_PICK用于选择单个图像。

对于多个图像选择: - - luminous.ACTION_MULTIPLE_PICK用于选择多个图像。

multiple image pick in android geekonjava

main activity.Java

// For single image
Intent i = new Intent(Action.ACTION_PICK);
startActivityForResult(i, 100);

// For multiple images
Intent i = new Intent(Action.ACTION_MULTIPLE_PICK);
startActivityForResult(i, 200);

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == 100 && resultCode == Activity.RESULT_OK) {
            adapter.clear();

            viewSwitcher.setDisplayedChild(1);
            String single_path = data.getStringExtra("single_path");
            imageLoader.displayImage("file://" + single_path, imgSinglePick);

        } else if (requestCode == 200 && resultCode == Activity.RESULT_OK) {
            String[] all_path = data.getStringArrayExtra("all_path");

            ArrayList<CustomGallery> dataT = new ArrayList<CustomGallery>();

            for (String string : all_path) {
                CustomGallery item = new CustomGallery();
                item.sdcardPath = string;

                dataT.add(item);
            }

            viewSwitcher.setDisplayedChild(0);
            adapter.addAll(dataT);
        }
    }

在AndroidManifest.xml中

<activity android:name="CustomGalleryActivity" >
            <intent-filter>
                <action android:name="luminous.ACTION_PICK" />
                <action android:name="luminous.ACTION_MULTIPLE_PICK" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
 </activity>

60
投票

在类中定义这些变量:

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();得到一个单一的图像,我把它存储在imageEncoded String中,如果用户选择多个图像,那么它们应该存储在列表中

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

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


20
投票

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

更新: 从@ ilsy的评论来看,这个库中的CustomGalleryActivity使用的是manageQuery,这是不推荐使用的,所以它应该改为getContentResolver().query()cursor.close(),如this answer


14
投票

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

调用文件选择器的代码:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*"); //allows any image file type. Change * to specific extension to limit it
//**These 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的选择器在某些设备上提供了照片和图库。照片允许选择多个图像。 Gallery一次只允许一个。


2
投票

初始化实例:

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();
    }
}

希望这可以帮到你。


0
投票

嗨,下面的代码工作正常。

 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


0
投票

我也有同样的问题。我也希望用户可以在从画廊中挑选照片时轻松拍照。无法找到本地方式,因此我决定制作一个开源项目。它很像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;
    }
}

0
投票

试试这个IntentChooser。只需添加一些代码行,我就为您完成剩下的工作。

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);
    }
}

PS:正如上面的答案所述,EXTRA_ALLOW_MULTIPLE仅适用于API> = 18.而且某些图库应用程序无法使用此功能(Google照片和文档(com.android.documentsui)可用。


0
投票

我从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();
                            }

                        }
                    }

                }

            }

        }

    }

}
© www.soinside.com 2019 - 2024. All rights reserved.