Get file path from content URI - android

I had this working at a time, but now it fails every time I try to get the file path. I am receiving the file from Acrobat Reader and can receive the file name and size, but not the relative file path.
My code looks like this:
if(uri.getScheme().equals("content"))
{
String[] dataFields = new String[]{
MediaStore.MediaColumns.DATA,
OpenableColumns.DISPLAY_NAME,
OpenableColumns.SIZE};
Cursor cursor = context.getContentResolver().query(uri, dataFields, null, null, null);
cursor.moveToFirst();
fileLocation = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA));
title = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
size = cursor.getInt(cursor.getColumnIndex(OpenableColumns.SIZE));
cursor.close();
contentType = context.getContentResolver().getType(uri);
}
I get the following error in LogCat:
Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 2 columns.
I understand it as it can't find the column. However, I don't understand how this can be?

A Uri is not a file. There is no requirement that the Uri be from MediaStore or otherwise have a MediaStore.MediaColumns.DATA column. If you want to access the content represented by the Uri, use openInputStream() on a ContentResolver.

Related

Get filename and path from URI from mediastore in Nought and Oreo device

I have image uri like this :"content://com.iceburgapp.provider/external_files/.pkgName/File1.jpg"
Now whenever I get path it give me : "/external_files/.pkgName/File1.jpg"
I want to get RealPathFrom content Uri.
I got solution from stackoverflow and I tried below code but not working for me :
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
AnyOne know How to do this? I got below error for using above code.
java.lang.IllegalArgumentException: column '_data' does not exist. Available columns: []
It's only not working in the Nought and oreo device because of contentUri using file provider.
Use a ContentResolver and openInputStream() to get an InputStream on the content identified by the Uri. Ideally, just use that stream directly, for whatever it is that you are trying to do. Or, use that InputStream and some FileOutputStream on a file that you control to make a copy of the content, then use that file.
This is working properly in devices before Android N

How do I get the file name from an Android URI, not just the display name?

so I'm pretty new to Android development. I'm trying to have the user select a song from their SD card or internal storage using a file manager and upload the file to a server. Right now, I'm just trying to access the name of the file that the user selected so that I can use it to access the contents of the file later and upload those contents.
I've looked at other posts concerning this and most of them tell you to query the content resolver and then use the cursor to grab the display name, but that does not always return the display name (this is mentioned in Google's guide to the SAF). It has not been returning the full file name, just part of it (the title of the song).
Here's my code that starts the intent:
Intent chooseIntent = new Intent(Intent.ACTION_GET_CONTENT);
chooseIntent.addCategory(Intent.CATEGORY_OPENABLE);
chooseIntent.setType("audio/*");
startActivityForResult(chooseIntent, SELECT_SONG_FILE_REQUEST_CODE);
How I'm getting the display name now:
String fileName = null;
if (uri.getScheme().equals("content")) {
try (Cursor cursor = getContentResolver().query(uri, null, null, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
fileName = cursor.getString(
cursor.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME));
Log.i(TAG, "Filename: " + fileName);
cursor.close();
}
}
}
How can I get the full file name rather than just the display name?
You also can use TITLE in Cursor as URI parameter to get the full name of file
use below code it
Cursor cursor = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,MediaStore.Audio.Media.TITLE, null, null, null);
Or You can use DATA to get Path of the file
Cursor cursor = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,MediaStore.Audio.Media.DATA, null, null, null);
All You have to do is let the user choose the music and after selecting with the use of DATA you have full path of song and with TITLE you have full name of file .
Next just upload it.
There are several things that you can do to improve the performance of the query
You are getting all the columns which can be painfully slow.
You can write code like the one below and then check what field you want to use. You will get all the data for all the audio files installed in the device. You can walk through this code in the debugger to see the data that you need.
{
Uri objUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
ContentResolver cr = context.getContentResolver();
String[] entityColumns = {MediaStore.Audio.AudioColumns.DATA,
MediaStore.Audio.AudioColumns.DISPLAY_NAME,
MediaStore.Audio.AudioColumns.TITLE};
cursor = cr.query(
objUri,
entityColumns,
null,
null,
null);
if (cursor != null && cursor.moveToFirst()) {
do {
String filePath = cursor.getString(cursor.getColumnIndex(entityCoumns[0]));
String fileName = cursor.getString(cursor.getColumnIndex(entityColumns[1]));
String fileTitle =
cursor.getString(cursor.getColumnIndex(entityColumns[2]));
} while (cursor.moveToNext());
cursor.close();
}
}

Intent.ACTION_GET_CONTENT opens recent files which gives a bad URI

I'm using Intent.ACTION_GET_CONTENT which opens recent files. Selecting items from the recent files gives a bad URI but selecting the same file from the file manager gives a right URI which can be handled by my code.
public static String getRealPathFromURI(Context context, Uri uri) {
String path;
if ("content".equals(uri.getScheme())) {
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
path = cursor.getString(idx);
cursor.close();
} else {
path = uri.getPath();
}
return path;
}
Note: The uri.getPath() output when I select a PDF from the recent files is /document/... but selecting the same file from the file manager is, .../emulated/....
Note: the error while selecting the file from the recent files is
Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
The problem was my code doesn't handle the new Layout Storage URIs of Android. If you face this problem too, please refer to this link because the writer is wrote a fantastic method to get real path of every URIs.

Extract file data when receiving ACTION_SEND in android

I can receive fileinfo in ACTION_VIEW like this:
String[] dataFileds = new String[]{
MediaStore.MediaColumns.DATA,
OpenableColumns.DISPLAY_NAME,
OpenableColumns.SIZE};
Cursor cursor = context.getContentResolver().query(uri, dataFileds, null, null, null);
cursor.moveToFirst();
fileLocation = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA));
title = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
size = cursor.getInt(cursor.getColumnIndex(OpenableColumns.SIZE));
cursor.close();
It has an URI that could look like this: content://downloads/all_downloads/387
My problem is when receiving a file through ACTION_SEND. Here I get an URI that look like this: file:///storage/emulated/0/Download/Arkitekturvalg.pdf
When I use the same code to get the file data, I get an null pointer error on cursor.
How will I be able to receive the file information when a user want to share a file to my app?
Note that bothe of the URIs is for the same file.
If the scheme of the Uri is file, then use getLastPathSegment() to get the "display name" (filename). Then, use new File(uri.getPath()).length() to get the length of the file.

MediaStore - Uri to query all types of files (media and non-media)

In the class MediaStore.Files class, its mentioned that,
Media provider table containing an index of all files in the media storage, including non-media files.
I'm interested in querying for non-media files like PDF.
I'm using CursorLoader to query the database. The second parameter for the constructor requires an Uri argument which is easy to get for the media types Audio, Images and Video as each of them have a EXTERNAL_CONTENT_URI and INTERNAL_CONTENT_URI constant defined for them.
For MediaStore.Files there is no such defined constant. I tried using the getContentUri() method but couldn't figure out the argument value for volumeName. I tried giving "/mnt/sdcard" and also the volume name that appears when I connect the device to my system but in vain.
I saw a similar question on Google Groups but that is not resolved.
EDIT: I also tried using Uri.fromFile(new File("/mnt/sdcard/")) and Uri.parse(new File("/mnt/sdcard").toString()) but that didn't work out either.
It is "external" or "internal" although internal (system files) is probably not useful here.
ContentResolver cr = context.getContentResolver();
Uri uri = MediaStore.Files.getContentUri("external");
// every column, although that is huge waste, you probably need
// BaseColumns.DATA (the path) only.
String[] projection = null;
// exclude media files, they would be here also.
String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_NONE;
String[] selectionArgs = null; // there is no ? in selection so null here
String sortOrder = null; // unordered
Cursor allNonMediaFiles = cr.query(uri, projection, selection, selectionArgs, sortOrder);
If you want .pdf only you could check the mimetype
// only pdf
String selectionMimeType = MediaStore.Files.FileColumns.MIME_TYPE + "=?";
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf");
String[] selectionArgsPdf = new String[]{ mimeType };
Cursor allPdfFiles = cr.query(uri, projection, selectionMimeType, selectionArgsPdf, sortOrder);

Categories

Resources