Android गैलरी से कई छवियों का चयन करें


114

तो मूल रूप से जो मैं हासिल करने की कोशिश कर रहा हूं वह Galleryएंड्रॉइड में खुल रहा है और उपयोगकर्ता को चुनने दें multiple images। अब यह सवाल अक्सर पूछा जाता है, लेकिन मैं जवाबों से संतुष्ट नहीं हूं। मुख्य रूप से क्योंकि मुझे अपने आईडीई में डी डॉक्स में कुछ दिलचस्प मिला (मैं इस पर बाद में वापस आता हूं) और इस तरह मैं एक कस्टम एडॉप्टर का उपयोग नहीं करना चाहता, लेकिन सिर्फ वेनिला एक।

अब एक छवि चुनने के लिए मेरा कोड है:

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

अब एसओ और अन्य वेबसाइटों पर मौजूद लोग आपको बताएंगे कि आपके पास 2 विकल्प हैं:

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?




1
@KyleShank समाधान ने मेरे लिए काम किया। सेटिंग EXTRA_ALLOW_MULTIPLEआपको कई आइटम चुनने देती है। में getClipData()लौटे इरादे से कॉल करके URI प्राप्त करें onActivityResult। एकमात्र समस्या यह है कि गैलरी विजेट एकाधिक चयन की अनुमति नहीं देगा। उस स्थिति में किसी भी छवि पर क्लिक करने से आप चॉसर खत्म कर लेंगे और getDataलौटे इरादे से कॉल करके यूआरआई (सिंगल आइटम) प्राप्त कर सकते हैं
तनवीर आलम

जवाबों:


122

EXTRA_ALLOW_MULTIPLE विकल्प इरादे के माध्यम से Intent.putExtra () विधि पर सेट किया गया है:

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विकल्प केवल एंड्रॉइड एपीआई 18 और उच्चतर में उपलब्ध है।


मुझे यह पता है लेकिन जैसा कि मैंने अपने जवाब में उल्लेख किया है: "दुख की बात यह है कि मुझे यह नहीं मिल रहा है जहां Developers.android गाइड में है और यह भी INTENT वर्ग में एक निरंतर के रूप में परिभाषित नहीं है।" मेरा IDE Intent.EXTRA_ALLOW_MULTIPLE को नहीं पहचानता है। मेरे पास एपीआई स्तर 18 स्थापित है। मेरी आईडीई कहती है: "EXTRA_ALLOW_MULTIPLE को हल नहीं किया जा सकता है या यह एक क्षेत्र नहीं है"
डायोन सेग्निज

आशय .putExtra (Intent.EXTRA_ALLOW_MULTIPLE, सच); एमुलेटर का उपयोग करें, कई चयन का समर्थन न करें।
किनमियाओ

11
यह कई छवि का चयन। लेकिन गतिविधि परिणाम पर छवि url कैसे प्राप्त करें ????
जॉन

4
यह छवि पिकर लॉन्च करता है और मुझे कई छवियों का चयन करने की अनुमति देता है, लेकिन मुझे नहीं पता है कि onActivityResult में यूआरएल कैसे प्राप्त करें।
टॉम किनकैड

5
आप परिणाम में urls प्राप्त कर सकते हैं Intent.getClipData। इसमें क्लिपडेटा आइटम की सरणी है।
टैम ह्यहन्ह

71

कक्षा में इन चरों को परिभाषित करें:

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

मान लें कि एक बटन पर क्लिक करें यह छवियों का चयन करने के लिए गैलरी खोलना चाहिए

 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 (); एक एकल छवि प्राप्त करने के लिए और मैंने इसे यहां संग्रहीत किया है इमेजकोडेड स्ट्रिंग यदि उपयोगकर्ता बहु-छवियों का चयन करता है, तो उन्हें सूची में संग्रहीत किया जाना चाहिए

तो आपको यह जांचना होगा कि दूसरे का उपयोग करने के लिए कौन सा शून्य है

काश आपके पास एक अच्छी कोशिश और दूसरों के लिए होती


मैंने "आशय.सेटटाइप (" छवि / * ") को छोड़ दिया;" और यह उपयोगकर्ताओं को सीधे गैलरी में जाने के बजाय उपयोगकर्ता को फोटो भेजने के लिए भेजता है जो मल्टी-पिक्स चयन की अनुमति नहीं देता है। निश्चित नहीं है कि अगर इसकी वजह से है, तो मेरा गेटडाटा () कभी भी अशक्त नहीं रहता है, इसलिए मैंने विशेष रूप से सिंगल और मल्टीपल छवि चयन दोनों के लिए गेटक्लिपडाटा का उपयोग करना समाप्त कर दिया।
जॉनी वू

1
केवल भाग data.getClipData का उपयोग करें () पर्याप्त है, data.getData () की जांच करने की कोई आवश्यकता नहीं है
truongnm

&& null! = data ??
ओडेम

8
उरी उरई = सामग्री: //com.android.providers.media.documents/document/image%3A772 uri में डेटा है, लेकिन कर्सर.getString मेरे लिए रिटर्न null है इमेज ऑनकोड = कर्सर .getString (columnIndex);
मुहम्मद ज़ुबैर अशरफ़

2
यह उपयोगी था, लेकिन मुझे getPath के लिए इन कार्यों के साथ पूरक करना पड़ा: stackoverflow.com/a/20559175/6141959
Geynen

30

इनमें से बहुत से जवाबों में समानता है लेकिन सभी सबसे महत्वपूर्ण हिस्सा याद कर रहे हैं जो 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)
            }
        }
    }
}

ध्यान दें कि एंड्रॉइड के चयनकर्ता के पास कुछ उपकरणों पर फ़ोटो और गैलरी उपलब्ध हैं। तस्वीरें कई छवियों को चुनने की अनुमति देती हैं। गैलरी एक समय में सिर्फ एक की अनुमति देता है।


getClipData () क्या है? data.getData पर्याप्त नहीं है?
आदि

1
कुछ सैमसंग उपकरणों में, परिणाम गैर-सैमसंग उपकरणों की तुलना में अलग होंगे। यदि उपयोगकर्ता कई फ़ाइलों का चयन करता है, getData()तो कभी-कभी शून्य नहीं होगा , लेकिन केवल एक उड़ी होगी। यदि आप संभालना चाहते हैं जब कोई उपयोगकर्ता कई फ़ाइलों का चयन करता है, तो getClipData()पहले जांचें getData()- यदि क्लिप डेटा शून्य नहीं है, तो उपयोगकर्ता ने कई छवियों का चयन किया हो सकता है। GetData से पहले getClipData को संभालना, लेकिन दोनों मामलों को संभालना विभिन्न उपकरणों के समर्थन के लिए महत्वपूर्ण है जबकि अभी भी कई Uris की अनुमति है।
मीरा_कॉले

@Mira_Code मैं चयनित छवियों को विभिन्न छवि दृश्यों में कैसे सेट कर सकता हूं।
हसनैन घीस

20

मुझे आशा है कि यह उत्तर देर से नहीं आएगा। क्योंकि गैलरी विजेट डिफ़ॉल्ट रूप से कई चयन का समर्थन नहीं करता है, लेकिन आप ग्रिडव्यू को कस्टमाइज़ कर सकते हैं जिसने आपके बहुस्तरीय इरादे को स्वीकार किया है। दूसरा विकल्प गैलरी दृश्य का विस्तार करना और कई चयन की अनुमति देने के लिए अपने स्वयं के कोड में जोड़ना है।
यह सरल पुस्तकालय यह कर सकता है: https://github.com/luminousman/MultipleImagePick

अपडेट :
@ ilsy की टिप्पणी से, इस पुस्तकालय के उपयोग में CustomGalleryActivity , जिसे अपदस्थ किया manageQueryगया है, इसलिए इसे इस उत्तर में बदलना getContentResolver().query()और cursor.close()पसंद करना चाहिए


@ R4j हां और मैंने इसके बारे में लिखा है: पुस्तकालय परियोजनाओं में उपयोग के लिए तैयार नहीं है। इसका उपयोग शुरू करने के लिए कई अपडेट की आवश्यकता है। और आपके अपडेट के बारे में: getContentResolver().query()UI थ्रेड में उपयोग न करें । लोडर और समर्थन लाइब्रेरी के बारे में पढ़ें।
mbelsky

.cacheOnDisc()यह भी बदल दिया तो यह .cacheOnDisc(true)बूलियन परम के साथ बदल
प्रतिक बुटानी

5

प्रारंभिक उदाहरण:

private String imagePath;
private List<String> imagePathList;

में onActivityResult आप इस, तो-और कुछ 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();
    }
}

आशा है इससे आपको सहायता मिलेगी।


1

मैं अशक्त हो गया 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();
                            }

                        }
                    }

                }

            }

        }

    }

}

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


1
अगर यह काम करता है तो ठीक है। इसका अच्छा तरीका यह है कि आप डिप्रेस्ड कोड को इंगित कर सकते हैं, लेकिन जब तक आप इसका उपयोग कर रहे हैं बिना किसी समस्या के इसका उपयोग करने के लिए ठीक है। यह जानना महत्वपूर्ण है कि इसका पदावनत क्यों किया गया, चाहे यह सुरक्षा के मुद्दे हों, नया कोड अधिक कुशल हो, आदि। लेकिन चूंकि एंड्रॉइड ऐप्स आगे हैं संगत अपग्रेडित कोड अभी भी भविष्य में काम करेगा।
जेस्टेफन

0

मेरा भी यही मुद्दा था। मैं भी चाहता था ताकि उपयोगकर्ता गैलरी से फ़ोटो लेने के दौरान आसानी से फ़ोटो ले सकें। ऐसा करने का मूल तरीका नहीं मिल सका इसलिए मैंने एक ओपनसोर्स प्रोजेक्ट बनाने का फैसला किया। यह मल्टिपलमैजिक की तरह है लेकिन इसे लागू करने का सिर्फ बेहतर तरीका है।

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) ( काम)।


भले ही जोड़ा गया मुझे कई छवियों का चयन न करने देंintent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
बिच्छू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.