Below is code which I wrote for pick files from my application
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("*/*");
intent.putExtra("return-data", true);
This code works fine when I pick files through other file manager apps installed. But while picking a file from Recent category it fails while converting selected file Uri to absolute path.
Uri selectedImage = intent.getData();
String[] filePathColumn = {MediaStore.Files.FileColumns.DATA};
Cursor cursor = context.getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
In the above code I get picturePath as null whenever I choose file from Recent category. Please help me with this.
But while picking a file from Recent category it fails while converting selected file Uri to absolute path
A Uri is not a file. There is no reliable means of "converting selected file Uri to absolute path". Please use ContentResolver and openInputStream() to use the content backed by the Uri, just like how use an HTTP client API (e.g., HttpUrlConnection) to use the content backed by a URL.
Related
I am testing app on nexus 5 which has marshmallow version of android. I am looked into several method to get file path from uri but all the time it returns null. This method works for me on jelly bean and also on kitkat but not on marshmallow.
public String getPath(Uri uri) {
Log.d(TAG,"Uri GET PATH "+uri);
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
Log.d(TAG,"Cursor value "+cursor);
int Column_Index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
Log.d(TAG,"Column Index "+Column_Index);
cursor.moveToFirst();
String ImagePath = cursor.getString(Column_Index);
Log.d(TAG,"ImagePath of "+ImagePath);
cursor.close();
return ImagePath;
}
I also tried this this and also so many others but getting file path from uri is always null.
Uri return from Intent:content://com.android.providers.media.documents/document/image%3A2304`
I am looked into several method to get file path from uri but all the time it returns null
There is no file path. A Uri is not a file.
Use a ContentResolver and openInputStream() to get an InputStream on the content identified by the Uri. Either use that InputStream directly, or use it and a FileOutputStream on some file that you control (e.g., in getCacheDir()) to copy the content to the file, then use the resulting file.
I have a method below:
private String getRealPathFromUriForVideos(Uri selectedVideoUri) {
String wholeID = DocumentsContract.getDocumentId(selectedVideoUri);
String id = wholeID.split(":")[1];
String[] column = { MediaStore.Video.Media.DATA };
String sel = MediaStore.Video.Media._ID + "=?";
Cursor cursor = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ id }, null);
String filePath = "";
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
}
This works just fine getting the file for videos that hte user selects. However, I want to allow users to also create new videos (from my app) and then get the URI and the file from there. The URI for newly created videos is: content://media/external/video/media/41. For selected videos is like content://com.android.providers.media.documents/document/video%3A42.
It works with the second one but not the first one. First one I get IllegalArgumentException because its not a document URI. How can I get the file from the first URI?
This works just fine getting the file for videos that hte user selects
It may work in a few situations. It will not work in general. A Uri that you get from something like ACTION_OPEN_DOCUMENT does not have to represent a file, let alone one that you can access via the filesystem, let alone one that this script-kiddie algorithm will let you access.
The URI for newly created videos is: content://media/external/video/media/41
Not necessarily. I suppose that there is a way that you get a Uri like that for a recorded video, though off the top of my head I cannot think of a recommended way that would give you such a Uri. If you are using MediaRecorder or ACTION_VIDEO_CAPTURE, you create your own file (and, for ACTION_VIDEO_CAPTURE, your own Uri for that file). And, if you are creating your own file, you know where that file is.
Need to be able to upload to my server
For the video, record to a file that you control, then use that file.
Use some library that lets you upload from a Uri or InputStream. Otherwise:
Use ContentResolver and openFileInput() to get an InputStream on the content represented by the Uri
Create a FileOutputStream on some file that you control (e.g., in getCacheDir())
Copy the content from the InputStream to the OutputStream
Use your copy for the upload
Delete your copy when the work is done
You treat a foreign Uri as if it were a URL to a Web server: stream the content.
Seems to get it from the second URI I need this:
private String getRealPathFromUriForImagesAndVideo(Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = {MediaStore.Images.Media.DATA};
cursor = getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} catch (Exception e) {
return contentUri.getPath();
} finally {
if (cursor != null) {
cursor.close();
}
}
}
I am trying to get the full path of a sound file on the SD card.
This launches sound picker - I then use the Play Music app to select a file
Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setData(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RESULT_SOUNDPICKER);
On activity result I am trying to get the full path
case RESULT_SOUNDPICKER: {
Log.d("TAG", "onActivityResult "+requestCode+" "+resultCode);
if (resultCode == RESULT_OK)
{
Uri uri = data.getData();
String filePath = uri.getPath();
Log.d("TAG", "FilePath: "+filePath);
// A song was picked.
Log.d("TAG", "PickSongActivity.onActivityResult: "+data.getDataString());
}
}
But this returns a path like
//media/external/audio/media/13085
Rather than a proper path of where the file is held.
I need to get the full path back as I then want to use it to play the file.
Thank you.
Solution
This method can be used to get the full path.
private String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
CursorLoader loader = new CursorLoader(getApplicationContext(), contentUri, proj, null, null, null);
Cursor cursor = loader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
I need to get the full path back as I then want to use it to play the file.
There may not be a path (as it does not have to be a file), let alone a path that you can reach (as the file does not have to be on storage that is accessible to you).
MediaPlayer can use a Uri directly, so I suggest going that route.
i am implementing the functionality to save file in my app which is being sent by some exteral application.
i have provided support for single and mulitple files. Provided handling for all kind of files.
But i am not able to handle the following scenario.
I view a file from an email client -> View it in QuickOffice -> Click on send -> Choose my app->Then click on save in my app.
In that i get the path in following wrapped in the exception
java.io.FileNotFoundException: /file:/data/data/com.qo.android.sp.oem/files/temp/Error.log: open failed: ENOENT (No such file or directory)
I have seen this post which is quite useful for handling uri which has content scheme
Get filename and path from URI from mediastore
Below is my code
Uri uri = (Uri) iterator.next();
if ("content".equals(uri.getScheme())) {
filePath = getFilePathFromContentUri(uri, hostAcitvity.getContentResolver());
}
else {
filePath = uri.getPath();
}
fileName = uri.getLastPathSegment();
fileSize = hostAcitvity.getContentResolver().openInputStream(uri).available();
Code for getFilePathFromContentUri
private String getFilePathFromContentUri(Uri selectedVideoUri, ContentResolver contentResolver)
{
String filePath;
String[] filePathColumn = { MediaColumns.DATA };
Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filePath = cursor.getString(columnIndex);
cursor.close();
return filePath;
}
Then i wrap the path in a FileInputStream which is throwing the above exception
Not able to resolve the file path properly. Is this the correct way of finding the path ?
cheers,
Saurav
I have seen this post which is quite useful for handling uri which has content scheme
That never worked reliably and will work even less reliably in the future.
Is this the correct way of finding the path ?
No, because there is no requirement that every Uri map to a path on a filesystem that you can access.
Use getInputStream() on ContentResolver to get an InputStream on the Uri, and consume the data that way.
I am having a problem capturing an image from the built-in camera app on the Samsung Galaxy S.
I have a button on my app that when pressed launches the camera:
ContentValues values = new ContentValues();
values.put(Images.Media.MIME_TYPE, "image/jpeg");
mPicUri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mPicUri.getPath());
startActivityForResult(intent, REQ_CODE_TAKE_PIC);
From what I read on the interwebz, I can get the full-sized just-taken picture using the URI I passed to the intent. And so I have this on my onActivityResult:
Uri selectedImage = mPicUri;
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
And then using the variable filePath, I set the image in an ImageView. I am getting no image, and when I stepped through the code, I found out that BitmapFactory.decodeFile() is returning null.
Bitmap chosenPic = BitmapFactory.decodeFile(filePath);
So I tried a little more debugging. I found out that mPicUri returns a seemingly valid URI, such as: content://media/external/images/media/90. After the picture is taken and the user chooses to save the picture, the cursor resolves to the following filePath: /sdcard/DCIM/Camera/1285601413961.jpg. No bitmap is decoded though, BUT when I looked through the gallery, the picture I just took is there. So I tried to take a look at the URI of that picture, and this is what I got:
URI is: content://media/external/images/media/91
File path is: /sdcard/DCIM/Camera/2010-09-27 23.30.30.jpg
And so, it looks like the value I got from mPicUri is not the final URI that will be used.
Am I missing a step here? All I really want to do is retrieve the file of the just-taken picture.
Thanks in advance,
Zarah.
Did you try to specify File in both cases before taking picture and the same after?
public static File getTempFile() {
//it will return /sdcard/image.jpg
final File path = new File(Environment.getExternalStorageDirectory(), "MyApp");
if (!path.exists()) {
path.mkdir();
}
return new File(path, "image.jpg");
}
I'm using this function to get and set file path.