How to get the android Path string to a file on Assets folder?
I need to know the string path to a file on assets folder, because I'm using a map API that needs to receive a string path, and my maps must be stored on assets folder
This is the code i'm trying:
MapView mapView = new MapView(this);
mapView.setClickable(true);
mapView.setBuiltInZoomControls(true);
mapView.setMapFile("file:///android_asset/m1.map");
setContentView(mapView);
Something is going wrong with "file:///android_asset/m1.map"
because the map is not being loaded.
Which is the correct string path file to the file m1.map stored on my assets folder?
Thanks
EDIT for Dimitru: This code doesn't works, it fails on is.read(buffer);
with 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);}
AFAIK the files in the assets directory don't get unpacked. Instead, they are read directly from the APK (ZIP) file.
So, you really can't make stuff that expects a file accept an asset 'file'.
Instead, you'll have to extract the asset and write it to a seperate file, like Dumitru suggests:
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());
You can use this method.
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;
}
You should never use InputStream.available() in such cases. It returns only bytes that are buffered. Method with .available() will never work with bigger files and will not work on some devices at all.
In Kotlin (;D):
@Throws(IOException::class)
fun getRobotCacheFile(context: Context): File = File(context.cacheDir, "robot.png")
.also {
it.outputStream().use { cache -> context.assets.open("robot.png").use { it.copyTo(cache) } }
}