Как получить 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
@CommonsWare похоже, что вы пропустили '/' в своем 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 / на схеме. Веб-представление не загрузило бы ни один из моих ресурсов без 3. Я попробовал 2, как (ранее) прокомментировал CommonsWare, и это не сработало. Затем я посмотрел на исходный код CommonsWare на github и заметил лишнюю косую черту.

Это тестирование проводилось только на эмуляторе Android 1.6, но я сомневаюсь, что на реальном устройстве или более поздней версии оно будет отличаться.

РЕДАКТИРОВАТЬ: CommonsWare обновил свой ответ, чтобы отразить это крошечное изменение. Итак, я отредактировал это, так что он все еще имеет смысл с его текущим ответом.


String fileName = "file:///android_asset/file.csv"; System.out.println(new File(fileName).exists()); // prints false
Больше

@Elgirhath конструктор File, принимающий строку, ожидает путь, а не URI . Я не программировал для Android несколько лет, и все могло измениться. Я не уверен, что вы можете получить доступ к папке встроенных ресурсов с помощью обычного класса Java File. Кажется, я помню, что вам нужно использовать AssetManager . Файлы в папке с ресурсами размещаются на устройстве в пакете APK, доступном только для чтения, и сжимаются (APK на самом деле представляют собой zip-файлы), поэтому требуется больше работы, чтобы прочитать их обратно. Попробуйте что-нибудь вроде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

Наконец, я нашел способ получить путь к файлу, который присутствует в активах, из этого ответа в Kotlin. Здесь мы копируем файл ресурсов в кеш и получаем путь к файлу из этого файла кеша.

@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блока, то он не будет копировать файл каждый раз , даже файл уже находится на кэш
Енг

@ShylendraMadda, @Yeung, if(!it.exist)показывает ссылку на неразрешенную ошибку. любое решение?
бинребин

Проверить, существует ли в вашем кеше файл с таким именем? @binrebin
Шилендра Мадда

@ShylendraMadda, я знаю только имя файла. Можем ли мы загрузить его скриптом, не зная фактического uri
binrebin

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

7

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

Убедитесь, что ваша папка с активами находится в правильном положении.


Вы можете поместить его где хотите и определить путь в вашем файле build.gradle следующим образомsourceSets { main { assets.srcDirs = ['src/main/assets'] } }
Марсель Бро

2
Как получить путь к hello.html? пожалуйста, добавьте
Рохит Сингх

6

Работает для WebView, но, похоже, не работает URL.openStream(). Поэтому вам нужно различать протоколы file: // и обрабатывать их через AssetManager, как предлагается.


4

Попробуйте, это работает:

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

Если вы получили исключение нулевого значения, попробуйте это (с классом TopBrandData):

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

Если не работает, попробуйте это: InputStream in_s1 = TopBrandData.class.getResourceAsStream ("/ assets / TopBrands.xml");
Jaspreet Singh 02

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
Hippo Seven,

1
Работал. Большое спасибо. Lol, я просто ищу получить внутренний файл URI // СОЗДАТЬ RAW-ПАПКУ ВНУТРИ RES, ТОГДА ИМЯ ФАЙЛА СОДЕРЖИТ ТОЛЬКО символ..z0..9, БЕЗ ЗАПИСИ !!!
phnghue

0

Да, вы не можете получить доступ к папке диска с вашего телефона Android или эмулятора, потому что ваш компьютер и Android - это две разные ОС. Я бы выбрал папку res для 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.