¿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?

Tito
fuente

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.

CommonsWare
fuente
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.

Russ
fuente
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();
Raaz Thakur
fuente
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
Shylendra Madda
fuente
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.

Chuanhang.gu
fuente
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.

Gaylord Zach
fuente
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");
Jaspreet Singh
fuente
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;
}
jayesh kavathiya
fuente
1

prueba esto :

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

Lo hice y funcionó

Nyle
fuente
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);
 }
no renunciará
fuente
-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();
 }
Irfan Ali
fuente