Як отримати URI з файлу активу?


127

Я намагався отримати шлях URI для файлу активів.

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

Коли я перевіряю, чи існує файл, я бачу, що файл не існує

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

Чи може хтось мені сказати, як я можу згадати абсолютний шлях до файлу, який існує в папці ресурсу

Відповіді:


160

Не існує "абсолютного шляху до файлу, який існує в папці". Вміст assets/папки вашого проекту упаковано у файл APK. Використовуйте AssetManagerоб'єкт для отримання InputStreamактиву.

Бо WebViewви можете використовувати file Uriсхему приблизно так само, як і URL-адресу. Синтаксис для активів - це file:///android_asset/...(примітка: три косої риски), де еліпсис - це шлях до файлу всередині assets/папки.


32
file://android_asset/..., де ...відносний шлях до assets/каталогу вашого проекту .
CommonsWare

4
Ось зразок проекту, який використовує file://android_asset/, хоча не для Uri: github.com/commonsguy/cw-advandroid/tree/master/WebView/GeoWeb1
CommonsWare

20
@CommonsПерегляньте, схоже, що ви пропустили '/' у своєму URI. Це повинно бути file:///.
ThomasW

7
Я спробував це як new File("file:///android_asset/sounds/beep.mid");, але файл результатів не існує. Будь-які ідеї? Файл PS знаходиться в assets/sounds/папці.
дядько Лем

3
Чи правильно, що ´file: ///android_asset/...´ працює лише в WebView і неможливо отримати InputStream за допомогою URI / URL / Uri поза WebView?
Луббо

74

Правильна URL-адреса:

file:///android_asset/RELATIVEPATH

де RELATIVEPATH - шлях до вашого ресурсу відносно папки активів.

Зверніть увагу на схему 3 / s. Перегляд в Інтернеті не завантажував би жоден з моїх активів без 3-х. Я спробував 2, як (раніше) прокоментував CommonsWare, і це не працюватиме. Тоді я подивився на джерело CommonsWare на github і помітив додатковий переріз вперед.

Це тестування хоч і робилося лише на емуляторі 1.6 Android, але я сумніваюся, що він відрізняється від реального пристрою чи версії.

EDIT: CommonsWare оновив свою відповідь, щоб відобразити цю крихітну зміну. Тому я це відредагував, щоб він все ще мав сенс у його нинішній відповіді.


Більше не працює String fileName = "file:///android_asset/file.csv"; System.out.println(new File(fileName).exists()); // prints false
Elgirhath

@Elgirhath конструктор, Fileякий приймає рядок, очікує шлях, не URI . Я не кодував Android протягом кількох років, і все може змінитися. Я не впевнений, чи можете ви отримати доступ до папки з вбудованими активами, використовуючи звичайний клас файлу Java. Я, мабуть, пам’ятаю, що вам потрібно використовувати AssetManager . Файли в папці активів розміщуються на пристрої в пакеті APK, які доступні лише для читання, і стискаються (APK - це фактично поштові файли), таким чином, більше роботи над його читанням. Спробуйте щось на кшталтnew File(new URI(filename))
Russ

10

Спробуйте спробувати цей код

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

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

8

Нарешті, я знайшов спосіб отримати шлях до файлу, який присутній в активах, з цієї відповіді в Котліні. Тут ми копіюємо файл активів у кеш і отримуємо шлях до цього файлу кешу.

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

Отримайте шлях до файлу, наприклад:

val filePath =  getFileFromAssets(context, "fileName.extension").absolutePath

1
Зауважте, що якщо fileNameмати каталог dir/file. Він зазнає краху з шляху, який cache/dir/fileне існує. Також я думаю, що краще мати перевірку if(!it.exist)всередині alsoблоку, тоді він не буде копіювати файл кожного разу, навіть якщо файл уже є в кеші
Yeung

@ShylendraMadda, @Yeung, if(!it.exist)виникла помилка з невирішеною посиланням. будь-яке рішення?
бінребін

Перевірте, чи існує файл у вашому кеші з цим ім'ям файлу? @binrebin
Shylendra Madda

@ShylendraMadda, я знаю лише ім'я файлу. Чи можемо ми завантажити його зі скриптом, не знаючи фактичної
урі

Думаю, if(!it.exist)слід поставити раніше it.outputStream()...
Yeung

7

введіть тут опис зображення

Будьте впевнені, папка з активами поставлена ​​в правильне положення


Ви можете помістити його куди завгодно і визначити шлях у файлі build.gradle наступним чиномsourceSets { main { assets.srcDirs = ['src/main/assets'] } }
Marcel Bro

2
Як пройти шлях hello.html? додайте, будь ласка,
Рохіт Сінгх

6

Працює для WebView, але, здається, не працює URL.openStream(). Тому вам потрібно розрізнити файли: // протоколи та обробити їх через AssetManager, як було запропоновано.


4

Спробуйте це, воно працює:

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

Якщо ви отримаєте Null Value Exception, спробуйте це (з класом TopBrandData):

InputStream in_s1 =
    TopBrandData.class.getResourceAsStream("/assets/TopBrands.xml");

Якщо не працює, спробуйте це: InputStream in_s1 = TopBrandData.class.getResourceAsStream ("/ активи / TopBrands.xml");
Джаспрет Сінгх

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

1

спробуйте це :

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

Я це зробив, і це спрацювало


2
Насправді це працює. Перевірте ContentResolver.openAssetFileDescriptor
Бегемот 7

1
Працювали. Дуже дякую. Lol, я просто шукаю отримати внутрішній файл URI // СТВОРИТИ СИСТЕМУ СИСТЕМИ ВНУТРІШЕННЯ ВІДТВОРЕННЯ, ТІЛЬКИ ФАЙЛ ІМ'Я ВІДПОВІДАЄТЬСЯ ТОЛЬКО а..з0..9 символів, НЕ ПІДГОТОВКИ !!!
phnghue

0

Так, ви не можете отримати доступ до папки вашого диска з вашого телефону або емулятора Android, оскільки ваш комп'ютер та андроїд - це два різних ОС. До тих пір, поки у вас немає дуже вагомих причин помістити файл у папку активів. Натомість Ви можете це зробити

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

-7

Працювало для мене Спробуйте цей код

   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();
 }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.