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());
hpique
źródło
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".

Adil Hussain
źródło
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;
    }
Sanket Berde
źródło
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

Juan Camilo Rodriguez Durán
źródło
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.

Matthew Flaschen
źródło
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();
  }
vishwajit76
źródło
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();
Jacek Kwiecień
źródło
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ę;)

Hemant Kaushik
źródło
3
Działa to tylko wtedy, gdy schemat uri jest ustawiony nafile
MatPag,
7

Z Kotlin jest jeszcze łatwiej:

val file = File(uri.path)

Lub jeśli używasz rozszerzeń Kotlin dla Androida :

val file = uri.toFile()
Włodzimierz
źródło
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()

Bogdan Kornev
źródło
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.

Kovács Ede
źródło
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.

Ciężkie bombardowanie
źródło
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;
}

}

牟家宏
źródło
-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;
    }
SARose
źródło
-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)

Sayooj
źródło
-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 ----

Phạm Hùng
źródło
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;
            }
        }
NagendraBabu
źródło
-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

Phan Van Linh
źródło
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)
Jotaro Kujo-kun
źródło