Konwertuj plik: Uri na plik w Androidzie


401

Jaki jest najłatwiejszy sposób konwersji z file: android.net.Uri na FileAndroid?

Próbowałem następujących, ale to nie działa:

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

Oto moje rozwiązanie !! To dobrze działa! stackoverflow.com/questions/2789276/…
— cesards


Co robi assertEquals?
— Huzaifa Asif

Kontekst Uri.fromFile po prostu nie działa na mnie :(
— Bay

Odpowiedzi:


781

To czego chcesz to ...

new File(uri.getPath());

... i nie...

new File(uri.toString());

UWAGA: uri.toString() Zwraca ciąg znaków w formacie: "file:///mnt/sdcard/myPicture.jpg", natomiast uri.getPath()zwraca ciąg w formacie: "/mnt/sdcard/myPicture.jpg".


4
Jaka jest różnica między nimi? Co ma toStringzrobić?
— Merlyn Morgan-Graham,

86
url.toString()zwraca ciąg w następującym formacie: „plik: ///mnt/sdcard/myPicture.jpg”, podczas gdy url.getPath()zwraca ciąg w następującym formacie: „/mnt/sdcard/myPicture.jpg”, tzn. bez typu schematu naprawiony.
— Adil Hussain,

44
Jeśli identyfikator URI to Images.Media.EXTERNAL_CONTENT_URI (np. Z Intent.ACTION_PICK dla galerii), musisz go wyszukać, jak na stackoverflow.com/q/6935497/42619
— Nuthatch

2
@Chlebta sprawdź bibliotekę o nazwie Picasso, aby bardzo łatwo ładować pliki (nawet adresy URL) do ImageViews.
— Virat Singh,

18
Przez większość czasu otrzymuję, open failed: ENOENT (No such file or directory)gdy próbuję otworzyć podany plik. Ponadto, jeśli Uri jest na przykład Uri treści obrazu, to na pewno nie działa.
— clu

50

Po długich poszukiwaniach, to działało dla mnie:

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

6
managedQueryjest teraz przestarzałe getContentResolver().query(...)zamiast tego użyj , który działa na API 11+. Dodaj warunek dla urządzeń starszych niż API 11.
— Kyle Falconer

2
Z jakiegoś powodu zwraca mi wartość null. A mój Android Uri zwraca coś takiego: {content: //com.android.providers.media.documents/document/image%3A2741} Android.Net.UriInvoker
— erkinyldz

To nie jest dobre rozwiązanie, ponieważ nie będzie działać na wszystkich platformach. Niektóre urządzenia nawet nie wypełniają tej kolumny, zalecam, aby dostawca treści poradził sobie z tym, jak sugeruje @CommonWare w poprzedniej odpowiedzi
— Liran Cohen

3
dotyczy tylko pliku typu obrazu, a co z innymi?
— Pratibha sarve

2
Upewnij się, że otrzymujesz swój identyfikator uri od Intent.ACTION_PICK, a nie Intent.ACTION_GET_CONTENT, ponieważ później nie ma MediaStore.Images.Media.DATA
— Denys Lobur

34

posługiwać się

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

bezpośrednio i skopiuj plik. Zobacz także:

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


1
To powinno być oceniane znacznie więcej. ContentResolver jest tym, na co domyślnie spojrzysz, aby rozwiązać ścieżkę z Android.Net.Uri.
— Mike Makarov

Chcę dodać kolejny głos, ale okazuje się, że mogę to zrobić tylko raz!
— Xenolion

27

EDYCJA: Przepraszam, powinienem był wcześniej przetestować lepiej. To powinno działać:

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

Identyfikator URI to java.net.URI.


3
Ach, ale pytanie brzmi Uri, a nie URI. Ludzie muszą na to uważać :)
— Muz

1
@Muz, uważam, że odpowiedź jest prawidłowa. androidURIto android.net.Uri. java.net.URI (który istnieje na Androidzie) jest używany tylko jako część procesu konwersji.
— Matthew Flaschen

2
Czy nie możemy po prostu zrobić: nowy plik (uri.getPath ());
— Bart Burg

14
To tylko rzuca: IllegalArgumentException: Oczekiwany schemat plików w URI: content: // media / external / images / media / 80038
— Jacek Kwiecień

7
Otrzymuję java.lang.IllegalArgumentException: Expected file scheme in URI: content://com.shajeel.daily_monitoring.localstorage.documents.localstorage.documents/document/%2Fstorage%2Femulated%2F0%2FBook1.xlsxwyjątek po użyciu tej metody.
— Shajeel Afzal

15

Najlepsze rozwiązanie

Utwórz jedną prostą klasę FileUtil i użyj jej do utworzenia, skopiowania i zmiany nazwy pliku

Używam uri.toString() i uri.getPath()nie pracuję dla mnie. W końcu znalazłem to rozwiązanie.

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

Użyj klasy FileUtil w swoim kodzie

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

  } catch (IOException e) {
          e.printStackTrace();
  }

działa to, ale kiedy wybieram obraz z galerii, generuje błąd w wierszu: InputStream inputStream = context.getContentResolver (). openInputStream (uri);
— Vahid Akbari

Działa bardzo dobrze, ale generuje FileNotFoundException na niektórych urządzeniach z Androidem.
— vishwajit76

to nie działa z aparatem
— suyash saurabh

Użyj tego kodu, aby wybrać zdjęcie z aparatu stackoverflow.com/a/51095098/7008132
— vishwajit76

13

Nic z tego nie działa dla mnie. Znalazłem to działające rozwiązanie. Ale moja sprawa jest specyficzna dla obrazów .

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

To powinna być odpowiedź! :) Przetestowałem to na API 25.
— iroiroys

4
Pamiętaj, że ta technika jest zabroniona na Androidzie Q. Nie możesz już uzyskać dostępu do kolumny DANE (i to było przede wszystkim zawodne podejście).
— CommonsWare

13

Android + Kotlin

  1. Dodaj zależność dla rozszerzeń Kotlin dla Androida:

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

  2. Pobierz plik z URI:

    uri.toFile()

Android + Java

Po prostu przejdź na górę;)


3
Działa to tylko wtedy, gdy schemat uri jest ustawiony nafile
— MatPag,


2

@CommonsWare całkiem dobrze wyjaśnił wszystkie rzeczy. I naprawdę powinniśmy skorzystać z zaproponowanego przez niego rozwiązania.

Nawiasem mówiąc, tylko informacje, na których mogliśmy polegać podczas wyszukiwania, ContentResolverto nazwa i rozmiar pliku, jak wspomniano tutaj: Pobieranie informacji o pliku | Programiści Androida

Jak widać, istnieje interfejs OpenableColumnszawierający tylko dwa pola: DISPLAY_NAME i SIZE.

W moim przypadku musiałem pobrać informacje EXIF ​​dotyczące obrazu JPEG i obrócić je w razie potrzeby przed wysłaniem na serwer. W tym celu skopiowałem zawartość pliku do pliku tymczasowego za pomocą ContentResolveriopenInputStream()


1

Zrobiłem to w następujący sposób:

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

Zasadniczo najpierw próbuję użyć pliku, tj. Zdjęcia zrobionego aparatem i zapisanego na karcie SD. To nie działa dla obrazu zwróconego przez: Intent photoPickerIntent = nowy Intent (Intent.ACTION_PICK); W takim przypadku należy przekonwertować Uri na ścieżkę rzeczywistą według getRealPathFromURI()funkcji. Wniosek jest taki, że zależy to od tego, jaki typ Uri chcesz przekonwertować na plik.


1

Jeśli masz taki, Uriktóry jest zgodny z tym DocumentContract, prawdopodobnie nie chcesz go używać File. Jeśli jesteś na kotlinie, użyj DocumentFilerzeczy, których używałbyś w starym świecie File, i używajContentResolver aby uzyskać strumienie.

Wszystko inne jest prawie całkowicie zepsute.


0

W tym przypadku, szczególnie na Androidzie, droga do bajtów jest zwykle szybsza.

Dzięki temu rozwiązałem to, ustanawiając klasę FileHelper której powierzono odpowiedzialność za odczytywanie / zapisywanie bajtów z / do pliku poprzez strumień, oraz klasę, UriHelperktórej powierzono obowiązek ustalenia ścieżki Uri i pozwolenia.

O ile ogólnie wiadomo, string.getBytes((charset == null) ? DEFAULT_CHARSET:charset)może pomóc nam przenieść ciąg znaków, który chcesz bajtów, których potrzebujesz.

Jak zezwolić UriHelper i FileHelper na skopiowanie obrazu zaznaczonego przez Uri do pliku, możesz uruchomić:

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

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

}

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

}


-1

Dla osób, które tutaj szukają rozwiązania dla obrazów w szczególności tutaj jest.

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

-1

Plik imageToUpload = nowy plik (nowy URI (androidURI.toString ())); działa, jeśli jest to plik utworzony w pamięci zewnętrznej.

Na przykład plik: /// storage / emulated / 0 / (niektóre nazwy katalogów i plików)


-1

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

Następnie za pomocą, aby uzyskać plik z URI:

        File finalFile = newFile(getRealPathFromURI(uri));

- NADZIEJA MOŻE CI POMÓC ----


1
Pamiętaj, że ta technika jest zabroniona na Androidzie Q. Nie możesz już uzyskać dostępu do kolumny DANE (i to było przede wszystkim zawodne podejście).
— CommonsWare

-1

Dzięki poniższemu kodowi jestem w stanie uzyskać udostępniony plik pdf aplikacji Adobe jako strumień i zapisać w ścieżce aplikacji Androida

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

-2

Rozszerzenie bazy na odpowiedź @Jacek Kwiecień na konwersję obrazu uri do pliku

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
}

Jeśli użyjemy File(uri.getPath()), to nie będzie działać

wprowadź opis zdjęcia tutaj

Jeśli użyjemy rozszerzenia z Androida-ktx , nadal nie będzie działać, ponieważ https://github.com/android/android-ktx/blob/master/src/main/java/androidx/core/net/Uri.kt


2
Pamiętaj, że ta technika jest zabroniona na Androidzie Q. Nie możesz już uzyskać dostępu do DATAkolumny (i to było przede wszystkim niewiarygodne).
— CommonsWare

-2

Dodaj onActivityResult, pobierz plik docx lub pdf

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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.