web-dev-qa-db-fra.com

Comment obtenir la chaîne de cheminement Android) vers un fichier sur le dossier Assets?

J'ai besoin de connaître le chemin de la chaîne vers un fichier sur le dossier des actifs, car j'utilise une API de carte qui doit recevoir un chemin de chaîne et mes cartes doivent être stockées dans le dossier des actifs.

C'est le code que j'essaye:

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

Quelque chose ne va pas avec "file:///Android_asset/m1.map" Car la carte n'est pas en cours de chargement.

Quel est le fichier de chemin de chaîne correct vers le fichier m1.map stocké dans mon dossier de ressources?

Merci

EDIT pour Dimitru: Ce code ne fonctionne pas, il échoue sur is.read(buffer); avec 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);}
59

Autant que je sache, les fichiers du répertoire des actifs ne sont pas décompressés. Au lieu de cela, ils sont lus directement à partir du fichier APK (Zip).

Donc, vous ne pouvez vraiment pas créer de choses qui attendent un fichier accepter un 'fichier' de ressource.

Au lieu de cela, vous devrez extraire l'actif et l'écrire dans un fichier séparé, comme le suggère 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());
89
Jacob Nordfalk

Consultez le ReadAsset.Java à partir des exemples d’API fournis avec le 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);
    }
9
Dumitru Hristov

Vous pouvez utiliser cette méthode.

    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;
    }

Vous devriez ne jamais utiliser InputStream.available () dans de tels cas. Il ne renvoie que les octets mis en mémoire tampon. La méthode avec .available () ne fonctionnera jamais avec des fichiers plus volumineux et ne fonctionnera pas du tout sur certains périphériques.

En 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) } }
    }
9
Jacek Marchwicki

Juste pour ajouter la solution parfaite de Jacek. Si vous essayez de faire cela à Kotlin, cela ne fonctionnera pas immédiatement. Au lieu de cela, vous voudrez utiliser ceci:

@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
}
3
CheesusCrust