Convert file: Uri to File in Android
Asked Answered
Q

29

513

What is the easiest way to convert from an android.net.Uri object which holds a file: type to a java.io.File object in Android?

I tried the following but it doesn't work:

File file = new File(Environment.getExternalStorageDirectory(), "read.me");
Uri uri = Uri.fromFile(file);
File auxFile = new File(uri.toString());
assertEquals(file.getAbsolutePath(), auxFile.getAbsolutePath());
Quittor answered 4/6, 2010 at 14:48 Comment(4)
Here is my solution!! It works well! #2789776Parry
See #5657911Blackthorn
What does assertEquals do?Reprography
Uri.fromFile context is just not working on me :(Tantalic
P
953

What you want is...

new File(uri.getPath());

... and not...

new File(uri.toString());
Notes
  1. For an android.net.Uri object which is named uri and created exactly as in the question, uri.toString() returns a String in the format "file:///mnt/sdcard/myPicture.jpg", whereas uri.getPath() returns a String in the format "/mnt/sdcard/myPicture.jpg".
  2. 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.
Prospective answered 3/12, 2011 at 19:23 Comment(24)
What is the difference between the two? What does toString do?Voluptuous
url.toString() return a String in the following format: "file:///mnt/sdcard/myPicture.jpg", whereas url.getPath() returns a String in the following format: "/mnt/sdcard/myPicture.jpg", i.e. without the scheme type pre-fixed.Prospective
If the URI is a Images.Media.EXTERNAL_CONTENT_URI (e.g. from Intent.ACTION_PICK for the Gallery) from you will need to look it up as in https://mcmap.net/q/75111/-android-get-gallery-image-uri-path/42619Dermatitis
@AdilHussain and then how to display this File from imageView ?Tram
@Tram check out a library called Picasso for loading Files (even URLs) into ImageViews very easily.Psychologism
Most of the time I'm getting open failed: ENOENT (No such file or directory) When I try to open the File given with this. Also, if the Uri is the Content Uri of an Image for example, it definitely doesn't work.Smyth
@AdilHussain in one of my test device, "Uri.getPath();" sometimes return "file:///pathToTheFile". I don't know why is that happens, so i need to substring that path to get the path without scheme type.Reserpine
open failed: ENOENT (No such file or directory) , how i will get storage path of anytype of File, like pdfJarrell
how to read actual file fro its uri in onActivityForResult? i am working on audio file want to pick audio File instead of just its url...the above solution is for only to create new file on that path of uri instead of getting that existing audio/any fileAndreas
@natiqjavid you are asking a question that is outside the scope of this thread. Please start a different thread for your issue that stating what you've tried and what hasn't worked.Prospective
i solved my problem with this instead of getting that actual file i copied that input stream from uri and write my own same file by outputsteam #28225112Andreas
CommonsWare's is the right solution. A URI can mean mean things, not only a localsystem file. Either way, if you are forcing the URI to be a file, with at least java 8 you can do new File(uri)Candi
The OP did not ask about Uri's in general, but file: Uri's. As such, this answer is correct. @Nuthatch: I think you're talking about content: Uri's, not file: Uri's.Visibility
@Adil Hussain It looks like you show url.toString (with a lower case L in url) instead of the uri.toString (with lower case I in uri). Just in case someone was trying urL with no luckBrute
@Candi "CommonsWare's is the right solution." great! Where was that again?Globular
@Globular don't know now, sorry, he might have changed his username :/Candi
When I create file from the uri returned by content provider - it says file does not existReichard
Year 2019, androidOne device, SDK 28(android pie) : both uri.getPath() and uri.toString() points to /mnt/sdcard/myPicture.jpgBrink
Not working in Android 10 i got file not found exception?Adrial
uri.toString() gives me "content://com.google.android.apps.nbu.files.provider/1/file%3A%2F%2F%2Fstorage%2Femulated%2F0%2FDownload%2Fbackup.file", uri.getPath() gives me "/1/file:///storage/emulated/0/Download/backup.file" and new File(uri.getPath()) gives me "/1/file:/storage/emulated/0/Download/backup.file". So answer is not fully correctDisplace
this is a better answer https://mcmap.net/q/73848/-convert-file-uri-to-file-in-androidLicha
This will not work Android API 11 and above on external storage unless you have manage external storage permission, which is very sensitive and most likely will not be granted. See the answer from Juan Camilo Rodriguez DuránBrigantine
Not working solution. I get following error message /document/msf:2391: open failed: ENOENT (No such file or directory)Beaded
This isn't working for me with URIs returned by the file picker: java.lang.IllegalArgumentException: URI is not absoluteBodiless
P
116

use

InputStream inputStream = getContentResolver().openInputStream(uri);    

directly and copy the file. Also see:

https://developer.android.com/guide/topics/providers/document-provider.html

Pereyra answered 25/7, 2016 at 13:8 Comment(9)
This should be upvoted much much more. ContentResolver is what it seems you'll look at by default to resolve the path from Android.Net.Uri.Nichols
I want to add another upVote, but it turns out I can do only once!Fouts
We selected a file from a chooser and then we'll first have to copy the file? :/Corkscrew
@M.UsmanKhan it depends. If you want to use the file later on copy it. Otherwise just use it as an input stream. You should not rely on other apps keeping the file for you.Westminster
@VaiTon86 . We want a File object from URI, without copying the file.Corkscrew
Agreed this should be the top answer. File to URI will not work because permissions, especially in Android 11 and above. Must use contentResolver. developer.android.com/guide/topics/providers/…Brigantine
Agreed, this is the real answer write here!Leff
@Leff rite here, not write hereZarzuela
"Real Answer" that doesn't work - exception No Content ProviderHildagarde
D
71

After searching for a long time this is what worked for me:

File file = new File(getPath(uri));


public String getPath(Uri uri) 
    {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
        if (cursor == null) return null;
        int column_index =             cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String s=cursor.getString(column_index);
        cursor.close();
        return s;
    }
Divot answered 12/5, 2013 at 19:17 Comment(8)
managedQuery is now deprecated. use getContentResolver().query(...) instead, which works on API 11+. Add a conditional for devices older than API 11.Kellsie
This returns null to me for some reason. And my android uri is returns something like that:{content://com.android.providers.media.documents/document/image%3A2741} Android.Net.UriInvokerPerdure
This is not a good solution since it wont work across all platforms. Some devices do not even populate this column, i recommend letting the content provider handle this as suggested by @CommonWare in previous answerOutspeak
this is only for image type file, what about others?Jarrell
Make sure you're getting your uri from Intent.ACTION_PICK and not Intent.ACTION_GET_CONTENT, because the later has no MediaStore.Images.Media.DATARayerayfield
crash in java.lang.IllegalArgumentException: column ''_data'' does not exist at android.database.AbstractCursor.getColumnIndexOrThrow(FileUtils.java)Jodhpur
You my friend are a life saver... this worked perfectly for meReft
MediaStore.Images.Media.DATA deprecated for SDK >= 29Homicide
W
41

Android + Kotlin

  1. Add dependency for Kotlin Android extensions:

    implementation 'androidx.core:core-ktx:{latestVersion}'

  2. Get file from uri:

    uri.toFile()

Word answered 25/5, 2018 at 6:23 Comment(8)
I tried this: androidx.core:core-ktx:1.5.0-alpha01 . Dont see this function "toFile"Corkscrew
@M.UsmanKhan as per the documentation version 1.5.0-alpha01 can be used with minimum Android 11 Beta 01, so you can try 1.4.0-alpha01 or stable release 1.3.0. More info: developer.android.com/jetpack/androidx/releases/…Word
@M.UsmanKhan it exists in version 1.3.0, developer.android.com/kotlin/ktx/…Word
I had 1.3.0 previously and it was not there :sCorkscrew
I moved the ktx to my library build file and then i see it. Thanks !Corkscrew
Error: java.lang.IllegalArgumentException: Uri lacks 'file' scheme: content://media/external/images/media/54545Cordage
What do you mean by "Just move to top" for Android + Java? ThanksProbst
Answer already given by Adil for Java: https://mcmap.net/q/73848/-convert-file-uri-to-file-in-androidWord
S
38

Best Solution

Create one simple FileUtil class & use to create, copy and rename the file

I used uri.toString() and uri.getPath() but not work for me. I finally found this solution.

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.util.Log;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class FileUtil {
    private static final int EOF = -1;
    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

    private FileUtil() {

    }

    public static File from(Context context, Uri uri) throws IOException {
        InputStream inputStream = context.getContentResolver().openInputStream(uri);
        String fileName = getFileName(context, uri);
        String[] splitName = splitFileName(fileName);
        File tempFile = File.createTempFile(splitName[0], splitName[1]);
        tempFile = rename(tempFile, fileName);
        tempFile.deleteOnExit();
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(tempFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if (inputStream != null) {
            copy(inputStream, out);
            inputStream.close();
        }

        if (out != null) {
            out.close();
        }
        return tempFile;
    }

    private static String[] splitFileName(String fileName) {
        String name = fileName;
        String extension = "";
        int i = fileName.lastIndexOf(".");
        if (i != -1) {
            name = fileName.substring(0, i);
            extension = fileName.substring(i);
        }

        return new String[]{name, extension};
    }

    private static String getFileName(Context context, Uri uri) {
        String result = null;
        if (uri.getScheme().equals("content")) {
            Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
            try {
                if (cursor != null && cursor.moveToFirst()) {
                    result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }
        }
        if (result == null) {
            result = uri.getPath();
            int cut = result.lastIndexOf(File.separator);
            if (cut != -1) {
                result = result.substring(cut + 1);
            }
        }
        return result;
    }

    private static File rename(File file, String newName) {
        File newFile = new File(file.getParent(), newName);
        if (!newFile.equals(file)) {
            if (newFile.exists() && newFile.delete()) {
                Log.d("FileUtil", "Delete old " + newName + " file");
            }
            if (file.renameTo(newFile)) {
                Log.d("FileUtil", "Rename file to " + newName);
            }
        }
        return newFile;
    }

    private static long copy(InputStream input, OutputStream output) throws IOException {
        long count = 0;
        int n;
        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        while (EOF != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
            count += n;
        }
        return count;
    }
}

Use FileUtil class in your code

try {
         File file = FileUtil.from(MainActivity.this,fileUri);
         Log.d("file", "File...:::: uti - "+file .getPath()+" file -" + file + " : " + file .exists());

  } catch (IOException e) {
          e.printStackTrace();
  }
Shenashenan answered 30/8, 2018 at 10:58 Comment(3)
this is worked but when i select image from gallery it throws error in line of: InputStream inputStream = context.getContentResolver().openInputStream(uri);Homestead
It worked very well but it throws FileNotFoundException on some android devices.Shenashenan
Use this code for pick photo from camera https://mcmap.net/q/75113/-android-camera-intent-not-working-launching-gallery-insteadShenashenan
M
25

EDIT: Sorry, I should have tested better before. This should work:

new File(new URI(androidURI.toString()));

URI is java.net.URI.

Motorize answered 4/6, 2010 at 14:51 Comment(10)
Ah, but the question is Uri, not URI. People have to watch out for that :)Fulminous
@Muz, I believe the answer is correct. androidURI is an android.net.Uri. java.net.URI (which does exist on Android) is only used as part of the conversion process.Motorize
Can't we just do: new File(uri.getPath());Rapier
combinated with @Adil Hussain comment this two answers illuminated me about uri/strings/files thanksRelieve
This just throws: IllegalArgumentException: Expected file scheme in URI: content://media/external/images/media/80038Georgettageorgette
@Xylian, yes, the question asks, "What's the easiest way to convert from a file: android.net.Uri to a File". You're not using a file: URL.Motorize
I am getting java.lang.IllegalArgumentException: Expected file scheme in URI: content://com.shajeel.daily_monitoring.localstorage.documents.localstorage.documents/document/%2Fstorage%2Femulated%2F0%2FBook1.xlsx exception after using this method.Dotted
@ShajeelAfzal the question says it's using the "file:" protocol. Like Xylian, you're using the content:// protocol.Motorize
Works great in 2021Horta
java.lang.IllegalArgumentException: URI scheme is not "file".Deepsix
F
15

None of this works for me. I found this to be the working solution. But my case is specific to images.

String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().getContentResolver().query(uri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
Funeral answered 10/4, 2014 at 19:42 Comment(2)
This should be an answer ! :) I tested it on API 25.Unifoliolate
Note that this technique is banned on Android Q. You can no longer access the DATA column (and that was an unreliable approach in the first place).Neotropical
E
13

With Kotlin it is even easier:

val file = File(uri.path)

Or if you are using Kotlin extensions for Android:

val file = uri.toFile()

UPDATE: For images it return "Uri lacks 'file' scheme: content://"

Thanks for comment

Emulsoid answered 7/6, 2018 at 8:3 Comment(3)
Bad answer, especially for images it return "Uri lacks 'file' scheme: content://"Acatalectic
Good answer, I am having the issue "Uri lacks 'file' scheme: content://" that help me to support my hypothesis.Bistre
@Acatalectic it's not bad answer, it's because it's only for Uris which have 'file' scheme. The method itself describes it - Creates a File from the given Uri. Note that this will throw an IllegalArgumentException when invoked on a Uri that lacks file scheme. If you are talking about MediaStore Uri or DocumentProvider Uri then you should not convert it to File anyway!Yecies
D
12

One other way to reach that is create a Temporary File. to do that:

fun createTmpFileFromUri(context: Context, uri: Uri, fileName: String): File? {
    return try {
        val stream = context.contentResolver.openInputStream(uri)
        val file = File.createTempFile(fileName, "", context.cacheDir)
        org.apache.commons.io.FileUtils.copyInputStreamToFile(stream,file)
        file
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}

We use Apache Commons library FileUtils class. For adding it to your project:

implementation "commons-io:commons-io:2.7"

Note that MAKE SURE call to file.delete() after usage. for more information checkout Documents.

Dian answered 15/8, 2021 at 14:9 Comment(1)
have tested and works on API 31Merrilee
C
8

If you have a Uri that conforms to the DocumentContract then you probably don't want to use File. If you are on kotlin, use DocumentFile to do stuff you would in the old World use File for, and use ContentResolver to get streams.

Everything else is pretty much guaranteed to break.

Cambodia answered 13/1, 2020 at 0:50 Comment(1)
Please, show, how to use it?Deepsix
S
3

@CommonsWare explained all things quite well. And we really should use the solution he proposed.

By the way, only information we could rely on when querying ContentResolver is a file's name and size as mentioned here: Retrieving File Information | Android developers

As you could see there is an interface OpenableColumns that contains only two fields: DISPLAY_NAME and SIZE.

In my case I was need to retrieve EXIF information about a JPEG image and rotate it if needed before sending to a server. To do that I copied a file content into a temporary file using ContentResolver and openInputStream()

Semaphore answered 9/3, 2017 at 18:39 Comment(0)
V
2

For this case, especially on Android, the way going for bytes is usually faster.

With this, I solved it by setting up a class FileHelper which is given the responsibility to deal with reading/writing bytes from/to file through stream and a class UriHelper which is given the responsibility to figure out path of Uri and permission.

As far as it's knew generally, string.getBytes((charset == null) ? DEFAULT_CHARSET:charset) can help us to transfer string you want to bytes you need.

How to let UriHelper and FileHelper you to copy a picture noted by Uri into a file, you can run:

FileHelper.getInstance().copy(UriHelper.getInstance().toFile(uri_of_a_picture)
                        , FileHelper.getInstance().createExternalFile(null, UriHelper.getInstance().generateFileNameBasedOnTimeStamp()
                                + UriHelper.getInstance().getFileName(uri_of_a_picture, context), context)
                );

about my UriHelper:

public class UriHelper {
private static UriHelper INSTANCE = new UriHelper();

public static UriHelper getInstance() {
    return INSTANCE;
}

@SuppressLint("SimpleDateFormat")
public String generateFileNameBasedOnTimeStamp() {
    return new SimpleDateFormat("yyyyMMdd_hhmmss").format(new Date()) + ".jpeg";
}

/**
 * if uri.getScheme.equals("content"), open it with a content resolver.
 * if the uri.Scheme.equals("file"), open it using normal file methods.
 */
//

public File toFile(Uri uri) {
    if (uri == null) return null;
    Logger.d(">>> uri path:" + uri.getPath());
    Logger.d(">>> uri string:" + uri.toString());
    return new File(uri.getPath());
}

public DocumentFile toDocumentFile(Uri uri) {
    if (uri == null) return null;
    Logger.d(">>> uri path:" + uri.getPath());
    Logger.d(">>> uri string:" + uri.toString());
    return DocumentFile.fromFile(new File(uri.getPath()));
}

public Uri toUri(File file) {
    if (file == null) return null;
    Logger.d(">>> file path:" + file.getAbsolutePath());
    return Uri.fromFile(file); //returns an immutable URI reference representing the file
}

public String getPath(Uri uri, Context context) {
    if (uri == null) return null;
    if (uri.getScheme() == null) return null;
    Logger.d(">>> uri path:" + uri.getPath());
    Logger.d(">>> uri string:" + uri.toString());
    String path;
    if (uri.getScheme().equals("content")) {
        //Cursor cursor = context.getContentResolver().query(uri, new String[] {MediaStore.Images.ImageColumns.DATA}, null, null, null);
        Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
        if (cursor == null) {
            Logger.e("!!! cursor is null");
            return null;
        }
        if (cursor.getCount() >= 0) {
            Logger.d("... the numbers of rows:" + cursor.getCount()
                        + "and the numbers of columns:" + cursor.getColumnCount());
            if (cursor.isBeforeFirst()) {
                while (cursor.moveToNext()) {
                    StringBuilder stringBuilder = new StringBuilder();
                    for (int i = 0; i<cursor.getColumnCount(); i++) {
                        stringBuilder.append("... iterating cursor.getString(" + i +"(" + cursor.getColumnName(i) + ")):" + cursor.getString(i));
                        stringBuilder.append("\n");
                    }
                    Logger.d(stringBuilder.toString());
                }
            } else {
                cursor.moveToFirst();
                do {
                    StringBuilder stringBuilder = new StringBuilder();
                    for (int i = 0; i<cursor.getColumnCount(); i++) {
                        stringBuilder.append("... iterating cursor.getString(" + i +"(" + cursor.getColumnName(i) + ")):" + cursor.getString(i));
                        stringBuilder.append("\n");
                    }
                    Logger.d(stringBuilder.toString());
                } while (cursor.moveToNext());
            }
            path = uri.getPath();
            cursor.close();
            Logger.d("... content scheme:" + uri.getScheme() + "  and return:" + path);
            return path;
        } else {
            path = uri.getPath();
            Logger.d("... content scheme:" + uri.getScheme()
                    + " but the numbers of rows in the cursor is < 0:" + cursor.getCount()
                    + "  and return:" + path);
            return path;
        }
    } else {
        path = uri.getPath();
        Logger.d("... not content scheme:" + uri.getScheme() + "  and return:" + path);
        return path;
    }
}

public String getFileName(Uri uri, Context context) {
    if (uri == null) return null;
    if (uri.getScheme() == null) return null;
    Logger.d(">>> uri path:" + uri.getPath());
    Logger.d(">>> uri string:" + uri.toString());
    String path;
    if (uri.getScheme().equals("content")) {
        //Cursor cursor = context.getContentResolver().query(uri, new String[] {MediaStore.Images.ImageColumns.DATA}, null, null, null);
        Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
        if (cursor == null) {
            Logger.e("!!! cursor is null");
            return null;
        }
        if (cursor.getCount() >= 0) {
            Logger.d("... the numbers of rows:" + cursor.getCount()
                    + "and the numbers of columns:" + cursor.getColumnCount());
            if (cursor.isBeforeFirst()) {
                while (cursor.moveToNext()) {
                    StringBuilder stringBuilder = new StringBuilder();
                    for (int i = 0; i<cursor.getColumnCount(); i++) {
                        stringBuilder.append("... iterating cursor.getString(" + i +"(" + cursor.getColumnName(i) + ")):" + cursor.getString(i));
                        stringBuilder.append("\n");
                    }
                    Logger.d(stringBuilder.toString());
                }
            } else {
                cursor.moveToFirst();
                do {
                    StringBuilder stringBuilder = new StringBuilder();
                    for (int i = 0; i<cursor.getColumnCount(); i++) {
                        stringBuilder.append("... iterating cursor.getString(" + i +"(" + cursor.getColumnName(i) + ")):" + cursor.getString(i));
                        stringBuilder.append("\n");
                    }
                    Logger.d(stringBuilder.toString());
                } while (cursor.moveToNext());
            }
            cursor.moveToFirst();
            path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DISPLAY_NAME));
            cursor.close();
            Logger.d("... content scheme:" + uri.getScheme() + "  and return:" + path);
            return path;
        } else {
            path = uri.getLastPathSegment();
            Logger.d("... content scheme:" + uri.getScheme()
                    + " but the numbers of rows in the cursor is < 0:" + cursor.getCount()
                    + "  and return:" + path);
            return path;
        }
    } else {
        path = uri.getLastPathSegment();
        Logger.d("... not content scheme:" + uri.getScheme() + "  and return:" + path);
        return path;
    }
}

}

about my FileHelper:

public class FileHelper {
private static final String DEFAULT_DIR_NAME = "AmoFromTaiwan";
private static final int DEFAULT_BUFFER_SIZE = 1024;
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private static final int EOF = -1;
private static FileHelper INSTANCE = new FileHelper();

public static FileHelper getInstance() {
    return INSTANCE;
}

private boolean isExternalStorageWritable(Context context) {
    /*
    String state = Environment.getExternalStorageState();
    return Environment.MEDIA_MOUNTED.equals(state);
    */
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (context.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            Logger.e("!!! checkSelfPermission() not granted");
            return false;
        }
    } else { //permission is automatically granted on sdk<23 upon installation
        return true;
    }
}

private boolean isExternalStorageReadable(Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (context.checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            Logger.e("!!! checkSelfPermission() not granted");
            return false;
        }
    } else { //permission is automatically granted on sdk<23 upon installation
        return true;
    }
}

@SuppressLint("SimpleDateFormat")
private String generateFileNameBasedOnTimeStamp() {
    return new SimpleDateFormat("yyyyMMdd_hhmmss").format(new Date()) + ".jpeg";
}

public File createExternalFile(String dir_name, String file_name, Context context) {
    String dir_path;
    String file_path;
    File dir ;
    File file;
    if (!isExternalStorageWritable(context)) {
        Logger.e("!!! external storage not writable");
        return null;
    }
    if (dir_name == null) {
        dir_path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator + DEFAULT_DIR_NAME;
    } else {
        dir_path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator + dir_name;
    }
    Logger.d("... going to access an external dir:" + dir_path);
    dir = new File(dir_path);
    if (!dir.exists()) {
        Logger.d("... going to mkdirs:" + dir_path);
        if (!dir.mkdirs()) {
            Logger.e("!!! failed to mkdirs");
            return null;
        }
    }
    if (file_name == null) {
        file_path = dir_path + File.separator + generateFileNameBasedOnTimeStamp();
    } else {
        file_path = dir_path + File.separator + file_name;
    }
    Logger.d("... going to return an external dir:" + file_path);
    file = new File(file_path);
    if (file.exists()) {
        Logger.d("... before creating to delete an external dir:" + file.getAbsolutePath());
        if (!file.delete()) {
            Logger.e("!!! failed to delete file");
            return null;
        }
    }
    return file;
}

public File createInternalFile(String dir_name, String file_name, Context context) {
    String dir_path;
    String file_path;
    File dir ;
    File file;
    if (dir_name == null) {
        dir = new ContextWrapper(context).getDir(DEFAULT_DIR_NAME, Context.MODE_PRIVATE);
    } else {
        dir = new ContextWrapper(context).getDir(dir_name, Context.MODE_PRIVATE);
    }
    dir_path = dir.getAbsolutePath();
    Logger.d("... going to access an internal dir:" + dir_path);
    if (!dir.exists()) {
        Logger.d("... going to mkdirs:" + dir_path);
        if (!dir.mkdirs()) {
            Logger.e("!!! mkdirs failed");
            return null;
        }
    }
    if (file_name == null) {
        file = new File(dir, generateFileNameBasedOnTimeStamp());
    } else {
        file = new File(dir, file_name);
    }
    file_path = file.getAbsolutePath();
    Logger.d("... going to return an internal dir:" + file_path);
    if (file.exists()) {
        Logger.d("... before creating to delete an external dir:" + file.getAbsolutePath());
        if (!file.delete()) {
            Logger.e("!!! failed to delete file");
            return null;
        }
    }
    return file;
}

public File getExternalFile(String dir_name, String file_name, Context context) {
    String dir_path;
    String file_path;
    File file;
    if (!isExternalStorageWritable(context)) {
        Logger.e("!!! external storage not writable");
        return null;
    }
    if (dir_name == null) {
        dir_path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator + DEFAULT_DIR_NAME;
    } else {
        dir_path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator + dir_name;
    }
    if (file_name == null) {
        file_path = dir_path;
    } else {
        file_path = dir_path + File.separator + file_name;
    }
    Logger.d("... going to return an external file:" + file_path);
    file = new File(file_path);
    if (file.exists()) {
        Logger.d("... file exists:" + file.getAbsolutePath());
    } else {
        Logger.e("!!! file does't exist:" + file.getAbsolutePath());
    }
    return file;
}

public File getInternalFile(String dir_name, String file_name, Context context) {
    String file_path;
    File dir ;
    File file;
    if (dir_name == null) {
        dir = new ContextWrapper(context).getDir(DEFAULT_DIR_NAME, Context.MODE_PRIVATE);
    } else {
        dir = new ContextWrapper(context).getDir(dir_name, Context.MODE_PRIVATE);
    }
    if (file_name == null) {
        file = new File(dir.getAbsolutePath());
    } else {
        file = new File(dir, file_name);
    }
    file_path = file.getAbsolutePath();
    Logger.d("... going to return an internal dir:" + file_path);
    if (file.exists()) {
        Logger.d("... file exists:" + file.getAbsolutePath());
    } else {
        Logger.e("!!! file does't exist:" + file.getAbsolutePath());
    }
    return file;
}

private byte[] readBytesFromFile(File file) {
    Logger.d(">>> path:" + file.getAbsolutePath());
    FileInputStream fis;
    long file_length;
    byte[] buffer;
    int offset = 0;
    int next = 0;
    if (!file.exists()) {
        Logger.e("!!! file doesn't exists");
        return null;
    }
    if (file.length() > Integer.MAX_VALUE) {
        Logger.e("!!! file length is out of max of int");
        return null;
    } else {
        file_length = file.length();
    }
    try {
        fis = new FileInputStream(file);
        //buffer = new byte[(int) file_length];
        buffer = new byte[(int) file.length()];
        long time_start = System.currentTimeMillis();
        while (true) {
            Logger.d("... now next:" + next + " and offset:" + offset);
            if (System.currentTimeMillis() - time_start > 1000) {
                Logger.e("!!! left due to time out");
                break;
            }
            next = fis.read(buffer, offset, (buffer.length-offset));
            if (next < 0 || offset >= buffer.length) {
                Logger.d("... completed to read");
                break;
            }
            offset += next;
        }
        //if (offset < buffer.length) {
        if (offset < (int) file_length) {
            Logger.e("!!! not complete to read");
            return null;
        }
        fis.close();
        return buffer;
    } catch (IOException e) {
        e.printStackTrace();
        Logger.e("!!! IOException");
        return null;
    }
}

public byte[] readBytesFromFile(File file, boolean is_fis_fos_only) {
    if (file == null) return null;
    if (is_fis_fos_only) {
        return readBytesFromFile(file);
    }
    Logger.d(">>> path:" + file.getAbsolutePath());
    FileInputStream fis;
    BufferedInputStream bis;
    ByteArrayOutputStream bos;
    byte[] buf = new byte[(int) file.length()];
    int num_read;
    if (!file.exists()) {
        Logger.e("!!! file doesn't exists");
        return null;
    }
    try {
        fis = new FileInputStream(file);
        bis = new BufferedInputStream(fis);
        bos = new ByteArrayOutputStream();
        long time_start = System.currentTimeMillis();
        while (true) {
            if (System.currentTimeMillis() - time_start > 1000) {
                Logger.e("!!! left due to time out");
                break;
            }
            num_read = bis.read(buf, 0, buf.length); //1024 bytes per call
            if (num_read < 0) break;
            bos.write(buf, 0, num_read);
        }
        buf = bos.toByteArray();
        fis.close();
        bis.close();
        bos.close();
        return buf;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        Logger.e("!!! FileNotFoundException");
        return null;
    } catch (IOException e) {
        e.printStackTrace();
        Logger.e("!!! IOException");
        return null;
    }
}

/**
 * streams (InputStream and OutputStream) transfer binary data
 * if to write a string to a stream, must first convert it to bytes, or in other words encode it
 */
public boolean writeStringToFile(File file, String string, Charset charset) {
    if (file == null) return false;
    if (string == null) return false;
    return writeBytesToFile(file, string.getBytes((charset == null) ? DEFAULT_CHARSET:charset));
}

public boolean writeBytesToFile(File file, byte[] data) {
    if (file == null) return false;
    if (data == null) return false;
    FileOutputStream fos;
    BufferedOutputStream bos;
    try {
        fos = new FileOutputStream(file);
        bos = new BufferedOutputStream(fos);
        bos.write(data, 0, data.length);
        bos.flush();
        bos.close();
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
        Logger.e("!!! IOException");
        return false;
    }
    return true;
}

/**
 * io blocks until some input/output is available.
 */
public boolean copy(File source, File destination) {
    if (source == null || destination == null) return false;
    Logger.d(">>> source:" + source.getAbsolutePath() + ", destination:" + destination.getAbsolutePath());
    try {
        FileInputStream fis = new FileInputStream(source);
        FileOutputStream fos = new FileOutputStream(destination);
        byte[] buffer = new byte[(int) source.length()];
        int len;
        while (EOF != (len = fis.read(buffer))) {
            fos.write(buffer, 0, len);
        }
        if (true) { //debug
            byte[] copies = readBytesFromFile(destination);
            if (copies != null) {
                int copy_len = copies.length;
                Logger.d("... stream read and write done for " + copy_len + " bytes");
            }
        }
        return destination.length() != 0;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}

public void list(final String path, final String end, final List<File> files) {
    Logger.d(">>> path:" + path + ", end:" + end);
    File file = new File(path);
    if (file.isDirectory()) {
        for (File child : file.listFiles()){
            list(child.getAbsolutePath(), end, files);
        }
    } else if (file.isFile()) {
        if (end.equals("")) {
            files.add(file);
        } else {
            if (file.getName().endsWith(end)) files.add(file);
        }
    }
}

public String[] splitFileName(File file, String split) {
    String path;
    String ext;
    int lastIndexOfSplit = file.getAbsolutePath().lastIndexOf(split);
    if (lastIndexOfSplit < 0) {
        path = file.getAbsolutePath();
        ext = "";
    } else {
        path = file.getAbsolutePath().substring(0, lastIndexOfSplit);
        ext = file.getAbsolutePath().substring(lastIndexOfSplit);
    }
    return new String[] {path, ext};
}

public File rename(File old_file, String new_name) {
    if (old_file == null || new_name == null) return null;
    Logger.d(">>> old file path:" + old_file.getAbsolutePath() + ", new file name:" + new_name);
    File new_file = new File(old_file, new_name);
    if (!old_file.equals(new_file)) {
        if (new_file.exists()) { //if find out previous file/dir at new path name exists
            if (new_file.delete()) {
                Logger.d("... succeeded to delete previous file at new abstract path name:" + new_file.getAbsolutePath());
            } else {
                Logger.e("!!! failed to delete previous file at new abstract path name");
                return null;
            }
        }
        if (old_file.renameTo(new_file)) {
            Logger.d("... succeeded to rename old file to new abstract path name:" + new_file.getAbsolutePath());
        } else {
            Logger.e("!!! failed to rename old file to new abstract path name");
        }
    } else {
        Logger.d("... new and old file have the equal abstract path name:" + new_file.getAbsolutePath());
    }
    return new_file;
}

public boolean remove(final String path, final String end) {
    Logger.d(">>> path:" + path + ", end:" + end);
    File file = new File(path);
    boolean result = false;
    if (file.isDirectory()) {
        for (File child : file.listFiles()){
            result = remove(child.getAbsolutePath(), end);
        }
    } else if (file.isFile()) {
        if (end.equals("")) {
            result = file.delete();
        } else {
            if (file.getName().endsWith(end)) result = file.delete();
        }
    } else {
        Logger.e("!!! child is not file or directory");
    }
    return result;
}

@TargetApi(Build.VERSION_CODES.O)
public byte[] readNIOBytesFromFile(String path) throws IOException {
    Logger.d(">>> path:" + path);
    if (!Files.exists(Paths.get(path), LinkOption.NOFOLLOW_LINKS)) {
        Logger.e("!!! file doesn't exists");
        return null;
    } else {
        return Files.readAllBytes(Paths.get(path));
    }
}

@TargetApi(Build.VERSION_CODES.O)
public File writeNIOBytesToFile(String dir, String name, byte[] data) {
    Logger.d(">>> dir:" + dir + ", name:" + name);
    Path path_dir;
    Path path_file;
    try {
        if (!Files.exists(Paths.get(dir), LinkOption.NOFOLLOW_LINKS)) {
            Logger.d("... make a dir");
            path_dir = Files.createDirectories(Paths.get(dir));
            if (path_dir == null) {
                Logger.e("!!! failed to make a dir");
                return null;
            }
        }
        path_file = Files.write(Paths.get(name), data);
        return path_file.toFile();
    } catch (IOException e) {
        e.printStackTrace();
        Logger.e("!!! IOException");
        return null;
    }
}

@TargetApi(Build.VERSION_CODES.O)
public void listNIO(final String dir, final String end, final List<File> files) throws IOException {
    Logger.d(">>> dir:" + dir + ", end:" + end);
    Files.walkFileTree(Paths.get(dir), new FileVisitor<Path>() {
        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
            Logger.d("... file:" + dir.getFileName());
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
            Logger.d("... file:" + file.getFileName());
            if (end.equals("")) {
                files.add(file.toFile());
            } else {
                if (file.endsWith(end)) files.add(file.toFile());
            }
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file, IOException exc) {
            Logger.d("... file:" + file.getFileName());
            if (end.equals("")) {
                files.add(file.toFile());
            } else {
                if (file.endsWith(end)) files.add(file.toFile());
            }
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
            Logger.d("... file:" + dir.getFileName());
            return FileVisitResult.CONTINUE;
        }
    });
}

/**
 * recursion
 */
private int factorial (int x) {
    if (x > 1) return (x*(factorial(x-1)));
    else if (x == 1) return x;
    else return 0;
}

}

Vigilant answered 22/11, 2018 at 7:29 Comment(0)
J
2

For getting a file properly using a context uri, Thanks to answers from @Mohsents , @Bogdan Kornev , @CommonsWare , @Juan Camilo Rodriguez Durán ;

I created an inputStream from uri and used this iStream to create a temporary file finally I am able to extract uri and path from this file.

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()
        }
    }
}
Jesusa answered 16/2, 2022 at 10:54 Comment(1)
Should the output stream be closed as well as flushed or closed instead of flushed?Locative
K
2

Some libraries are required File Objects for a process like a retrofit, some image editors e.t.c. to convert URI to file object or anything similar we have a way which is to support all android old versions and upcoming versions.

Step 1:

You have to create a new file inside FilesDir which is nonreadable to other Apps with the same name as our file and extension.

Step 2:

You have to copy the content of the URI to create a file by using InputStream.

File f = getFile(getApplicationContext(), uri);

public static File getFile(Context context, Uri uri) throws IOException {
    File destinationFilename = new File(context.getFilesDir().getPath() + File.separatorChar + queryName(context, uri));
    try (InputStream ins = context.getContentResolver().openInputStream(uri)) {
        createFileFromStream(ins, destinationFilename);
    } catch (Exception ex) {
        Log.e("Save File", ex.getMessage());
        ex.printStackTrace();
    }
    return destinationFilename;
}

public static void createFileFromStream(InputStream ins, File destination) {
    try (OutputStream os = new FileOutputStream(destination)) {
        byte[] buffer = new byte[4096];
        int length;
        while ((length = ins.read(buffer)) > 0) {
            os.write(buffer, 0, length);
        }
        os.flush();
    } catch (Exception ex) {
        Log.e("Save File", ex.getMessage());
        ex.printStackTrace();
    }
}

private static String queryName(Context context, Uri uri) {
    Cursor returnCursor =
            context.getContentResolver().query(uri, null, null, null, null);
    assert returnCursor != null;
    int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
    returnCursor.moveToFirst();
    String name = returnCursor.getString(nameIndex);
    returnCursor.close();
    return name;
}
Konrad answered 6/8, 2022 at 19:9 Comment(0)
C
1

I made this like the following way:

try {
    readImageInformation(new File(contentUri.getPath()));

} catch (IOException e) {
    readImageInformation(new File(getRealPathFromURI(context,
                contentUri)));
}

public static String getRealPathFromURI(Context context, Uri contentUri) {
        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);
}

So basically first I try to use a file i.e. picture taken by camera and saved on SD card. This don't work for image returned by: Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); That case there is a need to convert Uri to real path by getRealPathFromURI() function. So the conclusion is that it depends on what type of Uri you want to convert to File.

Comptometer answered 9/5, 2015 at 12:34 Comment(0)
S
1

After lots of searches and trying different approaches, I found this one working on different Android versions: First copy this function:

    fun getRealPathFromUri(context: Context, contentUri: Uri): String {
        var cursor: Cursor? = null
        try {
            val proj: Array<String> = arrayOf(MediaStore.Images.Media.DATA)
            cursor = context.contentResolver.query(contentUri, proj, null, null, null)
            val columnIndex = cursor?.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
            cursor?.moveToFirst()
            return columnIndex?.let { cursor?.getString(it) } ?: ""
        } finally {
            cursor?.close()
        }
    }

And then, generate a file like this:

File(getRealPathFromUri(context, uri))
Skimp answered 25/9, 2022 at 8:29 Comment(1)
As said in other answers, MediaStore.Images.Media.DATA is deprecated, also it is for images.Deepsix
D
0

uri.toString() gives me: "content://com.google.android.apps.nbu.files.provider/1/file%3A%2F%2F%2Fstorage%2Femulated%2F0%2FDownload%2Fbackup.file"

uri.getPath() gives me: "/1/file:///storage/emulated/0/Download/backup.file"

new File(uri.getPath()) gives me "/1/file:/storage/emulated/0/Download/backup.file".

So if you have an access to file and want to avoid using ContentResolver or directly reading file, the answer is:

private String uriToPath( Uri uri )
{
    File backupFile = new File( uri.getPath() );
    String absolutePath = backupFile.getAbsolutePath();
    return absolutePath.substring( absolutePath.indexOf( ':' ) + 1 );
}

Error handling is skipped to simplify the answer

Displace answered 12/5, 2021 at 7:58 Comment(1)
This does not work in android 10Blamed
S
0

you can use this function for get file from uri in new android and older

fun getFileFromUri(context: Context, uri: Uri?): File? {
    uri ?: return null
    uri.path ?: return null

    var newUriString = uri.toString()
    newUriString = newUriString.replace(
        "content://com.android.providers.downloads.documents/",
        "content://com.android.providers.media.documents/"
    )
    newUriString = newUriString.replace(
        "/msf%3A", "/image%3A"
    )
    val newUri = Uri.parse(newUriString)

    var realPath = String()
    val databaseUri: Uri
    val selection: String?
    val selectionArgs: Array<String>?
    if (newUri.path?.contains("/document/image:") == true) {
        databaseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        selection = "_id=?"
        selectionArgs = arrayOf(DocumentsContract.getDocumentId(newUri).split(":")[1])
    } else {
        databaseUri = newUri
        selection = null
        selectionArgs = null
    }
    try {
        val column = "_data"
        val projection = arrayOf(column)
        val cursor = context.contentResolver.query(
            databaseUri,
            projection,
            selection,
            selectionArgs,
            null
        )
        cursor?.let {
            if (it.moveToFirst()) {
                val columnIndex = cursor.getColumnIndexOrThrow(column)
                realPath = cursor.getString(columnIndex)
            }
            cursor.close()
        }
    } catch (e: Exception) {
        Log.i("GetFileUri Exception:", e.message ?: "")
    }
    val path = realPath.ifEmpty {
        when {
            newUri.path?.contains("/document/raw:") == true -> newUri.path?.replace(
                "/document/raw:",
                ""
            )
            newUri.path?.contains("/document/primary:") == true -> newUri.path?.replace(
                "/document/primary:",
                "/storage/emulated/0/"
            )
            else -> return null
        }
    }
    return if (path.isNullOrEmpty()) null else File(path)
}
Soares answered 15/6, 2021 at 17:2 Comment(0)
S
0

Use this to write to file, It worked for me when uri of gif was provided by GBoard and I have to copy that gif in my app data.

    try {
      String destinationFilePath = getExternalFilesDir("gifs") + "/tempFile.txt";
      InputStream inputStream = getContentResolver().openInputStream(uri);
      OutputStream outputStream = new FileOutputStream(destinationFilePath);

      byte[] buffer = new byte[1024];
      int bytesRead;

      while ((bytesRead = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, bytesRead);
      }

      inputStream.close();
      outputStream.close();
    }
    catch (Exception e) {
      e.printStackTrace();
    }
Schoen answered 7/5, 2022 at 12:11 Comment(0)
G
0

Kotlin 2022

suspend fun Context.createFileFromAsset(assetName: String, fileName: String): File? {
    return withContext(Dispatchers.IO) {
        runCatching {
            val stream = assets.open(assetName)
            val file = File(cacheDir.absolutePath, fileName)
            org.apache.commons.io.FileUtils.copyInputStreamToFile(stream, file)
            file
        }.onFailure { Timber.e(it) }.getOrNull()
    }
}

When done with the File make sure to call .delete() on it. Kudos to @Mohsent

Groggy answered 4/9, 2022 at 16:50 Comment(0)
O
0

Use this Method for Kotlin

private fun readAllData(path:Uri){
    lifecycleScope.launch(Dispatchers.IO){
        contentResolver.openInputStream(path)?.apply {
            val tmp = ByteArray(available())
            read(tmp)
            val strData = String(tmp)
            val files = path.path?.split("/")
            val fileName = files?.get(files.size-1)
            val ext = strData.split(".")[1]
            close()
        }
    }
}
Oshea answered 11/7, 2023 at 4:52 Comment(0)
T
0

It's constantly updating thema while Google constantly keeps changing the rules to access the FileSystem. We must now use the ContentResolver and get the File path from the Query. Query gives it in a column MediaStore.Images.Media.DATA if you have permission to access it.

This Example works from Android 7 till Android 13, you need only to ask for a right permissions.

If you don't have access, Uri gives an empty String.

fun getImage(cntx: Context, uriImg: Uri): MediaPic? {
    val uri: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
    Log.d ("TAG, urix", uriImg.lastPathSegment.toString())
    Log.d ("TAG, urix", uriImg.lastPathSegment!!.split(":")[1])
    val selectedID = uriImg.lastPathSegment!!.split(":")[1]
    val whereQuery = "_id=$selectedID"
    var theMediaPic: MediaPic? = null
    val projection = arrayOf ( MediaStore.Images.Media._ID, MediaStore.Images.Media.BUCKET_ID,
        MediaStore.Images.Media.BUCKET_DISPLAY_NAME, MediaStore.Images.Media.DISPLAY_NAME,
        MediaStore.Images.Media.DATA, MediaStore.Images.Media.SIZE, MediaStore.Images.Media.WIDTH,
        MediaStore.Images.Media.HEIGHT, MediaStore.Images.Media.DATE_ADDED, MediaStore.Images.Media.DESCRIPTION,
        MediaStore.Images.Media.TITLE, MediaStore.Images.Media.DATE_MODIFIED
    )

    val cursor: Cursor? = cntx.contentResolver.query(uri, projection, whereQuery, null, null)
    Log.d ("TAG, cursor", cursor.toString())

    //val ids: ArrayList<MediaPic> = arrayListOf()
    if (cursor != null) {
        Log.d ("TAG,cursor...", cursor.columnCount.toString())
        Log.d ("TAG, cursor...", cursor.count.toString())
        val columnIndex = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID)
        val columnBDN = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME)
        val columnDN = cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME)
        val columnId = cursor.getColumnIndex(MediaStore.Images.Media._ID)
        val columnData = cursor.getColumnIndex(MediaStore.Images.Media.DATA)
        val columnSize = cursor.getColumnIndex(MediaStore.Images.Media.SIZE)
        val columnWidth = cursor.getColumnIndex(MediaStore.Images.Media.WIDTH)
        val columnHeight = cursor.getColumnIndex(MediaStore.Images.Media.HEIGHT)
        val columnDate = cursor.getColumnIndex(MediaStore.Images.Media.DATE_ADDED)
        val columnDateModified = cursor.getColumnIndex(MediaStore.Images.Media.DATE_MODIFIED)
        val columnDescription = cursor.getColumnIndex(MediaStore.Images.Media.DESCRIPTION)
        val columnTitle = cursor.getColumnIndex(MediaStore.Images.Media.TITLE)
        while (cursor.moveToNext()) {
            val description: String? = cursor.getStringOrNull(columnDescription)
            val title: String = cursor.getString(columnTitle)?.toString() ?: ""
            val displayName: String = cursor.getString(columnDN)?.toString() ?: title
            val tMP = MediaPic (
                id = cursor.getLong(columnId),
                folderId = cursor.getString(columnIndex),
                folderName = cursor.getString(columnBDN),
                name = title.ifEmpty { displayName },
                path = cursor.getString(columnData),
                uri = Uri.parse(cursor.getString(columnData).orEmpty()),
                size = cursor.getLong(columnSize),
                resolution = Size (cursor.getInt(columnWidth), cursor.getInt(columnHeight)),
                description = description ?: displayName,
                date = cursor.getLong(columnDate)
            )
            theMediaPic = tMP
        }
    }
    cursor?.close()
    return theMediaPic
}
Triangular answered 8/8, 2023 at 21:20 Comment(0)
P
-1

For folks that are here looking for a solution for images in particular here it is.

private Bitmap getBitmapFromUri(Uri contentUri) {
        String path = null;
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = getContentResolver().query(contentUri, projection, null, null, null);
        if (cursor.moveToFirst()) {
            int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            path = cursor.getString(columnIndex);
        }
        cursor.close();
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        return bitmap;
    }
Photosynthesis answered 22/3, 2014 at 18:23 Comment(0)
O
-1

File imageToUpload = new File(new URI(androidURI.toString())); works if this is a file u have created in the external storage.

For example file:///storage/emulated/0/(some directory and file name)

Outermost answered 28/2, 2015 at 0:31 Comment(0)
P
-1

By the following code, I am able to get adobe application shared pdf file as a stream and saving into android application path

Android.Net.Uri fileuri =
    (Android.Net.Uri)Intent.GetParcelableExtra(Intent.ExtraStream);

    fileuri i am getting as {content://com.adobe.reader.fileprovider/root_external/
                                        data/data/com.adobe.reader/files/Downloads/sample.pdf}

    string filePath = fileuri.Path;

   filePath I am gettings as root_external/data/data/com.adobe.reader/files/Download/sample.pdf

      using (var stream = ContentResolver.OpenInputStream(fileuri))
      {
       byte[] fileByteArray = ToByteArray(stream); //only once you can read bytes from stream second time onwards it has zero bytes

       string fileDestinationPath ="<path of your destination> "
       convertByteArrayToPDF(fileByteArray, fileDestinationPath);//here pdf copied to your destination path
       }
     public static byte[] ToByteArray(Stream stream)
        {
            var bytes = new List<byte>();

            int b;
            while ((b = stream.ReadByte()) != -1)
                bytes.Add((byte)b);

            return bytes.ToArray();
        }

      public static string convertByteArrayToPDF(byte[] pdfByteArray, string filePath)
        {

            try
            {
                Java.IO.File data = new Java.IO.File(filePath);
                Java.IO.OutputStream outPut = new Java.IO.FileOutputStream(data);
                outPut.Write(pdfByteArray);
                return data.AbsolutePath;

            }
            catch (System.Exception ex)
            {
                return string.Empty;
            }
        }
Purl answered 31/8, 2018 at 16:18 Comment(0)
Y
-2

public String getRealPathFromURI(Uri uri) {

    String result;
    Cursor cursor = getContentResolver().query(uri, null, null, null, null);
    if (cursor == null) {
        result = uri.getPath();
        cursor.close();
        return result;
    }
    cursor.moveToFirst();
    int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
    result = cursor.getString(idx);
    cursor.close();
    return result;
}

Then using to get file from URI :

        File finalFile = newFile(getRealPathFromURI(uri));

--HOPE CAN HELP YOU----

Yasukoyataghan answered 20/3, 2018 at 4:56 Comment(1)
Note that this technique is banned on Android Q. You can no longer access the DATA column (and that was an unreliable approach in the first place).Neotropical
D
-2

Get the input stream using content resolver

InputStream inputStream = getContentResolver().openInputStream(uri);

Then copy the input stream into a file

FileUtils.copyInputStreamToFile(inputStream, file);

Sample utility method:

private File toFile(Uri uri) throws IOException {
        String displayName = "";
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);

        if(cursor != null && cursor.moveToFirst()){
            try {
                displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
            }finally {
                cursor.close();
            }
        }

        File file =  File.createTempFile(
                FilenameUtils.getBaseName(displayName),
                "."+FilenameUtils.getExtension(displayName)
        );
        InputStream inputStream = getContentResolver().openInputStream(uri);
        FileUtils.copyInputStreamToFile(inputStream, file);
        return file;
    }
Declaratory answered 21/10, 2020 at 16:35 Comment(0)
P
-3

Extension base on @Jacek Kwiecień answer for convert image uri to file

fun Uri.toImageFile(context: Context): File? {
    val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
    val cursor = context.contentResolver.query(this, filePathColumn, null, null, null)
    if (cursor != null) {
        if (cursor.moveToFirst()) {
            val columnIndex = cursor.getColumnIndex(filePathColumn[0])
            val filePath = cursor.getString(columnIndex)
            cursor.close()
            return File(filePath)
        }
        cursor.close()
    }
    return null
}

If we use File(uri.getPath()), it will not work

enter image description here

If we use extension from android-ktx, it still not work too because https://github.com/android/android-ktx/blob/master/src/main/java/androidx/core/net/Uri.kt

Proportioned answered 22/10, 2018 at 3:44 Comment(1)
Note that this technique is banned on Android Q. You can no longer access the DATA column (and that was an unreliable approach in the first place).Neotropical
G
-5

Add in onActivityResult, getting docx, or pdf file

var imageUriPath = ""
imageUriPath =
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val split = (imageUri.path ? : "").split(":") //split the path.
    split[1]
  } else {
    imageUri.path ? : ""
  }
val file = File(imageUriPath)
Grasmere answered 28/5, 2019 at 8:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.