508 Stimmen

Datei konvertieren: Uri in Datei in Android

Wie konvertiert man am einfachsten von einer android.net.Uri Objekt, das eine file: Typ zu einer File Objekt in Android?

Ich habe das Folgende versucht, aber es funktioniert nicht:

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

0 Stimmen

Hier ist meine Lösung!! Es funktioniert gut! stackoverflow.com/questions/2789276/

1 Stimmen

0 Stimmen

Was bewirkt assertEquals?

947voto

Adil Hussain Punkte 27332

Was Sie wollen, ist...

new File(uri.getPath());

... und nicht...

new File(uri.toString());
Notas
  1. Für eine android.net.Uri Objekt mit dem Namen uri und genau so erstellt wie in die Frage , uri.toString() gibt eine String im Format "file:///mnt/sdcard/myPicture.jpg" in der Erwägung, dass uri.getPath() gibt eine String im Format "/mnt/sdcard/myPicture.jpg" .
  2. Ich weiß, dass es bei der Dateispeicherung in Android einige Besonderheiten gibt. Meine Absicht in dieser Antwort ist es, genau das zu beantworten, was der Fragesteller gefragt hat, und nicht auf die Feinheiten einzugehen.

5 Stimmen

Worin besteht der Unterschied zwischen den beiden? Was bedeutet toString tun?

96 Stimmen

url.toString() einen String im folgenden Format zurück: "file:///mnt/sdcard/myPicture.jpg", während url.getPath() gibt einen String im folgenden Format zurück: "/mnt/sdcard/myPicture.jpg", d.h. ohne den vorangestellten Schematyp.

48 Stimmen

Wenn der URI ein Images.Media.EXTERNAL_CONTENT_URI ist (z. B. von Intent.ACTION_PICK für die Galerie), müssen Sie ihn wie folgt nachschlagen stackoverflow.com/q/6935497/42619

112voto

Verwenden.

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

direkt und kopieren Sie die Datei. Siehe auch:

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

4 Stimmen

Dies sollte viel mehr hochgevotet werden. ContentResolver ist, was es scheint, dass Sie standardmäßig den Pfad von Android.Net.Uri auflösen werden.

0 Stimmen

Ich möchte eine weitere upVote hinzufügen, aber es stellt sich heraus, dass ich das nur einmal tun kann!

0 Stimmen

Wir haben eine Datei aus einer Auswahlliste ausgewählt, und dann müssen wir die Datei erst kopieren? :/

71voto

Sanket Berde Punkte 6091

Nach langem Suchen hat das bei mir funktioniert:

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

8 Stimmen

managedQuery ist jetzt veraltet. Verwenden Sie getContentResolver().query(...) die mit API 11+ funktioniert. Fügen Sie eine Bedingung für Geräte hinzu, die älter als API 11 sind.

5 Stimmen

Aus irgendeinem Grund erhalte ich hier null. Und meine Android Uri ist gibt so etwas zurück:{content://com.Android.providers.media.documents/document/image%3A2741} Android.Net.UriInvoker

0 Stimmen

Dies ist keine gute Lösung, da sie nicht auf allen Plattformen funktioniert. Einige Geräte füllen diese Spalte nicht einmal aus. Ich empfehle, dies dem Inhaltsanbieter zu überlassen, wie von @CommonWare in einer früheren Antwort vorgeschlagen

40voto

Hemant Kaushik Punkte 1652

Android + Kotlin

  1. Hinzufügen der Abhängigkeit für Kotlin Android Erweiterungen:

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

  2. Datei von uri abrufen:

    uri.toFile()

Android + Java

Einfach nach oben verschieben ;)

1 Stimmen

Ich habe Folgendes versucht: androidx.core:core-ktx:1.5.0-alpha01 . Ich sehe diese Funktion "toFile" nicht.

0 Stimmen

@M.UsmanKhan gemäß der Dokumentationsversion 1.5.0-alpha01 kann mit minimalem Aufwand verwendet werden Android 11 Beta 01 so können Sie versuchen 1.4.0-alpha01 oder stabile Version 1.3.0 . Mehr Informationen: developer.Android.com/jetpack/androidx/releases/

0 Stimmen

@M.UsmanKhan es existiert in der Version 1.3.0 , developer.Android.com/kotlin/ktx/

38voto

vishwajit76 Punkte 1813

Beste Lösung

Eine einfache FileUtil-Klasse erstellen und zum Erstellen, Kopieren und Umbenennen der Datei verwenden

Ich habe uri.toString() y uri.getPath() aber für mich nicht funktionieren. Ich habe schließlich diese Lösung gefunden.

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

Verwenden Sie die Klasse FileUtil in Ihrem 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();
  }

0 Stimmen

Dies funktioniert, aber wenn ich ein Bild aus der Galerie auswähle, wird ein Fehler in der Zeile von: InputStream inputStream = context.getContentResolver().openInputStream(uri);

0 Stimmen

Es hat sehr gut funktioniert, aber auf einigen Android-Geräten wird eine FileNotFoundException ausgelöst.

0 Stimmen

Verwenden Sie diesen Code, um ein Foto von der Kamera auszuwählen stackoverflow.com/a/51095098/7008132

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X