Wie erhalte ich eine URI aus einer Asset-Datei?

127

Ich habe versucht, den URI-Pfad für eine Asset-Datei abzurufen.

uri = Uri.fromFile(new File("//assets/mydemo.txt"));

Wenn ich überprüfe, ob die Datei existiert, sehe ich, dass diese Datei nicht existiert

File f = new File(filepath);
if (f.exists() == true) {
    Log.e(TAG, "Valid :" + filepath);
} else {
    Log.e(TAG, "InValid :" + filepath);
}

Kann mir jemand sagen, wie ich den absoluten Pfad für eine im Asset-Ordner vorhandene Datei erwähnen kann

Titus
quelle

Antworten:

160

Es gibt keinen "absoluten Pfad für eine im Asset-Ordner vorhandene Datei". Der Inhalt des assets/Ordners Ihres Projekts wird in die APK-Datei gepackt. Verwenden Sie ein AssetManagerObjekt, um InputStreamein Asset abzurufen.

Für WebView, können Sie die Verwendung file UriSchema in der gleichen Weise würden Sie eine URL verwenden. Die Syntax für Assets lautet file:///android_asset/...(Hinweis: drei Schrägstriche), wobei die Auslassungspunkte der Pfad der Datei aus dem assets/Ordner sind.

CommonsWare
quelle
32
file://android_asset/..., wo ...ist der relative Pfad im assets/Verzeichnis Ihres Projekts .
CommonsWare
4
Hier ist ein Beispielprojekt mit file://android_asset/, jedoch nicht für Uri: github.com/commonsguy/cw-advandroid/tree/master/WebView/GeoWeb1
CommonsWare
20
@CommonsWare Es sieht so aus, als hätten Sie ein '/' in Ihrer URI verpasst. Es sollte sein file:///.
ThomasW
7
Ich habe dies als versucht new File("file:///android_asset/sounds/beep.mid");, aber die Ergebnisdatei existiert nicht. Irgendwelche Ideen? PS-Datei befindet sich im assets/sounds/Ordner.
Onkel Lem
3
Ist es richtig, dass ´file: ///android_asset/...´ nur in WebView funktioniert und es nicht möglich ist, InputStream mit URI / URL / Uri außerhalb von WebView abzurufen?
Lubbo
74

Die richtige URL lautet:

file:///android_asset/RELATIVEPATH

Dabei ist RELATIVEPATH der Pfad zu Ihrer Ressource relativ zum Assets-Ordner.

Beachten Sie die 3 / 's im Schema. Die Webansicht würde ohne die 3 keine meiner Assets laden. Ich habe 2 versucht, wie (zuvor) von CommonsWare kommentiert, und es würde nicht funktionieren. Dann schaute ich auf CommonsWares Quelle auf Github und bemerkte den zusätzlichen Schrägstrich.

Dieser Test wurde zwar nur mit dem 1.6 Android Emulator durchgeführt, aber ich bezweifle, dass er auf einem realen Gerät oder einer höheren Version anders ist.

BEARBEITEN: CommonsWare hat seine Antwort aktualisiert, um diese winzige Änderung widerzuspiegeln. Also habe ich das so bearbeitet, dass es mit seiner aktuellen Antwort immer noch Sinn macht.

Russ
quelle
Funktioniert nicht mehr String fileName = "file:///android_asset/file.csv"; System.out.println(new File(fileName).exists()); // prints false
Elgirhath
@Elgirhath Der Konstruktor File, der eine Zeichenfolge akzeptiert, erwartet einen Pfad, keinen URI . Ich habe seit einigen Jahren nicht mehr für Android codiert und die Dinge haben sich möglicherweise geändert. Ich bin mir nicht sicher, ob Sie mit einer normalen Java-Dateiklasse auf den Ordner für eingebettete Assets zugreifen können. Ich scheine mich zu erinnern, dass Sie einen AssetManager verwenden müssen . Dateien im Assets-Ordner werden im schreibgeschützten, gebündelten APK auf dem Gerät abgelegt und komprimiert (APKs sind eigentlich Zip-Dateien), sodass mehr Arbeit erforderlich ist, um sie zurückzulesen. Versuchen Sie etwas wienew File(new URI(filename))
Russ
10

Bitte versuchen Sie, dass dieser Code gut funktioniert

 Uri imageUri = Uri.fromFile(new File("//android_asset/luc.jpeg"));

    /* 2) Create a new Intent */
    Intent imageEditorIntent = new AdobeImageIntent.Builder(this)
            .setData(imageUri)
            .build();
Raaz Thakur
quelle
8

Schließlich habe ich aus dieser Antwort in Kotlin einen Weg gefunden, den Pfad einer Datei zu ermitteln, die in Assets vorhanden ist . Hier kopieren wir die Assets-Datei in den Cache und rufen den Dateipfad aus dieser Cache-Datei ab.

@Throws(IOException::class)
    fun getFileFromAssets(context: Context, fileName: String): File = File(context.cacheDir, fileName)
            .also {
               if (!it.exists()) {
                it.outputStream().use { cache ->
                    context.assets.open(fileName).use { inputStream ->
                            inputStream.copyTo(cache)
                    }
                  }
                }
            }

Holen Sie sich den Pfad zur Datei wie folgt:

val filePath =  getFileFromAssets(context, "fileName.extension").absolutePath
Shylendra Madda
quelle
1
Beachten Sie, dass wenn das fileNameVerzeichnis haben dir/file. Es wird mit Pfad abstürzen, der cache/dir/filenicht existiert. Ich denke auch, dass es besser ist, eine Überprüfung if(!it.exist)innerhalb des alsoBlocks durchzuführen, dann wird die Datei nicht jedes Mal kopiert, selbst wenn sich die Datei bereits im Cache befindet
Yeung
@ShylendraMadda, @Yeung, if(!it.exist)gibt einen Fehler ungelöste Referenz. irgendeine Lösung ?
Binrebin
Überprüfen Sie, ob die Datei mit diesem Dateinamen in Ihrem Cache vorhanden ist. @ Binrebin
Shylendra Madda
@ ShylendraMadda, ich kenne nur den Dateinamen. Können wir es mit Skript geladen werden, ohne dass tatsächlich uri zu wissen
binrebin
Ich denke if(!it.exist)sollte vorher setzen it.outputStream()...
Yeung
7

Geben Sie hier die Bildbeschreibung ein

Stellen Sie sicher, dass sich Ihr Assets-Ordner in der richtigen Position befindet.

Chuanhang.gu
quelle
Sie können es beliebig platzieren und den Pfad in Ihrer build.gradle-Datei wie folgt definierensourceSets { main { assets.srcDirs = ['src/main/assets'] } }
Marcel Bro
2
Wie bekomme ich den Pfad von hello.html? Bitte hinzufügen
Rohit Singh
6

Funktioniert für WebView, scheint aber zu scheitern URL.openStream(). Sie müssen also die Protokolle file: // unterscheiden und sie wie vorgeschlagen über AssetManager verarbeiten.

Gaylord Zach
quelle
4

Probieren Sie es aus, es funktioniert:

InputStream in_s = 
    getClass().getClassLoader().getResourceAsStream("TopBrands.xml");

Wenn Sie eine Nullwertausnahme erhalten, versuchen Sie Folgendes (mit Klasse TopBrandData):

InputStream in_s1 =
    TopBrandData.class.getResourceAsStream("/assets/TopBrands.xml");
Jaspreet Singh
quelle
Wenn dies nicht funktioniert, versuchen Sie Folgendes: InputStream in_s1 = TopBrandData.class.getResourceAsStream ("/ assets / TopBrands.xml");
Jaspreet Singh
3
InputStream is = getResources().getAssets().open("terms.txt");
String textfile = convertStreamToString(is);
    
public static String convertStreamToString(InputStream is)
        throws IOException {

    Writer writer = new StringWriter();
    char[] buffer = new char[2048];

    try {
        Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        int n;
        while ((n = reader.read(buffer)) != -1) {
            writer.write(buffer, 0, n);
        }
    } finally {
        is.close();
    }

    String text = writer.toString();
    return text;
}
Jayesh Kavathiya
quelle
1

Versuche dies :

Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.cat); 

Ich hatte es getan und es hat funktioniert

Nyle
quelle
2
Eigentlich funktioniert es. Überprüfen Sie ContentResolver.openAssetFileDescriptor
Hippo Seven
1
Hat funktioniert. Vielen Dank. Lol, ich suche nur nach einer URI-internen Datei.
Phnghue
0

Ja, Sie können nicht von Ihrem Android-Telefon oder Emulator auf Ihren Laufwerksordner zugreifen, da Ihr Computer und Android zwei verschiedene Betriebssysteme sind. Ich würde mich für den Res-Ordner von Android entscheiden, da er über gute Methoden zur Ressourcenverwaltung verfügt. Bis und solange Sie keinen guten Grund haben, Ihre Datei in den Assets-Ordner zu legen. Stattdessen können Sie dies tun

try {
      Resources res = getResources();
      InputStream in_s = res.openRawResource(R.raw.yourfile);

      byte[] b = new byte[in_s.available()];
      in_s.read(b);
      String str = new String(b);
    } catch (Exception e) {
      Log.e(LOG_TAG, "File Reading Error", e);
 }
wird nicht aufhören
quelle
-7

Arbeitete für mich Versuchen Sie diesen Code

   uri = Uri.fromFile(new File("//assets/testdemo.txt"));
   String testfilepath = uri.getPath();
    File f = new File(testfilepath);
    if (f.exists() == true) {
    Toast.makeText(getApplicationContext(),"valid :" + testfilepath, 2000).show();
    } else {
   Toast.makeText(getApplicationContext(),"invalid :" + testfilepath, 2000).show();
 }
Irfan Ali
quelle