2011-12-12 17 views
49

Necesito saber el camino cadena a un archivo en la carpeta de activos, porque estoy usando una API de mapa que necesita recibir una ruta de cadena, y mis mapas se deben almacenar en la carpeta de activos¿Cómo obtener la cadena de ruta de acceso de Android a un archivo en la carpeta Activos?

Ésta es la código que estoy tratando:

MapView mapView = new MapView(this); 
    mapView.setClickable(true); 
    mapView.setBuiltInZoomControls(true); 
    mapView.setMapFile("file:///android_asset/m1.map"); 
    setContentView(mapView); 

Algo va mal con "file:///android_asset/m1.map" porque el mapa no está siendo cargado.

¿Cuál es el archivo de ruta de cadena correcto para el archivo m1.map almacenado en mi carpeta de activos?

Gracias

EDITAR para Dumitru: Este código no funciona, se produce un error en is.read(buffer); con IOException

 try { 
      InputStream is = getAssets().open("m1.map"); 
      int size = is.available(); 
      byte[] buffer = new byte[size]; 
      is.read(buffer); 
      is.close(); 
      text = new String(buffer); 
     } catch (IOException e) {throw new RuntimeException(e);} 

Respuesta

74

AFAIK los archivos en el directorio de activos no se descomprimen. En cambio, se leen directamente desde el archivo APK (ZIP).

Por lo tanto, no puede hacer cosas que esperen que un archivo acepte un "archivo" de activos.

su lugar, usted tiene que extraer el activo y escribirla en un archivo separado, como sugiere Dumitru:

File f = new File(getCacheDir()+"/m1.map"); 
    if (!f.exists()) try { 

    InputStream is = getAssets().open("m1.map"); 
    int size = is.available(); 
    byte[] buffer = new byte[size]; 
    is.read(buffer); 
    is.close(); 


    FileOutputStream fos = new FileOutputStream(f); 
    fos.write(buffer); 
    fos.close(); 
    } catch (Exception e) { throw new RuntimeException(e); } 

    mapView.setMapFile(f.getPath()); 
+2

obtengo la excepción: java.io.FileNotFoundException: m1.map – NullPointerException

+0

la excepción está en la línea InputStream is = getAssets() .open ("m1.map"); – NullPointerException

+1

bien, resuelto, pero ahora tengo la misma excepción que con la respuesta Dumitru, 12-12 15: 06: 41.452: DEPURACIÓN/activo (3760): los datos exceden UNCOMPRESS_DATA_MAX (3491923 vs 1048576) – NullPointerException

8

Eche un vistazo a la ReadAsset.java a partir de muestras de API que vienen con el SDK.

 try { 
     InputStream is = getAssets().open("read_asset.txt"); 

     // We guarantee that the available method returns the total 
     // size of the asset... of course, this does mean that a single 
     // asset can't be more than 2 gigs. 
     int size = is.available(); 

     // Read the entire asset into a local byte buffer. 
     byte[] buffer = new byte[size]; 
     is.read(buffer); 
     is.close(); 

     // Convert the buffer into a string. 
     String text = new String(buffer); 

     // Finally stick the string into the text view. 
     TextView tv = (TextView)findViewById(R.id.text); 
     tv.setText(text); 
    } catch (IOException e) { 
     // Should never happen! 
     throw new RuntimeException(e); 
    } 
+0

No funciona para mí, la línea es.read (buffer); me da IOException – NullPointerException

+0

He editado mi pregunta con el nuevo código, verifíquelo – NullPointerException

+0

¿Qué excepción exactamente arroja? –

5

Puede utilizar este método.

public static File getRobotCacheFile(Context context) throws IOException { 
     File cacheFile = new File(context.getCacheDir(), "robot.png"); 
     try { 
      InputStream inputStream = context.getAssets().open("robot.png"); 
      try { 
       FileOutputStream outputStream = new FileOutputStream(cacheFile); 
       try { 
        byte[] buf = new byte[1024]; 
        int len; 
        while ((len = inputStream.read(buf)) > 0) { 
         outputStream.write(buf, 0, len); 
        } 
       } finally { 
        outputStream.close(); 
       } 
      } finally { 
       inputStream.close(); 
      } 
     } catch (IOException e) { 
      throw new IOException("Could not open robot png", e); 
     } 
     return cacheFile; 
    } 

Debe nunca utilice InputStream.available() en tales casos. Devuelve solo los bytes que están almacenados en el búfer. El método con .available() nunca funcionará con archivos más grandes y no funcionará en algunos dispositivos.

1

Solo para agregar la solución perfecta de Jacek. Si intentas hacer esto en Kotlin, no funcionará de inmediato. En su lugar, querrá usar esto:

@Throws(IOException::class) 
fun getSplashVideo(context: Context): File { 
    val cacheFile = File(context.cacheDir, "splash_video") 
    try { 
     val inputStream = context.assets.open("splash_video") 
     val outputStream = FileOutputStream(cacheFile) 
     try { 
      inputStream.copyTo(outputStream) 
     } finally { 
      inputStream.close() 
      outputStream.close() 
     } 
    } catch (e: IOException) { 
     throw IOException("Could not open splash_video", e) 
    } 
    return cacheFile 
} 
Cuestiones relacionadas