In my project i need a way of get the path of several images selecteds from the gallery.
I´m using this library MultipleSelectImages
It´s apparently work fine, but in the onActivityResult i need the array with the path of each image, however the result I get is this:
Paths: [com.darsh.multipleimageselect.models.Image#1e6d3057, com.darsh.multipleimageselect.models.Image#33824744]
...when i need the real path (/storage/emulated/0/DCIM/Camera/20150426_110936.jpg)
Reading the doc of the library don´t found solution.
This is the onActivityResult method:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == Constants.REQUEST_CODE && resultCode == RESULT_OK && data != null) {
//The array list has the image paths of the selected images
ArrayList<Image> images = data.getParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES);
Log.i("myLogs", "Paths:" + " " + images);
}
}
...Where "image" it´s imported from the library
import com.darsh.multipleimageselect.models.Image;
I´m not using EXTRA_ALLOW_MULTIPLE because need that the app works in android api 16 version
Thanks in advanced.
Try to use below code;
onActivityResult();-
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String imgPath = cursor.getString(columnIndex);
cursor.close();
Related
I'm using an image picker intent, to allow users to choose an image from their gallery, I get it's path, and pass it then to a 3rd library.
It's working fine for most of the cases, but if I picked up an image from Google Photos (an image that is stored online) I get a null path, though that I get valid URI for both of the working and not working images.
Here is my Intent call:
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RESULT_LOAD_IMAGE);
and here is onActivityResult:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Uri uri = data.getData();
Log.e(getClass().getName(),"file uri = " + uri);
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(uri, projection,
null, null, null);
if(cursor == null) return;
Log.e(getClass().getName(),"file cursor = " + cursor);
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
Log.e(getClass().getName(),"file columnIndex = " + columnIndex);
cursor.moveToFirst();
// The crash happens here
String photoPath = cursor.getString(columnIndex);
Log.e(getClass().getName(),"file photo path = " + photoPath);
cursor.close();
cropImage(photoPath);
}
And here are the logs for working and not-working image:
Working image:
file uri = content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F105681/ORIGINAL/NONE/187859359
file cursor =
android.content.ContentResolver$CursorWrapperInner#8953964
file columnIndex = 0
file photo path = /storage/emulated/0/DCIM/Camera/IMG_20190523_184830.jpg
Not working image:
file uri =
content://com.google.android.apps.photos.contentprovider/0/1/mediakey%3A%2Flocal%253A4574915c-b4ac-40af-bc08-b1004670cab2/ORIGINAL/NONE/477302338
file cursor =
android.content.ContentResolver$CursorWrapperInner#59448a4
file columnIndex = 0
file photo path = null
If there isn't way to avoid that error, is there a way instead to hide photos that are stored online and only show local ones?
The technique in your question has (at least) three problems:
Not every MediaStore entry has a value for DATA, as you're seeing
Not every non-null DATA value represents a filesystem path that you can access, as the MediaStore can get to content that you can't
The DATA column is not available on Android Q and higher
In your case, the uCrop library accepts a Uri. Well-written Android libraries know how to handle a Uri, so you can just hand the Uri over to the library and it will take it from there.
I have tried to modify on able to select multiple photo in album but the result just allowed me to select single photo. And I want to know that is it possible to store the selected multiple photo into Bitmap array so that I can call a function like save Image with using the bitmap array. Please help me. Thanks.
case R.id.bupload:
Intent pics=new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pics.setType("image/*");
pics.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(pics,RESULT_LOADS_IMAGE);
break;
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==RESULT_LOADS_IMAGE && resultCode==RESULT_OK && null!=data)
{
Uri selectedImage=data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor=getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex=cursor.getColumnIndex(filePathColumn[0]);
String picturePath=cursor.getString(columnIndex);
cursor.close();
Bitmap myselectedImage=BitmapFactory.decodeFile(picturePath);
wphoto.setImageBitmap(myselectedImage);
}
}
I have the codes work for loading images from the gallery but I really do not understand how it works. Here are the codes.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) { //Browse Gallery is requested
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
loadImage(picturePath); //load picture according the path
image_View.setImageBitmap(pic); //Show the selected picture
}
}
Uri selectedImage = data.getData();
Get the uri of selected image from intent
String[] filePathColumn = { MediaStore.Images.Media.DATA };
MediaStore.Images.Media.DATA is constant. I do not understand why do not use String instead of String[]
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
I do not understand this line.
cursor.moveToFirst();
Move to the first picture in Gallery.
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
For this one, I always get 0 no matter which picture I choose.
String picturePath = cursor.getString(columnIndex);
Since columnIndex is always 0, then how can it get a different path for different pictures?
Can anyone help me to check whether my explanation is correct and explain the line that I do not understand? Thanks.
1-
Uri selectedImage = data.getData();
This is the statement where you need to read the data passed through another intent which you called earlier via startActivityForResult method. In this case probably you open an intent and let the user select an image, then the URI of the image will be returned to you and you use getData to read that.
2-
String[] filePathColumn = { MediaStore.Images.Media.DATA };
When you want cursors to read something a Content Provider (via ContentResolver) you need to specify which columns you need to read from the database, and the argument you need to pass should be an array of String (whether it has one or more columns you still need to pass an array). MediaStore.Images.Media is a Database Contract which contains constants which you need to use to talk to Content Providers
3-
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
Cursors are used for reading data from Content Providers. If you are familiar with other programming languages it is like reading rows from database and your results are stored in Cursors. When you pass URI, you don't need to specify which database to read, ContentResolver will find that out for you (this is an advantage of using content providers)
4-
cursor.moveToFirst();
When you read the desired rows from the database (in this case probably you just selected one image), you need to move the cursor to point to the first entry (row) of the returned results
5-
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
You need to know which column you need to access to read your desired data (in this case file path name). so you ask cursor what is the column index of the file pathname and it will return you the column index. and of course in this case it will be always 0 because you only asked the content provider to return one column (file pathname) so there would be no more data to show other than that
6-
String picturePath = cursor.getString(columnIndex);
and finally this statement asks cursor to get the file pathname located at the index (in this case index 0) so at the end you have your path to file. Note that you can read only one picture data at a time with this method
Cursors store query result records in rows and grant many methods to access and iterate through the records. Also int columnIndex = cursor.getColumnIndex(filePathColumn[0]); is the reason why you always get 0 for your index
For query I need get _id, last digital from path
On my android 4.4 I see in debugger that mp3 path looks like: content://com.android.providers.media.documents/document/audio:10719 and I try to get real path as:
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == REQUEST_MUSIC_GET && resultCode == RESULT_OK){
Uri urri = data.getData();
String[] musIdAr=urri.getPath().split(":");
String orderBy = MediaStore.Audio.Media.DATA + " DESC";
Cursor cr = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null,"_id = ?",new String(musIdAr{musIdAr.length-1]},orderBy);
cr.moveToFirst();
String src=cr.getString(1);//real path id
cr.close();
initPlayer();
}
}
It works good,
but on android 4.3 I see that path looks like content://media/external/audio/media/900
without audio:10719 - it dosn't work
Is there universal way to get real path?
I am loading pictures in listview taken from camera and directly from gallery. On emulator images from gallery works perfect. But on device when i select first picture it works good. But when i select same picture second time application crashes and no logcat appears.
here is a code:
if (requestCode == UploadFile && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
Bitmap image=(BitmapFactory.decodeFile(picturePath));
cursor.close();
addattachmentsToListView(image);
Normally if it breaks without log you can try to debug it via the Eclipse debugger or similar, may be an option to better understand whats happening.
As far as i can see, your code seems to depend on the fact that there will always be a correct response with at least one result and the [0] column of that result valid.