¿Cómo obtener el URI de un archivo de activos?


127

He estado tratando de obtener la ruta URI para un archivo de activos.

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

Cuando verifico si el archivo existe, veo que ese archivo no existe

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

¿Alguien puede decirme cómo puedo mencionar la ruta absoluta para un archivo existente en la carpeta de activos?

Respuestas:


160

No existe una "ruta absoluta para un archivo existente en la carpeta del activo". El contenido de la assets/carpeta de su proyecto está empaquetado en el archivo APK. Use un AssetManagerobjeto para obtener un InputStreamen un activo.

Para WebView, puede usar el file Uriesquema de la misma manera que usaría una URL. La sintaxis de los activos es file:///android_asset/...(nota: tres barras) donde la elipsis es la ruta del archivo desde la assets/carpeta.


32
file://android_asset/..., donde ...está la ruta relativa dentro del assets/directorio de su proyecto .
CommonsWare

44
Aquí hay un proyecto de muestra que usa file://android_asset/, aunque no para Uri: github.com/commonsguy/cw-advandroid/tree/master/WebView/GeoWeb1
CommonsWare

20
@CommonsWare parece que te perdiste un '/' en tu URI. Debería ser file:///.
ThomasW

77
Intenté esto como new File("file:///android_asset/sounds/beep.mid");, pero el archivo de resultados no existe. ¿Algunas ideas? El archivo PS está en la assets/sounds/carpeta.
tío Lem

3
¿Es correcto que ´file: ///android_asset/...´ funcione solo en WebView y no sea posible obtener InputStream usando URI / URL / Uri fuera de WebView?
Lubbo

74

La url correcta es:

file:///android_asset/RELATIVEPATH

donde RELATIVEPATH es la ruta a su recurso en relación con la carpeta de activos.

Tenga en cuenta los 3 / 's en el esquema. La vista web no cargaría ninguno de mis activos sin el 3. Probé 2 como (anteriormente) comentó CommonsWare y no funcionaría. Luego miré la fuente de CommonsWare en github y noté la barra diagonal adicional.

Sin embargo, esta prueba solo se realizó en el emulador de Android 1.6, pero dudo que sea diferente en un dispositivo real o una versión superior.

EDITAR: CommonsWare actualizó su respuesta para reflejar este pequeño cambio. Así que he editado esto para que todavía tenga sentido con su respuesta actual.


Ya no funciona String fileName = "file:///android_asset/file.csv"; System.out.println(new File(fileName).exists()); // prints false
Elgirhath

@Elgirhath, el constructor Fileque acepta una cadena espera una ruta, no un URI . No he codificado para Android durante unos años y las cosas pueden haber cambiado. No estoy seguro de si puede acceder a la carpeta de activos incrustados utilizando una clase de archivo Java normal. Me parece recordar que tienes que usar un AssetManager . Los archivos en la carpeta de activos se colocan en el dispositivo en el APK incluido de solo lectura y se comprimen (los APK son en realidad archivos zip), por lo tanto, se necesita más trabajo para volver a leerlo. Pruebe algo comonew File(new URI(filename))
Russ

10

Intenta que este código funcione bien

 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

Finalmente, encontré una forma de obtener la ruta de un archivo que está presente en los activos de esta respuesta en Kotlin. Aquí estamos copiando el archivo de activos en la memoria caché y obteniendo la ruta del archivo desde ese archivo de memoria caché.

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

Obtenga la ruta al archivo como:

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

1
Tenga en cuenta que si fileNametiene el directorio dir/file. Se bloqueará con la ruta que cache/dir/fileno existe. También creo que es mejor tener una verificación if(!it.exist)dentro del alsobloque, entonces no copiará el archivo cada vez que incluso el archivo ya esté en el caché
Yeung

@ShylendraMadda, @Yeung, if(!it.exist)arroja un error de referencia sin resolver. alguna solución ?
binrebin

¿Verifica que el archivo existe en su caché con ese nombre de archivo? @binrebin
Shylendra Madda

@ShylendraMadda, solo sé el nombre de archivo. ¿Podemos cargarlo con script sin conocer uri real?
binrebin

Creo que if(!it.exist)debería poner antes it.outputStream()...
Yeung

7

ingrese la descripción de la imagen aquí

Asegúrese de que su carpeta de activos esté en la posición correcta.


Puede colocarlo donde desee y definir la ruta en su archivo build.gradle de la siguiente manerasourceSets { main { assets.srcDirs = ['src/main/assets'] } }
Marcel Bro

2
¿Cómo obtener la ruta de hello.html? por favor agregue
Rohit Singh

6

Funciona para WebView pero parece fallar URL.openStream(). Por lo tanto, debe distinguir los protocolos file: // y manejarlos a través de AssetManager como se sugiere.


4

Prueba esto, funciona:

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

Si obtiene una excepción de valor nulo, intente esto (con clase TopBrandData):

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

Si no funciona, intente con este: 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;
}

1

prueba esto :

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

Lo hice y funcionó


2
En realidad funciona. Compruebe ContentResolver.openAssetFileDescriptor
Hippo Seven el

1
Trabajó. Muchas gracias. Lol, solo estoy buscando obtener el archivo interno de URI // CREAR CARPETA CRUDA DENTRO DE RES, LUEGO EL ARCHIVO DE NOMBRE CONTIENE SOLAMENTE un carácter..z0..9, ¡¡¡SIN MAYÚSCULAS !!!
phnghue

0

Sí, no puedes acceder a la carpeta de tu unidad desde tu teléfono o emulador de Android porque tu computadora y Android son dos sistemas operativos diferentes. Yo elegiría la carpeta de Android porque tiene buenos métodos de administración de recursos. Hasta y a menos que tenga muy buenas razones para colocar su archivo en la carpeta de activos. En cambio, puedes hacer esto

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

Trabajó para mí Prueba este código

   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();
 }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.