Sunday, May 29, 2016

How to pick multiple files from Android's gallery via API? - UNDOCUMENTED

Google "How to pick multiple files from Android's gallery" and you'll get multiple Stack Overflow answers on how to do it, and just as many complaints that the "answer" does not work. At least not on many Samsung devices.

I implemented the standard answer:
         intent = new Intent(Intent.ACTION_GET_CONTENT);  
         intent.addCategory(Intent.CATEGORY_OPENABLE);  
         intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);  
         intent.setType("image/*");  

and on my Samsung device, I still could only select ONE photo!

Opening up the default email program though, I could use Gallery to select multiple photos. WTF!

Multiple Googling and still no luck!

Finally, out of desperation I decompiled SecGallery2013.apk from my phone. Low and behold there was a undocumented Action in the manifest:

"android.intent.action.MULTIPLE_PICK"

Using this action in my Intent I managed to get Android Gallery to go into multiple selection mode. Yay!

Now, onActivityResult returns a Intent with new extras: "selectedCount" and "selectedItems".

"selectedItems" returns to us a string array list of Uri's to the pictures!

So my code now looks like this:

To call the Gallery:

     findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {  
       @Override  
       public void onClick(View v) {  
         // Undocumented way to get multiple photo selections from Android Gallery ( on Samsung )  
         Intent intent = new Intent("android.intent.action.MULTIPLE_PICK");//("Intent.ACTION_GET_CONTENT);  
         intent.addCategory(Intent.CATEGORY_OPENABLE);  
         intent.setType("image/*"); 
         // Check to see if it can be handled...
         PackageManager manager = getApplicationContext().getPackageManager();  
         List<ResolveInfo> infos = manager.queryIntentActivities(intent, 0);  
         if (infos.size() > 0) {  
           // Ok, "android.intent.action.MULTIPLE_PICK" can be handled 
           action = "android.intent.action.MULTIPLE_PICK"; 
         } else {  
           action = Intent.ACTION_GET_CONTENT;
         /* This is the documented way you are to get multiple images from a gallery BUT IT DOES NOT WORK with Android Gallery! (at least on Samsung )  
           But the Android Email client WORKS! What the f'k!  
               */  
           intent.setAction(Intent.ACTION_GET_CONTENT);  
           intent.addCategory(Intent.CATEGORY_OPENABLE);  
           intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); // Note: only supported after Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT, harmless if used below 19, but no mutliple selection supported
         }  
         startActivityForResult(intent, 0xdead);  
       }  
     });  

And in the onActivityResult:

   @Override  
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
     if(action.equals("android.intent.action.MULTIPLE_PICK")){  
       final Bundle extras = data.getExtras();  
       int count = extras.getInt("selectedCount");  
       Object items = extras.getStringArrayList("selectedItems");  
       // do somthing  
     }else {  
       if (data != null && data.getData() != null) {  
         Uri uri = data.getData();  
         // do somthing  
       } else {  
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {  
           ClipData clipData = data.getClipData();  
           if (clipData != null) {  
             ArrayList<Uri> uris = new ArrayList<>();  
             for (int i = 0; i < clipData.getItemCount(); i++) {  
               ClipData.Item item = clipData.getItemAt(i);  
               Uri uri = item.getUri();  
               uris.add(uri);  
             }  
             // Do someting  
           }  
         }  
       }  
     }  
     super.onActivityResult(requestCode, resultCode, data);  
   }  

5 comments:

  1. Hi Jeff M, I am also facing the same problem in samsung mobile. Could you please explain detail usage of intent for multiple picture selection

    ReplyDelete
  2. Great post! Thanks
    "startActivityForResult(intent, 0xdead);" What is 0xdead?

    ReplyDelete
    Replies
    1. 0xdead is the result code passed to onActivityResult. Just a corney hex code... could be anything you want

      Delete
  3. How can we take the contents in the Uris and set them to a listview?

    ReplyDelete
  4. Hello. I will try... Does it really work? I am really tired of searching and testing with no results.. I hope it works, i will post the result...

    ReplyDelete