Converting file:// scheme to content:// scheme - android

I am running to the problem with using Droid X's Files app and Astro file manager to select an image file. This two apps return the selected image with the scheme "file://" while Gallery returns the image with the scheme "content://". How do I convert the first schema to the second. Or how do I decode the image with the second format?

You probably want to convert content:// to file://
For gallery images, try something like this:
Uri myFileUri;
Cursor cursor = context.getContentResolver().query(uri,new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
if(cursor.moveToFirst())
{
myFileUri = Uri.parse(cursor.getString(0)).getPath();
}
cursor.close

Here, the problem is that, for all files we can't have a content Uri (content://). Because content uri is for those files which are part of MediaStore. Eg: images, audio & video.
However, for supported files, we can find its absolute path. Like for images as follows-
File myimageFile = new File(path);
Uri content_uri=getImageContentUri(this,myimageFile);
The generic method is as follows.
public static Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (imageFile.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}}

Use ContentResolver.openInputStream() or related methods to access the byte stream. You shouldn't generally be worrying about whether it is a file: or content: URI.
http://developer.android.com/reference/android/content/ContentResolver.html#openInputStream(android.net.Uri)

Related

Android - Get absolute file path from uri, picked from Downloads

I am trying to get the absolute file path from the uri. But can't get it for the files downloaded with some download manager.
For example, I have downloaded an audio and stored it in /storage/emulated/0/MIUI/.ringtone/Our Street (30-secs version)_&_7f2f552b-b5b8-41a0-94de-4b3b065b7c00.mp3. If I pick this file from Downloads section of file picker I got the following uri content://com.android.providers.downloads.documents/document/19 and I can not calculate the absolute path from this uri.
But if I pick the file from original directory i.e /storage/emulated/0/MIUI/.ringtone/ I got this uri content://com.android.externalstorage.documents/document/primary%3AMIUI%2F.ringtone%2FOur%20Street%20(30-secs%20version)_%26_7f2f552b-b5b8-41a0-94de-4b3b065b7c00.mp3 and I can get the absolute file path from this url.
How could I get the absolute file path while picked from Downloads?
I am opening file picker using following code:
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
chooseFile.setType("*/*");
chooseFile.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,false);
startActivityForResult(Intent.createChooser(chooseFile, "Select Audio"), PICK_AUDIO_RESULT_CODE);
For parsing absolute file path from uri I'm using following code:
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)
);
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection,
selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;

How to get path of media files in android

I want paths of files shared through share intent from any app. I do get path of files like zip, apk, pdf, etc. with code ShareCompat.IntentReader.from(this).getStream().getPath();.
But but I don't get path for image, video and audio files I get content://media/external/video/media/40666, How to get real path of files of this type?
If all you want is the path, you can use the following code
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = getContentResolver().query(contentUri, null, null, null, null);
cursor.moveToFirst();
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":")+1);
cursor.close();
cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,null
, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
return path;
}
It basically uses he ContentResolver to get the data of the file.
You can change the query parameters to get what you want.
Or you can use
getContentResolver().openInputStream(uri)
If you want the entire file

Open a Google Drive File Content URI after using KitKat Storage Access Framework

I am using the Storage Access Framework for android 4.4 and opening the file picker.
Everything works except when choosing a file from Google Drive, I can only figure out how to open it as an input stream, but I would like to get a java File object.
The content uri that's being returned looks something like this: content://com.google.android.apps.docs.storage/document/acc%3D4%3Bdoc%3D2279
Other questions that are similar but do not have a working solution which allows me to get the filename, filesize and contents:
Get real path from URI, Android KitKat new storage access framework
Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT
I've also looked into Paul Burke's FileChooser ( https://github.com/iPaulPro/aFileChooser) and this is the most common question on the issue's list.
How can I get a file from that content uri?
My current workaround is to write out a temporary file from an inputstream.
Thanks!
Ok. I found that the right way is to use the input stream from the other posts in conjunction with some data from the contentresolver.
For reference here are the hard to find android docs: https://developer.android.com/training/secure-file-sharing/retrieve-info.html
The relevant code to get mimetype, filename, and filesize:
Uri returnUri = returnIntent.getData();
String mimeType = getContentResolver().getType(returnUri);
Cursor returnCursor =
getContentResolver().query(returnUri, null, null, null, null);
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
TextView nameView = (TextView) findViewById(R.id.filename_text);
TextView sizeView = (TextView) findViewById(R.id.filesize_text);
nameView.setText(returnCursor.getString(nameIndex));
sizeView.setText(Long.toString(returnCursor.getLong(sizeIndex)));
And to get the file contents:
getContentResolver().openInputStream(uri)
Hope this helps someone else.
Adding to #Keith Entzeroth answer , after getting fileName, fileSize and Input Stream , this is way to get the file
public static File getFile(final Context context, final Uri uri) {
Log.e(TAG,"inside getFile==");
ContentResolver contentResolver = context.getContentResolver();
try {
String mimeType = contentResolver.getType(uri);
Cursor returnCursor =
contentResolver.query(uri, null, null, null, null);
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
String fileName = returnCursor.getString(nameIndex);
String fileSize = Long.toString(returnCursor.getLong(sizeIndex));
InputStream inputStream = contentResolver.openInputStream(uri);
File tempFile = File.createTempFile(fileName, "");
tempFile.deleteOnExit();
FileOutputStream out = new FileOutputStream(tempFile);
IOUtils.copyStream(inputStream,out);
return tempFile;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
this code solved my problem, when i tried to select image from google drive ,app get crashed ,
private void setImagePath(Intent data) throws Exception {
String wholeID="";
Uri selectedImage = data.getData();
if(Build.VERSION.SDK_INT<=Build.VERSION_CODES.JELLY_BEAN_MR2){
wholeID=getUriPreKitkat(selectedImage);
}else {
wholeID = DocumentsContract.getDocumentId(selectedImage);
}
// Split at colon, use second item in the array
Log.i("debug","uri google drive "+wholeID);
String id = wholeID.split(":")[1];
String[] column = {MediaStore.Images.Media.DATA};
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = getActivity().getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{id}, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
}

Cursor query from specific image folder, not load all image from sdcard

The code below will return all image from the SD card. But, I need to modify it so that it only display images from other folders.
Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
ContentResolver mContentResolver = mContext.getContentResolver();
Cursor mCursor = mContentResolver.query(mImageUri, null, null, null, null);
I have tried this:
String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/Testing/";
Uri uri = Uri.parse(path);
Cursor mCursor = mContentResolver.query(Uri, null, null, null, null);
and am getting an error. Any help would be appreciated.
Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
// field data which u need
final String[] columns = { MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_ADDED};
Cursor mCursor = mContentResolver.query(mImageUri, columns, MediaStore.Images.Media.DATA + " like ? ",new String[] {"%/YourFolderName/%"}, null);
ArrayList<String> fileNames =null
File path =
File(getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).path,
"Your Folder Name")
if (path.exists()) {
fileNames = path.getList() //you may need to to adjust the Data type of fileNames
}
So, now you have list of images path that you can pass on to recycler view using recycler view Adapter.

how update Android MediaStore after i move a JPG file

my app move .jpg file to others folders and to get viewable in the stock gallery i have sendBroadcast ACTION_MEDIA_MOUNTED
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" +
Environment.getExternalStorageDirectory() )));
but this take much time.. i have understand (maybe) that i have to update manually with cursor/contentResolver in mediaStore directly to get this faster. can anyone help me on this? thanks..
my code actually is:
Uri uri = (Uri) list.get(cont);
Cursor cursor = managedQuery(uri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String app = cursor.getString(column_index);
File orig = new File( app.toString());
File dest = new File( destination_path +"/"+ orig.getName().toString());
orig.renameTo(dest);
with this i move a file from a path to another one.
after this, to get images in gallery
i have to sendBroadcast ACTION_MEDIA_MOUNTED
I just had to do the same, use following to update the MediaStore:
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, newPath);
boolean successMediaStore = context.getContentResolver().update(
MediaStore.<TYPE>.Media.EXTERNAL_CONTENT_URI, values,
MediaStore.MediaColumns.DATA + "='" + oldPath + "'", null) == 1;
Replace <TYPE> with the correct media store... (Images, Video, Audio...)
Use the MediaScannerConnection to update the OS:
MediaScannerConnection.scanFile(this,
new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
// code to execute when scanning is complete
}
});

Categories

Resources