Cannot convert content scheme uri to file path - android

I put .jpg , .pdf , .docx , .xlx , .mp3 , .mp4 type of fine on same location of sd-card (External memory card)
When i try to choose file then i able to choose only .jpg , .pdf file other type of file not choosen
Chosen file :->
1.path : `/storage/emulated/0/123.pdf` (from this path i successfully attached file)
2. path : `/storage/emulated/0/Program.docx`
3. path : `/storage/emulated/0/ApiCalling.mp4`
Error is :
file are not exists.. when i get 2. and 3. number of path
Code is :
public static void showFileChooser(Context context) {
PICK_IMAGE_REQUEST = 2;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
((Activity) context).startActivityForResult(
Intent.createChooser(intent, context.getResources().getString(R.string.select_file_msg)),
PICK_IMAGE_REQUEST);
} catch (android.content.ActivityNotFoundException ex) {
e.print();
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Uri uri = data.getData();
try {
String path = Utility.getRealPathFromURI(this, uri);
Log.e("path -> ",path);
File f = new File(path);
if (f.exists()) {
}
else
{
Log.e("err -> ","file not exists");
}
}
}
public static String getRealPathFromURI(Context context, Uri uri) throws URISyntaxException {
String selection = null;
String[] selectionArgs = null;
// Uri is different in versions after KITKAT (Android 4.4), we need to
if (uri != null) {
if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
return Environment.getExternalStorageDirectory() + "/" + split[1];
} else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
uri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("image".equals(type)) {
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
selection = "_id=?";
selectionArgs = new String[]{
split[1]
};
}
}
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = {
MediaStore.Images.Media.DATA
};
Cursor cursor = null;
try {
cursor = context.getContentResolver()
.query(uri, projection, selection, selectionArgs, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
}
return null;
}
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}

There's no guarantee that the content the user selected is on external storage and/or is backed by a file. Even if it is, chances are you don't have access to it. But you can simply use ContentResolver.openInputStream() with the Uri from the data field of the result Intent to read the data.

Try this
Intent mediaIntent = new Intent(Intent.ACTION_GET_CONTENT);
mediaIntent.setType("*/*"); //set mime type as per requirement
startActivityForResult(mediaIntent,REQUESTCODE_PICK_FILE);
Then you can get path in onActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUESTCODE_PICK_FILE
&& resultCode == Activity.RESULT_OK) {
Uri videoUri = data.getData();
Log.d("", "Video URI= " + videoUri);
}
}

Related

Android: Files: Unable to get file path from content URI when file is selected from RECENT section in file browser

I was trying to fetch file path from Uri given by data.data!! onActivityResult() method in android. When I selected the DCIM folder in File browser I was able to get the file path but when I selected the same file from RECENT section in file browser I was not getting the file path.
Code on Button click:
val intent = Intent();
intent.setType("image/*");
val mimeTypes: Array<String> = arrayOf("image/*", "application/pdf")
intent.putExtra(Intent.EXTRA_MIME_TYPES,mimeTypes)
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(Intent.createChooser(intent, "Select File"), 101);
Code on returning data from onActivityResult() method:
var selectedImagePathFB:String = ""
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
if (requestCode == 101) {
val selectedImageUri:Uri = data?.data!!
selectedImagePathFB = getPath(this#MyContactUsActivity,selectedImageUri);
//selectedImagePathFB = AppUtils().getRealPathFromURI(this#MyContactUsActivity,selectedImageUri)
val url: String = selectedImagePathFB
}
}
}
and getPath(Context,Uri) is common found code from stackoverflow by paulburke:
public static String getPath(final Context context, final Uri uri) {
// DocumentProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
return Environment.getExternalStorageDirectory() + "/" + split[1];
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
try {
final String id = DocumentsContract.getDocumentId(uri);
//Log.d(TAG, "getPath: id= " + id);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}catch (Exception e){
e.printStackTrace();
List<String> segments = uri.getPathSegments();
if(segments.size() > 1) {
String rawPath = segments.get(1);
if(!rawPath.startsWith("/")){
return rawPath.substring(rawPath.indexOf("/"));
}else {
return rawPath;
}
}
}
}
// 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;
}
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);
}
}catch (Exception e){
e.printStackTrace();
}finally {
if (cursor != null)
cursor.close();
}
return "nodata";
}
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
I am testing on android Q device. Why is that when selecting file from RECENT section in file browser i am not getting any file path meanwhile selecting same file in STORAGE section is returning file path? And is there a workaround also for converting files like PDF or Images in Base64 string if not from file path?
According to your code there is no error. But you have to get Storage permission before getting files from Recent section. Read and Write permission are required.

Unable to pickup file from SDCARD in Oreo

I am New in Android, Working on one functionality in which I have to pick up a file from internal storage and SDCARD. I have implemented some code. With the help of below code, I am able to pick up or select a file from SDcard and internal storage in the Android pie version(9 API level 28) and Android Nougat version(7) but I am not able to get pdf file in from SDCARD in Android Oreo(8 api level 26) version and for Marshmallow it is unable to select file from internal as well as SDCARD. I am not able to figure out what is the problem. Same code working for one not working for another. There is any universal way to access files(pdf and images).Thanks in advance
Implemented Code Below
private void SelectFileFromGallery(){
Intent intent = new Intent();
String[] mimeTypes = {"image/*", "application/pdf"};
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(Intent.createChooser(intent, getString(R.string.select_file)), SELECT_FILE);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_FILE) {
onSelectFileFromGalleryResult(data);
isUpdated = true;
} else if (requestCode == 11) {
onBackPressed();
}
}
private void onSelectFileFromGalleryResult(Intent data) {
try {
InputStream is;
Uri selectedImageUri = data.getData();
String file= AndroidUtilities.getFilePath(selectedImageUri);
File imageFile = new File(file);
Log.d("File Path",imageFile.getAbsolutePath());
if (imageFile.exists()) {
// Here I am Compressing the file to store
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getFilePath(final Uri uri) {
String filePath="";
try {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
if (isKitKat && DocumentsContract.isDocumentUri(MyApp.applicationContext, uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type=split[0];
String storageDefinition;
// if ("primary".equalsIgnoreCase(type)) {
// return Environment.getExternalStorageDirectory() + "/" + split[1];
// } else {
//
// if(Environment.isExternalStorageRemovable()){
// storageDefinition = "EXTERNAL_STORAGE";
//
// } else{
// storageDefinition = "SECONDARY_STORAGE";
// }
//
// return System.getenv(storageDefinition) + "/" + split[1];
// }
if("primary".equalsIgnoreCase(type)){
if (split.length > 1) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
} else {
return Environment.getExternalStorageDirectory() + "/";
}
// This is for checking SD Card
}
else if ("home".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/documents/" + split[1];
}
else {
return "storage" + "/" + docId.replace(":", "/");
}
} else if (isDownloadsDocument(uri)) {
String fileName = getFileName(MyApp.applicationContext, uri);
final String id = DocumentsContract.getDocumentId(uri);
if(fileName!=null){
return Environment.getExternalStorageDirectory().toString()+"/Download/"+fileName;
}
if (id != null && id.startsWith("raw:")) {
return id.substring(4);
}
String[] contentUriPrefixesToTry = new String[]{
"content://downloads/public_downloads",
"content://downloads/my_downloads",
"content://downloads/all_downloads",
};
// final Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefixesToTry), Long.valueOf(id));
// return getDataColumn(MyApp.applicationContext, contentUri, null, null);
for (String contentUriPrefix : contentUriPrefixesToTry) {
Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));
try {
String path = getDataColumn(MyApp.applicationContext, contentUri, null, null);
if (path != null) {
return path;
}
} catch (Exception e) {}
}
// File cacheDir = getDocumentCacheDir(MyApp.applicationContext);
// File file = generateFileName(fileName, cacheDir);
// String destinationPath = null;
// if (file != null) {
// destinationPath = file.getAbsolutePath();
// saveFileFromUri(MyApp.applicationContext, uri, destinationPath);
// }
// return destinationPath;
} else if (isMediaDocument(uri)||isMediaStorage(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
switch (type) {
case "image":
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
break;
case "video":
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
break;
case "audio":
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
break;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
return getDataColumn(MyApp.applicationContext, contentUri, selection, selectionArgs);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(MyApp.applicationContext, uri, null, null);
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
} catch (Exception e) {
Log.e("Exception", e.toString());
}
return null;
}
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {MediaStore.Images.Media.DATA};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
String value = cursor.getString(column_index);
if (value.startsWith("content://") || !value.startsWith("/") && !value.startsWith("file://")) {
return null;
}
return value;
}
} catch (Exception e) {
Log.e("Exception", e.toString());
} finally {
if (cursor != null) {
cursor.close();
}
}
return null;
}
private static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
private static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
private static boolean isMediaStorage(Uri uri) {
return "com.google.android.apps.docs.storage".equals(uri.getAuthority());
}

how ca in get data from choosed file with Intent.CreateChooser(Intent, "Select Any File") as byte

I want when choosing non-type files(apk, exe, pdf, ...) with intent chooser then extract data chose the file as a byte array in OnActivityResult I have a lot of searches but I can't do this, please help me.
This is my pick button Code:
private void Pick_Click(object sender, EventArgs e)
{
Intent = new Intent();
Intent.SetType("*/*");
Intent.SetAction(Intent.ActionGetContent);
Intent chooser = Intent.CreateChooser(Intent, "Select Any File");
StartActivityForResult(chooser, 1);
}
Now how can I get the choosed file in OnActivityResult?
I have created a new app and test with pdf and image, it works properly. The main code is as follows:
static readonly int REQUEST_CHOOSER = 0x001;
static readonly int REQUEST_File = 0x002;
Intent intent = new Intent(Intent.ActionGetContent);
intent.SetType("*/*");
intent.AddCategory(Intent.CategoryOpenable);
StartActivityForResult(Intent.CreateChooser(intent, "Select ,Music"), REQUEST_CHOOSER);
method OnActivityResult
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Canceled)
{
Finish();
}
else
{
try
{
var _uri = data.Data;
var filePath = IOUtil.getPath(this, _uri);
if (string.IsNullOrEmpty(filePath))
filePath = _uri.Path;
var file = IOUtil.readFile(filePath);// here we can get byte array
}
catch (Exception readEx)
{
System.Diagnostics.Debug.Write(readEx);
}
finally
{
Finish();
}
}
}
IOUtil.cs
public class IOUtil
{
public static string getPath(Context context, Android.Net.Uri uri)
{
bool isKitKat = Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat;
// DocumentProvider
if (isKitKat && DocumentsContract.IsDocumentUri(context, uri))
{
// ExternalStorageProvider
if (isExternalStorageDocument(uri))
{
var docId = DocumentsContract.GetDocumentId(uri);
string[] split = docId.Split(':');
var type = split[0];
if ("primary".Equals(type, StringComparison.OrdinalIgnoreCase))
{
return Android.OS.Environment.ExternalStorageDirectory + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri))
{
string id = DocumentsContract.GetDocumentId(uri);
Android.Net.Uri contentUri = ContentUris.WithAppendedId(
Android.Net.Uri.Parse("content://downloads/public_downloads"), long.Parse(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri))
{
var docId = DocumentsContract.GetDocumentId(uri);
string[] split = docId.Split(':');
var type = split[0];
Android.Net.Uri contentUri = null;
if ("image".Equals(type))
{
contentUri = MediaStore.Images.Media.ExternalContentUri;
}
else if ("video".Equals(type))
{
contentUri = MediaStore.Video.Media.ExternalContentUri;
}
else if ("audio".Equals(type))
{
contentUri = MediaStore.Audio.Media.ExternalContentUri;
}
var selection = "_id=?";
var selectionArgs = new string[] {
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
return uri.Path;
}
return null;
}
public static string getDataColumn(Context context, Android.Net.Uri uri, string selection,
string[] selectionArgs)
{
ICursor cursor = null;
var column = "_data";
string[] projection = {
column
};
try
{
cursor = context.ContentResolver.Query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.MoveToFirst())
{
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 bool isExternalStorageDocument(Android.Net.Uri uri)
{
return "com.android.externalstorage.documents".Equals(uri.Authority);
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is DownloadsProvider.
*/
public static bool isDownloadsDocument(Android.Net.Uri uri)
{
return "com.android.providers.downloads.documents".Equals(uri.Authority);
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is MediaProvider.
*/
public static bool isMediaDocument(Android.Net.Uri uri)
{
return "com.android.providers.media.documents".Equals(uri.Authority);
}
public static byte[] readFile(string file)
{
try
{
return readFile(new File(file));
}
catch (Exception ex)
{
System.Diagnostics.Debug.Write(ex);
return new byte[0];
}
}
public static byte[] readFile(File file)
{
// Open file
var f = new RandomAccessFile(file, "r");
try
{
// Get and check length
long longlength = f.Length();
var length = (int)longlength;
if (length != longlength)
throw new IOException("Filesize exceeds allowed size");
// Read file and return data
byte[] data = new byte[length];
f.ReadFully(data);
return data;
}
catch (Exception ex)
{
System.Diagnostics.Debug.Write(ex);
return new byte[0];
}
finally
{
f.Close();
}
}
}
Note: you need to add permission in AndroidManifest file, and add Runtime Permisssion in Android M and above.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Android- Not able to select file from internal storage

I have to get image from internal storage of mobile device and upload to server. If I select image from sdcard it working fine, while if I select image from internal storage it show error, I am not able to get this error.
Here is logcat output -
07-26 10:32:24.868: W/System.err(24051): java.io.FileNotFoundException: /document/primary:Pictures/Screenshots/Screenshot_20160712-172722.png: open failed: ENOENT (No such file or directory)
I am using this code to get image
private void showFileChooser() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult(
Intent.createChooser(intent, "Select a File to Upload"),
1);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(getActivity(), "Please install a File Manager.",
Toast.LENGTH_SHORT).show();
}
}
OnActivityResult code
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// 1
if (requestCode == 1) {
if (resultCode == Activity.RESULT_OK) {
try {
// SDK < API11
if (Build.VERSION.SDK_INT < 11)
realPath_1 = RealPathUtil
.getRealPathFromURI_BelowAPI11(getActivity(),
data.getData());
// SDK >= 11 && SDK < 19
else if (Build.VERSION.SDK_INT < 19)
realPath_1 = RealPathUtil.getRealPathFromURI_API11to18(
getActivity(), data.getData());
// SDK > 19 (Android 4.4)
else
realPath_1 = RealPathUtil.getRealPathFromURI_API19(
getActivity(), data.getData());
Log.e("", "Build Version : " + Build.VERSION.SDK_INT);
Log.e("", "Get Data Get Path : " + data.getData().getPath());
if (realPath_1.equalsIgnoreCase("")) {
realPath_1 = data.getData().getPath().toString();
}
Log.e("", "Real Path 1 : " + realPath_1);
file_1 = realPath_1.substring(
realPath_1.lastIndexOf('/') + 1,
realPath_1.length());
Log.i("File Name 1 ", file_1);
txt_file_name_1.setText(file_1);
} catch (Exception e) {
Uri selected = data.getData();
realPath_1 = selected.getPath();
file_1 = realPath_1.substring(
realPath_1.lastIndexOf('/') + 1,
realPath_1.length());
Log.i("File Name 1 ", file_1);
txt_file_name_1.setText(file_1);
}
}
}}
Here is class named - RealPathUtil to get path of images.
My
android:minSdkVersion="14"
android:targetSdkVersion="23"
and called this method from class RealPathUtil
public static String getRealPathFromURI_API19(Context context, Uri uri) {
String filePath = "";
String wholeID = DocumentsContract.getDocumentId(uri);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
String[] column = { MediaStore.Images.Media.DATA };
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.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();
return filePath;
}
Please help and thanks in advance.
Try this:
boolean isKitKat = false;
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showFileChooser();
}
});
Code for show file chooser function
private void showFileChooser() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
isKitKat = true;
startActivityForResult(Intent.createChooser(intent, "Select file"), 1);
} else {
isKitKat = false;
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select file"), 1);
}
}
OnActivity Result code :
#TargetApi(19)
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (data != null && data.getData() != null && resultCode == getActivity().RESULT_OK) {
boolean isImageFromGoogleDrive = false;
Uri uri = data.getData();
if (isKitKat && DocumentsContract.isDocumentUri(getActivity(), uri)) {
if ("com.android.externalstorage.documents".equals(uri.getAuthority())) {
String docId = DocumentsContract.getDocumentId(uri);
String[] split = docId.split(":");
String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
realPath_1 = Environment.getExternalStorageDirectory() + "/" + split[1];
} else {
Pattern DIR_SEPORATOR = Pattern.compile("/");
Set<String> rv = new HashSet<>();
String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET");
if (TextUtils.isEmpty(rawEmulatedStorageTarget)) {
if (TextUtils.isEmpty(rawExternalStorage)) {
rv.add("/storage/sdcard0");
} else {
rv.add(rawExternalStorage);
}
} else {
String rawUserId;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
rawUserId = "";
} else {
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
String[] folders = DIR_SEPORATOR.split(path);
String lastFolder = folders[folders.length - 1];
boolean isDigit = false;
try {
Integer.valueOf(lastFolder);
isDigit = true;
} catch (NumberFormatException ignored) {
}
rawUserId = isDigit ? lastFolder : "";
}
if (TextUtils.isEmpty(rawUserId)) {
rv.add(rawEmulatedStorageTarget);
} else {
rv.add(rawEmulatedStorageTarget + File.separator + rawUserId);
}
}
if (!TextUtils.isEmpty(rawSecondaryStoragesStr)) {
String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
Collections.addAll(rv, rawSecondaryStorages);
}
String[] temp = rv.toArray(new String[rv.size()]);
for (int i = 0; i < temp.length; i++) {
File tempf = new File(temp[i] + "/" + split[1]);
if (tempf.exists()) {
realPath_1 = temp[i] + "/" + split[1];
}
}
}
} else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
String id = DocumentsContract.getDocumentId(uri);
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
Cursor cursor = null;
String column = "_data";
String[] projection = {column};
try {
cursor = getActivity().getContentResolver().query(contentUri, projection, null, null,
null);
if (cursor != null && cursor.moveToFirst()) {
int column_index = cursor.getColumnIndexOrThrow(column);
realPath_1 = cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
} else if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
String docId = DocumentsContract.getDocumentId(uri);
String[] split = docId.split(":");
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;
}
String selection = "_id=?";
String[] selectionArgs = new String[]{split[1]};
Cursor cursor = null;
String column = "_data";
String[] projection = {column};
try {
cursor = getActivity().getContentResolver().query(contentUri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
int column_index = cursor.getColumnIndexOrThrow(column);
realPath_1 = cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
} else if ("com.google.android.apps.docs.storage".equals(uri.getAuthority())) {
isImageFromGoogleDrive = true;
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
Cursor cursor = null;
String column = "_data";
String[] projection = {column};
try {
cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
int column_index = cursor.getColumnIndexOrThrow(column);
realPath_1 = cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
realPath_1 = uri.getPath();
}
try {
Log.d(TAG, "Real Path 1 : " + realPath_1);
file_1 = realPath_1.substring(realPath_1.lastIndexOf('/') + 1, realPath_1.length());
Log.i("File Name 1 ", file_1);
} catch (Exception e) {
e.printStackTrace();
}
}
}}
Here file_1 = get image name and realPath_1 show full path of image from internal or external storage.
Happy to help :)
Use bellow code for get file URL.
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;
}
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;
}
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri
.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri
.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri
.getAuthority());
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri
.getAuthority());
}
Your code looks fine you just have to get runtime permissions from user. In Andorid 6.0 or later needs permission from user at runtime only declaring them manifest is not enough.
See here my earlier post about how to get runtime permissions.
Update:
private void showFileChooser() {
try {
// Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// startActivityForResult(i, RESULT_LOAD_IMAGE);
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
startActivityForResult(intent, RESULT_LOAD_IMAGE);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(getActivity(), "Please install a File Manager.",
Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
//Uri selectedImage = data.getData();
txt_file_name_1.setText(data.getData().toString());
}
}

Android opening a file with ACTION_GET_CONTENT results into different Uri's

I am trying to open files by using Intent.ACTION_GET_CONTENT.
Dependent on the Android version/device brand the file browser opens and I get the following results:
Selecting a file from Downloads:
content://com.android.providers.downloads.documents/document/446
Selecting a file from Fotos:
content://media/external/images/media/309
Selecting a file from FileCommander:
file:///storage/emulated/0/DCIM/Camera/20141027_132114.jpg
I can open all these files except when I try to open a file from Downloads,, Audio , Afbeeldingen(Images)
It's likely I can't handle this kind of Uri: content://com.android.providers.downloads.documents/document/446
I have tried the following things:
Trying to open the file by new File(uri.getPath()). File.exists() returns false.
Trying to open/reach the file by getContext().getContentResolver().openInputStream(uri). Results into a FileNotFoundException
Trying to open the file with the following code:
public static String getRealPathFromURI_API19(Context context, Uri uri) {
Log.i("uri", uri.getPath());
String filePath = "";
if (uri.getScheme().equals("file")) {
return uri.getPath();
} else if (DocumentsContract.isDocumentUri(context, uri)) {
String wholeID = DocumentsContract.getDocumentId(uri);
Log.i("wholeID", wholeID);
// Split at colon, use second item in the array
String[] splits = wholeID.split(":");
if (splits.length == 2) {
String id = splits[1];
String[] column = {MediaStore.Images.Media.DATA};
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.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();
}
} else {
filePath = AttachmentUtils.getPath(context, uri);
}
return filePath;
}
What am I doing wrong?
UPDATE:
I have noticed that the files that are listed in the screenshot that they are not physically existing in the storage.
The device I am using is a tablet from the company containing rubbish data. My colleague told me that this device once was connected with a different Google account. These files could be the files from the previous account which are not existing/reachable anymore.
My own conclusion about it is that I am encountering some bug in Android.
My bug report
Update 6 february 2017:
Android banned the file:// URI. Please consider to think about it.
Ban on file: Uri Scheme The biggest compatibility issue so far with
Android 7.0 is that the file: scheme for Uri values is banned, in
effect. If you attempt to pass a file: Uri in an Intent that is going
to another app — whether via an extra or as the “data” facet of the
Intent — you will crash with a FileUriExposedException exception. You
will face similar issues with putting file: Uri values on the
clipboard in ClipData . This is coming from an updated edition of
StrictMode . StrictMode.VmPolicy.Builder has a
penaltyDeathOnFileUriExposure() method that triggers the detection of
file: Uri values and the resulting FileUriExposedException exceptions.
And, it appears that this is pre-configured, much as how StrictMode is
pre-configured to apply penaltyDeathOnNetwork() (the source of your
NetworkOnMainThreadException crashes).
Use below code.This will work for sure.
public static String getPath(Context context, Uri uri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// DocumentProvider
if (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;
}
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;
}
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());
}
Use the below code to browse the file in any format.
public void browseClick() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
//intent.putExtra("browseCoa", itemToBrowse);
//Intent chooser = Intent.createChooser(intent, "Select a File to Upload");
try {
//startActivityForResult(chooser, FILE_SELECT_CODE);
startActivityForResult(Intent.createChooser(intent, "Select a File to Upload"),FILE_SELECT_CODE);
} catch (Exception ex) {
System.out.println("browseClick :"+ex);//android.content.ActivityNotFoundException ex
}
}
Then get that file path in the onActivityResult like below.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_SELECT_CODE) {
if (resultCode == RESULT_OK) {
try {
Uri uri = data.getData();
if (filesize >= FILE_SIZE_LIMIT) {
Toast.makeText(this,"The selected file is too large. Selet a new file with size less than 2mb",Toast.LENGTH_LONG).show();
} else {
String mimeType = getContentResolver().getType(uri);
if (mimeType == null) {
String path = getPath(this, uri);
if (path == null) {
filename = FilenameUtils.getName(uri.toString());
} else {
File file = new File(path);
filename = file.getName();
}
} else {
Uri returnUri = data.getData();
Cursor returnCursor = getContentResolver().query(returnUri, null, null, null, null);
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
filename = returnCursor.getString(nameIndex);
String size = Long.toString(returnCursor.getLong(sizeIndex));
}
File fileSave = getExternalFilesDir(null);
String sourcePath = getExternalFilesDir(null).toString();
try {
copyFileStream(new File(sourcePath + "/" + filename), uri,this);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void copyFileStream(File dest, Uri uri, Context context)
throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = context.getContentResolver().openInputStream(uri);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
is.close();
os.close();
}
}
After this you can open this file from your application external storage where you saved the file with appropriate action.
Pick any file using System File Picker:
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
startActivityForResult(intent, 1)
onActivityResult:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
data?.data?.let {
getFileFromUri(requireContext().contentResolver, uri, requireContext().cacheDir)
}
}
}
Get File:
private fun getFileFromUri(contentResolver: ContentResolver, uri: Uri, directory: File): File {
val file =
File.createTempFile("suffix", "prefix", directory)
file.outputStream().use {
contentResolver.openInputStream(uri)?.copyTo(it)
}
return file
}
The accepted answer on kotlin
#Suppress("SpellCheckingInspection")
object PathCompat {
#WorkerThread
fun getFilePath(context: Context, uri: Uri): String? = context.run {
return try {
when {
Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT -> getDataColumn(uri, null, null)
else -> getPathKitkatPlus(uri)
}
} catch (e: Throwable) {
Timber.e(e)
null
}
}
#Suppress("DEPRECATION")
#SuppressLint("NewApi", "DefaultLocale")
private fun Context.getPathKitkatPlus(uri: Uri): String? {
when {
DocumentsContract.isDocumentUri(applicationContext, uri) -> {
val docId = DocumentsContract.getDocumentId(uri)
when {
uri.isExternalStorageDocument -> {
val parts = docId.split(":")
if ("primary".equals(parts[0], true)) {
return "${Environment.getExternalStorageDirectory()}/${parts[1]}"
}
}
uri.isDownloadsDocument -> {
val contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
docId.toLong()
)
return getDataColumn(contentUri, null, null)
}
uri.isMediaDocument -> {
val parts = docId.split(":")
val contentUri = when (parts[0].toLowerCase()) {
"image" -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
"video" -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
"audio" -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
else -> return null
}
return getDataColumn(contentUri, "_id=?", arrayOf(parts[1]))
}
}
}
"content".equals(uri.scheme, true) -> {
return if (uri.isGooglePhotosUri) {
uri.lastPathSegment
} else {
getDataColumn(uri, null, null)
}
}
"file".equals(uri.scheme, true) -> {
return uri.path
}
}
return null
}
private fun Context.getDataColumn(uri: Uri, selection: String?, args: Array<String>?): String? {
contentResolver?.query(uri, arrayOf("_data"), selection, args, null)?.use {
if (it.moveToFirst()) {
return it.getString(it.getColumnIndexOrThrow("_data"))
}
}
return null
}
private val Uri.isExternalStorageDocument: Boolean
get() = authority == "com.android.externalstorage.documents"
private val Uri.isDownloadsDocument: Boolean
get() = authority == "com.android.providers.downloads.documents"
private val Uri.isMediaDocument: Boolean
get() = authority == "com.android.providers.media.documents"
private val Uri.isGooglePhotosUri: Boolean
get() = authority == "com.google.android.apps.photos.content"
}
There is a bug I just faced
final String docId = DocumentsContract.getDocumentId(uri);
return different URI (e.g: content://com.android.providers.downloads.documents/document/11
and sometime content://com.android.providers.downloads.documents/document/abc%aile.jpg in that case Long.valueOf(id) throws an exception to fix that
String id = DocumentsContract.getDocumentId(uri);
if (id.startsWith("raw:")) {
id = id.replaceFirst("raw:", "");
return id;
}
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(contentUri, null, null);
do this return the id, it worked for me

Categories

Resources