Android: Getting a file URI from a content URI?
Just use getContentResolver().openInputStream(uri)
to get an InputStream
from a URI.
http://developer.android.com/reference/android/content/ContentResolver.html#openInputStream(android.net.Uri)
How to convert a content Uri into a File
pass the Uri to another activity and retrieve it
Your other activity does not necessarily have rights to work with the content identified by the Uri
. Add FLAG_GRANT_READ_URI_PERMISSION
to the Intent
used to start that activity, and pass the Uri
via the "data" facet of the Intent
(setData()
), not an extra.
To get the actual Path of the Uri
First, there is no requirement that the Uri
that you get back be from the MediaStore
.
Second, managedQuery()
has been deprecated for six years.
Third, there is no requirement that the path that MediaStore
has be one that you can use. For example, the audio file might be on removable storage, and while MediaStore
can access it, you cannot.
How to convert a content Uri into a File
On a background thread:
- Get a
ContentResolver
by callinggetContentResolver()
on aContext
- Call
openInputStream()
on theContentResolver
, passing in theUri
that you obtained fromACTION_GET_CONTENT
, to get anInputStream
on the content identified by theUri
- Create a
FileOutputStream
on someFile
, where you want the content to be stored - Use Java I/O to copy the content from the
InputStream
to theFileOutputStream
, closing both streams when you are done
Android: How to convert File Uri to Content Uri
Use FileProvider to serve your file.
It gives nice uries.
FileProvider.getUriForFile().
You can serve all files except those from removable micro sd card.
Get content uri from file path in android
Try with:
ImageView.setImageURI(Uri.fromFile(new File("/sdcard/cats.jpg")));
Or with:
ImageView.setImageURI(Uri.parse(new File("/sdcard/cats.jpg").toString()));
Creating file from Uri
You can try this;
try {
Uri uri = data.getData();
String selectedFilePath = FilePath.getPath(getActivity(), uri);
final File file = new File(selectedFilePath);
new UploadFileToServer().execute(file);
}
catch (Exception e)
{
e.printStackTrace();
}
and define FilePath
class like this;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
public class FilePath {
/**
* Method for return file path of Gallery image/ Document / Video / Audio
*
* @param context
* @param uri
* @return path of the selected image file from gallery
*/
public static String getPath(final Context context, final Uri uri) {
// check here to KITKAT or new version
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/"
+ split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final 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;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] { split[1] };
return getDataColumn(context, contentUri, selection,
selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context
* The context.
* @param uri
* The Uri to query.
* @param selection
* (Optional) Filter used in the query.
* @param selectionArgs
* (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
public static String getDataColumn(Context context, Uri uri,
String selection, String[] selectionArgs) {
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;
}
/**
* @param uri
* The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri
.getAuthority());
}
/**
* @param uri
* The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri
.getAuthority());
}
/**
* @param uri
* The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri
.getAuthority());
}
/**
* @param uri
* The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri
.getAuthority());
}
}
Android: FileProvider.getUriForFile reading MediaStore-generated file?
Content uris does not have file-path or scheme. You should create an input stream and by using this inputstream create a temporary file. You can extract a file-uri or path from this file. Here is a function of mine to create a temporary file from content-uri:
fun createFileFromContentUri(fileUri : Uri) : File{
var fileName : String = ""
fileUri.let { returnUri ->
requireActivity().contentResolver.query(returnUri,null,null,null)
}?.use { cursor ->
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
cursor.moveToFirst()
fileName = cursor.getString(nameIndex)
}
// For extract file mimeType
val fileType: String? = fileUri.let { returnUri ->
requireActivity().contentResolver.getType(returnUri)
}
val iStream : InputStream = requireActivity().contentResolver.openInputStream(fileUri)!!
val outputDir : File = context?.cacheDir!!
val outputFile : File = File(outputDir,fileName)
copyStreamToFile(iStream, outputFile)
iStream.close()
return outputFile
}
fun copyStreamToFile(inputStream: InputStream, outputFile: File) {
inputStream.use { input ->
val outputStream = FileOutputStream(outputFile)
outputStream.use { output ->
val buffer = ByteArray(4 * 1024) // buffer size
while (true) {
val byteCount = input.read(buffer)
if (byteCount < 0) break
output.write(buffer, 0, byteCount)
}
output.flush()
}
}
}
--Edit--
Content Uri has path but not file path. For example;
content Uri path: content://media/external/audio/media/710 ,
file uri path : file:///sdcard/media/audio/ringtones/nevergonnagiveyouup.mp3
By using the function above you can create a temporary file and you can extract uri and path like this:
val tempFile: File = createFileFromContentUri(contentUri)
val filePath = tempFile.path
val fileUri = tempFile.getUri()
After using tempFile delete it to prevent memory issues(it will be deleted because it is written in cache ):
tempFile.delete()
There is no need to edit content uri. Adding scheme to content uri probably not gonna work
Convert file: Uri to File in Android
What you want is...
new File(uri.getPath());
... and not...
new File(uri.toString());
Notes
- For an
android.net.Uri
object which is nameduri
and created exactly as in the question,uri.toString()
returns aString
in the format"file:///mnt/sdcard/myPicture.jpg"
, whereasuri.getPath()
returns aString
in the format"/mnt/sdcard/myPicture.jpg"
. - I understand that there are nuances to file storage in Android. My intention in this answer is to answer exactly what the questioner asked and not to get into the nuances.
Related Topics
Dynamically Add and Remove View to Viewpager
How to Adjust Layout When Soft Keyboard Appears
Recommended Way/Order to Read Data from a Webservice, Parse That Data and Insert It in a SQLite Db
How to Pass the Values from One Activity to Previous Activity
How to Detect User Pressing Home Key in My Activity
Android Lollipop Change Navigation Bar Color
How to Calculate Distance Between Two Locations Using Their Longitude and Latitude Value
Actionbar Notification Count Icon (Badge) Like Google Has
How to Launch Activity Only Once When App Is Opened for First Time
Datepicker: How to Popup Datepicker When Click on Edittext
Listview Click to Show Image in Imageview
How to Implement Multi-Select in Recyclerview