Jak uzyskać identyfikator URI z pliku zasobów?

127

Próbowałem uzyskać ścieżkę URI dla pliku aktywów.

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

Kiedy sprawdzam, czy plik istnieje, widzę, że plik nie istnieje

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

Czy ktoś może mi powiedzieć, jak mogę wymienić bezwzględną ścieżkę do pliku istniejącego w folderze zasobów

Titus
źródło

Odpowiedzi:

160

Nie ma „bezwzględnej ścieżki do pliku istniejącego w folderze zasobów”. Zawartość assets/folderu Twojego projektu jest spakowana w pliku APK. Użyj AssetManagerobiektu, aby uzyskać informację InputStreamo zasobie.

Ponieważ WebViewmożesz używać file Urischematu w taki sam sposób, jak używasz adresu URL. Składnia zasobów to file:///android_asset/...(uwaga: trzy ukośniki), gdzie wielokropek oznacza ścieżkę do pliku z assets/folderu.

CommonsWare
źródło
32
file://android_asset/..., gdzie ...jest ścieżką względną w assets/katalogu twojego projektu .
CommonsWare
4
Oto przykładowy projekt wykorzystujący file://android_asset/, choć nie dla Uri: github.com/commonsguy/cw-advandroid/tree/master/WebView/GeoWeb1
CommonsWare
20
@CommonsWare wygląda na to, że przegapiłeś „/” w swoim identyfikatorze URI. Tak powinno być file:///.
ThomasW
7
Próbowałem tego jako new File("file:///android_asset/sounds/beep.mid");, ale plik wynikowy nie istnieje. Jakieś pomysły? Plik PS znajduje się w assets/sounds/folderze.
wujek Lem
3
Czy to prawda, że ​​„plik: ///android_asset/...” działa tylko w WebView i nie jest możliwe pobranie InputStream za pomocą URI / URL / Uri poza WebView?
Lubbo
74

Prawidłowy adres URL to:

file:///android_asset/RELATIVEPATH

gdzie RELATIVEPATH jest ścieżką do twojego zasobu względem folderu zasobów.

Zwróć uwagę na 3 / w schemacie. Widok sieciowy nie załadowałby żadnego z moich zasobów bez 3. Próbowałem 2, jak (poprzednio) skomentował CommonsWare, i nie zadziałałoby. Potem spojrzałem na źródło CommonsWare na githubie i zauważyłem dodatkowy ukośnik.

Testy te zostały jednak przeprowadzone tylko na emulatorze Androida 1.6, ale wątpię, by było inaczej na prawdziwym urządzeniu lub w wyższej wersji.

EDYCJA: CommonsWare zaktualizował swoją odpowiedź, aby odzwierciedlić tę drobną zmianę. Więc zredagowałem to, więc jego obecna odpowiedź nadal ma sens.

Russ
źródło
String fileName = "file:///android_asset/file.csv"; System.out.println(new File(fileName).exists()); // prints false
Już
@Elgirhath konstruktor dla, Filektóry akceptuje ciąg znaków oczekuje ścieżki, a nie identyfikatora URI . Od kilku lat nie kodowałem dla Androida i mogło się to zmienić. Nie jestem pewien, czy możesz uzyskać dostęp do folderu zasobów osadzonych przy użyciu normalnej klasy plików Java. Wydaje mi się, że pamiętam, że musisz użyć AssetManagera . Pliki w folderze zasobów są umieszczane na urządzeniu w pakiecie APK tylko do odczytu i kompresowane (pliki APK to w rzeczywistości pliki ZIP), dzięki czemu więcej pracy, aby je ponownie odczytać. Spróbuj na przykładnew File(new URI(filename))
Russ
10

Spróbuj, aby ten kod działał poprawnie

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

Wreszcie znalazłem sposób, aby uzyskać ścieżkę do pliku, który jest obecny w zasobach z tej odpowiedzi w Kotlinie. Tutaj kopiujemy plik zasobów do pamięci podręcznej i uzyskujemy ścieżkę do pliku z tego pliku pamięci podręcznej.

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

Uzyskaj ścieżkę do pliku, na przykład:

val filePath =  getFileFromAssets(context, "fileName.extension").absolutePath
Shylendra Madda
źródło
1
Zwróć uwagę, że jeśli plik fileNamehave directory dir/file. Spadnie ze ścieżką, która cache/dir/filenie istnieje. Myślę też, że lepiej mieć sprawdzenie if(!it.exist)wewnątrz alsobloku, wtedy nie skopiuje pliku za każdym razem, gdy plik jest już w pamięci podręcznej
Yeung
@ShylendraMadda, @Yeung, if(!it.exist)zgłasza błąd nierozwiązane odwołanie. jakieś rozwiązanie?
binrebin
Sprawdź, czy w pamięci podręcznej istnieje plik o tej nazwie? @binrebin
Shylendra Madda
@ShylendraMadda, znam tylko nazwę pliku. Czy możemy załadować go skryptem, nie znając faktycznego uri
binrebin
Myślę, że if(!it.exist)powinienem wstawić przed it.outputStream()...
Yeung
7

wprowadź opis obrazu tutaj

Upewnij się, że folder zasobów jest umieszczony we właściwej pozycji.

Chuanhang.gu
źródło
Możesz go umieścić w dowolnym miejscu i zdefiniować ścieżkę w pliku build.gradle w następujący sposóbsourceSets { main { assets.srcDirs = ['src/main/assets'] } }
Marcel Bro
2
Jak zdobyć ścieżkę do hello.html? proszę dodać
Rohit Singh,
6

Działa dla WebView, ale wydaje się, że nie działa URL.openStream(). Musisz więc rozróżniać protokoły file: // i obsługiwać je przez AssetManager zgodnie z sugestią.

Gaylord Zach
źródło
4

Wypróbuj to, działa:

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

Jeśli otrzymasz wyjątek wartości null, spróbuj tego (z klasą TopBrandData):

InputStream in_s1 =
    TopBrandData.class.getResourceAsStream("/assets/TopBrands.xml");
Jaspreet Singh
źródło
Jeśli nie działa, wypróbuj to: InputStream in_s1 = TopBrandData.class.getResourceAsStream ("/ asset / 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
źródło
1

Spróbuj tego :

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

Zrobiłem to i zadziałało

Nyle
źródło
2
Właściwie to działa. Sprawdź ContentResolver.openAssetFileDescriptor
Hippo Seven
1
Pracował. Wielkie dzięki. Lol, właśnie szukam wewnętrznego pliku URI // UTWÓRZ FOLDER RAW WEWNĄTRZ RES, NASTĘPNIE PLIK NAZWOWY ZAWIERA TYLKO znak a..z0..9, BEZ WIELKICH LITER !!!
phnghue
0

Tak, nie możesz uzyskać dostępu do folderu na dysku z telefonu z Androidem lub emulatora, ponieważ Twój komputer i Android to dwa różne systemy operacyjne. Poszedłbym do folderu res na Androida, ponieważ ma dobre metody zarządzania zasobami. Dopóki nie masz bardzo dobrego powodu, aby umieścić plik w folderze zasobów. Zamiast tego możesz to zrobić

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);
 }
willnotquit
źródło
-7

Pracował dla mnie Wypróbuj ten kod

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