In the android application, we need to pick any image from our gallery. For that android provides some in-built intent action that can fetch us image from gallery. After Android Kitkat, Google made few changes so that we can pick image from different applications.
The following code will open Default Picker app for KitKat, Lollipop, Marshmallow and Android N users and Gallery app for before Kitkat users to pick image.
Update:
The previous code sometimes failed to get image from external sdcard, Google Drive or sometime from internal storage too. So I did some research and integrate few answers from Stackoverflow and come up with a new solution which able to pick image from every things from that Default Picker App after Kitkat devices displayed in the image.
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); startActivityForResult(Intent.createChooser(intent, "Select Picture"), 1); } else { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), 1); }
Now after selecting image, we need to handle it properly to display it to ImageView or we need to get it’s path if we want to do any other operation on it. Here is the code for onActivityResult.
@TargetApi(19) @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (data != null && data.getData() != null && resultCode == RESULT_OK) { boolean isImageFromGoogleDrive = false; Uri uri = data.getData(); if (isKitKat && DocumentsContract.isDocumentUri(TestActivity.this, uri)) { if ("com.android.externalstorage.documents".equals(uri.getAuthority())) { String docId = DocumentsContract.getDocumentId(uri); String[] split = docId.split(":"); String type = split[0]; if ("primary".equalsIgnoreCase(type)) { imgPath = Environment.getExternalStorageDirectory() + "/" + split[1]; } else { Pattern DIR_SEPORATOR = Pattern.compile("/"); Set<String> rv = new HashSet<>(); String rawExternalStorage = System.getenv("EXTERNAL_STORAGE"); String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE"); String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET"); if(TextUtils.isEmpty(rawEmulatedStorageTarget)) { if(TextUtils.isEmpty(rawExternalStorage)) { rv.add("/storage/sdcard0"); } else { rv.add(rawExternalStorage); } } else { String rawUserId; if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { rawUserId = ""; } else { String path = Environment.getExternalStorageDirectory().getAbsolutePath(); String[] folders = DIR_SEPORATOR.split(path); String lastFolder = folders[folders.length - 1]; boolean isDigit = false; try { Integer.valueOf(lastFolder); isDigit = true; } catch(NumberFormatException ignored) { } rawUserId = isDigit ? lastFolder : ""; } if(TextUtils.isEmpty(rawUserId)) { rv.add(rawEmulatedStorageTarget); } else { rv.add(rawEmulatedStorageTarget + File.separator + rawUserId); } } if(!TextUtils.isEmpty(rawSecondaryStoragesStr)) { String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator); Collections.addAll(rv, rawSecondaryStorages); } String[] temp = rv.toArray(new String[rv.size()]); for (int i = 0; i < temp.length; i++) { File tempf = new File(temp[i] + "/" + split[1]); if(tempf.exists()) { imgPath = temp[i] + "/" + split[1]; } } } } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) { String id = DocumentsContract.getDocumentId(uri); Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); Cursor cursor = null; String column = "_data"; String[] projection = { column }; try { cursor = TestActivity.this.getContentResolver().query(contentUri, projection, null, null, null); if (cursor != null && cursor.moveToFirst()) { int column_index = cursor.getColumnIndexOrThrow(column); imgPath = cursor.getString(column_index); } } finally { if (cursor != null) cursor.close(); } } else if("com.android.providers.media.documents".equals(uri.getAuthority())) { String docId = DocumentsContract.getDocumentId(uri); String[] split = docId.split(":"); 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; } String selection = "_id=?"; String[] selectionArgs = new String[]{ split[1] }; Cursor cursor = null; String column = "_data"; String[] projection = { column }; try { cursor = TestActivity.this.getContentResolver().query(contentUri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { int column_index = cursor.getColumnIndexOrThrow(column); imgPath = cursor.getString(column_index); } } finally { if (cursor != null) cursor.close(); } } else if("com.google.android.apps.docs.storage".equals(uri.getAuthority())) { isImageFromGoogleDrive = true; } } else if ("content".equalsIgnoreCase(uri.getScheme())) { Cursor cursor = null; String column = "_data"; String[] projection = { column }; try { cursor = TestActivity.this.getContentResolver().query(uri, projection, null, null, null); if (cursor != null && cursor.moveToFirst()) { int column_index = cursor.getColumnIndexOrThrow(column); imgPath = cursor.getString(column_index); } } finally { if (cursor != null) cursor.close(); } } else if ("file".equalsIgnoreCase(uri.getScheme())) { imgPath = uri.getPath(); } if(isImageFromGoogleDrive) { try { Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri)); img.setImageBitmap(bitmap); } catch (Exception e) { e.printStackTrace(); } } else { File f = new File(imgPath); BitmapFactory.Options bmOptions = new BitmapFactory.Options(); Bitmap bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(),bmOptions); img.setImageBitmap(bitmap); } } super.onActivityResult(requestCode, resultCode, data); }
Here, images from Google Drive may not be on our device so we directly us InputStream of that image from the Google Drive and show it in the ImageView without getting it’s path. You can save it in your storage if you need to use it for any further requirement.
Please comments below if you find any mistake or having problem in implementing this code.
Download Source Code: https://github.com/dakshbhatt21/a-computer-engineer
Please upload full code with xml and java file for understanding how to use.
sure, I’ll update the post with the full source code in couple of days.
Hi there!
I just uploaded the full source code in Github, you can access it here https://github.com/dakshbhatt21/a-computer-engineer
Let me know if you need any further help.
I tried implementing this into my apps… But it causes the apps to crash whenever i pick any images… Any chance to repair it…?
Hi please check the storage permission in your manifest file. If your device has running Android Marshmallow then Google about “real time permission in Android”.
Or you can send me your logcat output or download the source code from github. You can find github link at the end of the article.
After lots of workaround… i manage to get it done… Thank you so much!!!! If there is any problem i will refer back to you..
Anyhow your coding is great and easy to understand…
Thank you Zabir! I’m glad that it helped you 🙂
Sure you can come here and comment if you have any problem.
thanks brother,was searching this for two days!
I’m glad that it helped you!