Конвертировать файл: Uri в файл в Android - PullRequest
342 голосов
/ 04 июня 2010

Какой самый простой способ конвертировать file: android.net.Uri в File в Android?

Пробовал следующее, но это не работает:

 final File file = new File(Environment.getExternalStorageDirectory(), "read.me");
 Uri uri = Uri.fromFile(file);
 File auxFile = new File(uri.toString());
 assertEquals(file.getAbsolutePath(), auxFile.getAbsolutePath());

Ответы [ 17 ]

694 голосов
/ 03 декабря 2011

То, что вы хотите, это ...

new File(uri.getPath());

... а не ...

new File(uri.toString());

ПРИМЕЧАНИЕ: uri.toString() возвращает строку в формате: "file:///mnt/sdcard/myPicture.jpg", тогда как uri.getPath() возвращает строку в формате: "/mnt/sdcard/myPicture.jpg".

37 голосов
/ 12 мая 2013

После долгих поисков вот что у меня сработало:

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;
    }
26 голосов
/ 04 июня 2010

РЕДАКТИРОВАТЬ: Извините, я должен был проверить лучше раньше. Это должно работать:

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

URI - это java.net.URI.

12 голосов
/ 25 июля 2016

использование

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

напрямую и скопируйте файл. Также см .:

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

11 голосов
/ 10 апреля 2014

Ничего из этого не работает для меня. Я нашел это, чтобы быть рабочим решением. Но мой случай относится только к изображениям .

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();
8 голосов
/ 30 августа 2018

Лучшее решение

Создать один простой Java-класс FileUtil и использовать для создания, копирования и переименования файла

Я использую uri.toString() и uri.getPath(), но у меня не работает. Я наконец нашел это решение.

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;
    }
}

Используйте класс FileUtil в своем коде

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

  } catch (IOException e) {
          e.printStackTrace();
  }
4 голосов
/ 07 июня 2018

С Kotlin это еще проще:

val file = File(uri.path)

Или, если вы используете расширения Kotlin для Android :

val file = uri.toFile()
4 голосов
/ 25 мая 2018

Android + Kotlin

  1. Добавить зависимость для расширений Kotlin Android:

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

  2. Получить файл из uri:

    uri.toFile()

Android + Java

Просто перейти наверх;)

1 голос
/ 09 мая 2015

Я сделал это следующим образом:

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);
}

Итак, сначала я пытаюсь использовать файл, то есть снимок, сделанный камерой и сохраненный на SD-карте. Это не работает для изображения, возвращенного: Intent photoPickerIntent = новое намерение (Intent.ACTION_PICK); В этом случае необходимо преобразовать Uri в реальный путь с помощью функции getRealPathFromURI(). Таким образом, вывод заключается в том, что это зависит от того, какой тип Uri вы хотите преобразовать в File.

1 голос
/ 09 марта 2017

@ CommonsWare объяснил все достаточно хорошо. И мы действительно должны использовать предложенное им решение.

Кстати, единственная информация, на которую мы можем полагаться при запросе ContentResolver - это имя и размер файла, как указано здесь: Получение информации о файле | Разработчики Android

Как вы могли видеть, существует интерфейс OpenableColumns, который содержит только два поля: DISPLAY_NAME и SIZE.

В моем случае мне нужно было получить EXIF-информацию об изображении JPEG и повернуть ее, если необходимо, перед отправкой на сервер. Для этого я скопировал содержимое файла во временный файл, используя ContentResolver и openInputStream()

...