retrieve absolute path when select image from gallery kitkat android - android

As I am supporting my app to Kitkat version, now in this the way of retrieve file from gallery was different.
I have preferred this Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT for retrieving file from gallery and successfully work but I required Absolute path of that file, I am getting
content://com.android.providers.media.documents/document/image:2505
For 19 below version we used uri different by using that I am getting path this way
Cursor cursor = this.getContentResolver().query(originalUri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String fpath = cursor.getString(column_index);
but in 19 version it will give me null value how to get absolute path of image file which was selected by user.
Thanks

Here is one way to access the Absolute path after selecting file.
After getting data in new URI format for KK(KitKat) like this way
content://com.android.providers.media.documents/document/image:2505
Just extract ID of your document
if(requestCode == GALLERY_KITKAT_INTENT_CALLED && resultCode == RESULT_OK){
Uri originalUri = data.getData();
final int takeFlags = data.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// Check for the freshest data.
getContentResolver().takePersistableUriPermission(originalUri, takeFlags);
/* now extract ID from Uri path using getLastPathSegment() and then split with ":"
then call get Uri to for Internal storage or External storage for media I have used getUri()
*/
String id = originalUri.getLastPathSegment().split(":")[1];
final String[] imageColumns = {MediaStore.Images.Media.DATA };
final String imageOrderBy = null;
Uri uri = getUri();
String selectedImagePath = "path";
Cursor imageCursor = managedQuery(uri, imageColumns,
MediaStore.Images.Media._ID + "="+id, null, imageOrderBy);
if (imageCursor.moveToFirst()) {
selectedImagePath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
Log.e("path",selectedImagePath ); // use selectedImagePath
}else if() {
// for older version use existing code here
}
// By using this method get the Uri of Internal/External Storage for Media
private Uri getUri() {
String state = Environment.getExternalStorageState();
if(!state.equalsIgnoreCase(Environment.MEDIA_MOUNTED))
return MediaStore.Images.Media.INTERNAL_CONTENT_URI;
return MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}

Pratik's solution helped me alot. Following is the version which works for me in Kitkat 4.4.2. Three things which i changed are
1) Using content resolver to get the path
2) originalUri.getLastPathSegment().split(":")[1] gives me index out of bound so i'm using index 0 instead.Its been working so far
3) Removed takeflags and check for freshest data as we are filtering the cursor with id.
try {
Uri originalUri = data.getData();
String pathsegment[] = originalUri.getLastPathSegment().split(":");
String id = pathsegment[0];
final String[] imageColumns = { MediaStore.Images.Media.DATA };
final String imageOrderBy = null;
Uri uri = getUri();
Cursor imageCursor = activity.getContentResolver().query(uri, imageColumns,
MediaStore.Images.Media._ID + "=" + id, null, null);
if (imageCursor.moveToFirst()) {
value = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
} catch (Exception e) {
Toast.makeText(activity, "Failed to get image", Toast.LENGTH_LONG).show();
}

Perfectly working solution:
package utils;
/**
* Created by layer on 4/21/2015.
*/
import android.annotation.TargetApi;
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 ImageFilePath {
/**
* Method for return file path of Gallery image
*
* #param context
* #param uri
* #return path of the selected image file from gallery
*/
#TargetApi(Build.VERSION_CODES.KITKAT)
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());
}
}
https://github.com/layerlre/Android-Utility-Class/blob/master/utils/ImageFilePath.java
Hope works for you.

Bitmap bitmap = MediaStore.Images.Media
.getBitmap(getActivity().getContentResolver(), uri);
I hope that this will help you.

Related

How to get file path from URI in Android N

How can I get the file path from Uri when I open a video file from file explore.
Uri host is "content" and "_data" return null.
I want to get other videos in the same directory thus i have to get the file path.if have any other way to get videos in the same directory without file path,it also work for me.
Thanks a lot for your any ideas and solutions.
Try this code. It works for me in Oreo as well.
/**
* Method for return file path of Gallery image/ Document / Video / Audio
*
* #param context - context of the application or class
* #param uri - uri to get the path
* #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.
*/
private 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.
*/
private 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.
*/
private 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.
*/
private 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.
*/
private static boolean isGooglePhotosUri(Uri uri)
{
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
This code requires the READ_EXTERNAL_STORAGE permission:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
This permission should be requested from the user at runtime as it is a dangerous permission.
Activity code:
Uri muri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
muri = getUriForFile("your activity", BuildConfig.APPLICATION_ID + ".provider", "file path");
} else {
muri = Uri.fromFile("file path");
}

Getting null value while upload pdf file from device memory

In my application i want to upload pdf file from device. So for that i have followed bellow link
[Android: Browse and upload a PDF or word file in application from the device
By using this code, after select pdf file getting null value. This getFileNameByUri method return null vlaue. I dont know, what is the issue hare. So please suggest me.
Thanks In Advance...
This the code i am using...
private void getDocument()
{
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("application/pdf");
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
startActivityForResult(intent, 1);
}
And this is the onactivity result
#Override
protected void onActivityResult(int req, int result, Intent data)
{
// TODO Auto-generated method stub
super.onActivityResult(req, result, data);
if (result == RESULT_OK)
{
Uri fileuri = data.getData();
docFilePath = getFileNameByUri(this, fileuri);
}
}
And this is the method for file path..
private String getFileNameByUri(Context context, Uri uri)
{
String filepath = "";//default fileName
//Uri filePathUri = uri;
File file;
if (uri.getScheme().toString().compareTo("content") == 0)
{
Cursor cursor = context.getContentResolver().query(uri, new String[] { android.provider.MediaStore.Images.ImageColumns.DATA, MediaStore.Images.Media.ORIENTATION }, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String mImagePath = cursor.getString(column_index);
cursor.close();
filepath = mImagePath;
}
else
if (uri.getScheme().compareTo("file") == 0)
{
try
{
file = new File(new URI(uri.toString()));
if (file.exists())
filepath = file.getAbsolutePath();
}
catch (URISyntaxException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
filepath = uri.getPath();
}
return filepath;
}
here this method getFileNameByUri returns null value..
This will get the file path from the MediaProvider, DownloadsProvider, and ExternalStorageProvider, while falling back to the unofficial ContentProvider method you mention.
/**
* Get a file path from a Uri. This will get the the path for Storage Access
* Framework Documents, as well as the _data field for the MediaStore and
* other file-based ContentProviders.
*
* #param context The context.
* #param uri The Uri to query.
* #author paulburke
*/
public static String getPath(final Context context, final Uri uri) {
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];
}
// TODO handle non-primary volumes
}
// 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 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 column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_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());
}
These are taken from Paul Burke's answer

Get Audio Video Images From SdCard Android Requires Minimum sdk 19

I Am Working In A Project Where I Have To get audio, video , images from SdCard and upload to server
I get The Images Quite Easily but Issue Is With The Audio And Video . Where Cursor Return Null
I Have Android lollipop .
This Is Code :-
Cursor cursor = getActivity().managedQuery(selectedImageUri, projection, null,null, null);
int data_column_index = cursor.getColumnIndexOrThrow("_data");
int size_column_index = cursor.getColumnIndexOrThrow("_size");
int name_column_index = cursor.getColumnIndexOrThrow("_display_name");
It Returns null
Now I am using This :-
https://limbaniandroid.blogspot.in/2014/03/how-to-get-absolute-path-when-select.html
But issue is, it requires minimum SDK 19, Warning/error in android studio .But it is compiling and running fine . I have Android lollipop
so its good to kept moving with this . Or I have to do my projects minimum SDK 19
Will it produce any error while uploading assigned .apk .
Because I have to upload it within 2, 3 days
Or I have to write separate code for lower version
Any help please.
Please try the following code:
Add the below file as DocumentPathUtil.java
import android.annotation.TargetApi;
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 DocumentPathUtil {
/**
* Get a file path from a Uri. This will get the the path for Storage Access
* Framework Documents, as well as the _data field for the MediaStore and
* other file-based ContentProviders.
*
* #param context The context.
* #param uri The Uri to query.
* #author paulburke
*/
#TargetApi(Build.VERSION_CODES.KITKAT)
public static String getPath(final Context context, final Uri uri) {
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];
}
// TODO handle non-primary volumes
}
// 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 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 column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_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());
}
public static String getFileName(String path) {
String fileNameSegments[] = path.split("/");
return fileNameSegments[fileNameSegments.length - 1];
}
}
And in onActivityResult use:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case RESULT_LOAD_DOC:
if (resultCode == Activity.RESULT_OK && data != null) {
String selectedImagePath = ImagePathUtil.getPath(this, data.getData());
}
break;
}
}
where selectedImagePath will give you the path to use.
RESULT_LOAD_DOC is the identifier used to check which data is being fetched.

get realPath return null on android marshmallow?

I am using this function to get the image path from uri:
private static 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();
}
}
}
the above function works fine with version < 23 . but it return null with android marshmallow ?
I am using emulator nexus 4 with android 6.0 x86_64
the emulator has storage permissions.
what may be the problem ?
UPDATE:
Please refer to this post on handling Uri in android to support the latest versions of the android operating system and new devices, most of the your requirements can be met with using streams instead of getting the path to the asset in the file system. So please consider using streams.
OLD ANSWER
/**
* Get a file path from a Uri. This will get the the path for Storage Access
* Framework Documents, as well as the _data field for the MediaStore and
* other file-based ContentProviders.
*
* #param context The context.
* #param uri The Uri to query.
* #author paulburke
*/
public static String getPath(final Context context, final Uri uri) {
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];
}
// TODO handle non-primary volumes
}
// 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());
}
taken from here and from this answer . This is an ugly hack that isn't guaranteed to work on all devices but in my experience it works on 99% of the devices out there. According to CommonsWare you shouldn't assume, that the stream you get via ContentResolver is convertable into file. Instead you are supposed to open an inputstream from that Uri using the context.getContentResolver().openInputStream(fileUri) method. Refer to his commonsBlog post for more information on this and how to handle Uris

Get the path from Uri in Android Kitkat throws Illegal Argument exception

I'm trying to get the path from uri. it works in devices below kitkat. I googled and found that I need to get the document Id and then query it with the gallery items. And it works. But I'm facing problem with videos. When i select the video from Videos section, it works. But When I select it from Gallery, my app crashes, giving Illegal Argument exception- Not a document type. I know why it's happening. It is because I'm looking for a document type of video in Gallery section. But how to prevent this. So that I can select videos from both Gallery & Videos Section.
Here is my code:
public static String getRealPathFromURI(Context context, Uri contentUri,String type) {
if(isKitkatBelow()) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor 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);
}else{
String docId= DocumentsContract.getDocumentId(contentUri);
String id= docId.split(":")[1];
if(type== TYPE_IMAGE){
String[] proj = { MediaStore.Images.Media.DATA };
String whereClause=MediaStore.Images.Media._ID + "=?";
Cursor cursor=context.getContentResolver().query(getUri(type),proj,whereClause,new String[]{id},null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}else{
String[] proj = { MediaStore.Video.Media.DATA };
String whereClause=MediaStore.Video.Media._ID + "=?";
Cursor cursor=context.getContentResolver().query(getUri(type),proj,whereClause,new String[]{id},null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}
}
This is happening because I'm trying to search a file of type MediaStore.Video.Media.DATA in Gallery. But for devices below kitkat, MediaStore.Images.Media.DATA gets the video uri, from the gallery too without causing any crash. Thanks in Advance..
You can use for getting absolute path from the Uri of selected file because of differences in both KitKat(API 19) and below Kitkat in android to achieve this using following code,
public static String getPath(final Context context, final Uri uri) {
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];
}
// TODO handle non-primary volumes
}
// 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 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 column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_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());
}

Categories

Resources