x86_64 unity r16b r13 ndk google 11c android android-ndk openscenegraph

unity - Cómo obtener archivos en activos de Android NDK



ndk unity (2)

Estoy intentando acceder a un archivo de imagen en la carpeta de activos desde el lado nativo. Ahora puedo buscar con éxito a través de la carpeta de activos y sus subdirectorios ubicando el archivo particular que estoy buscando:

AAssetDir* assetDir = AAssetManager_openDir(asset_manager, "images"); const char* filename; while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) { __android_log_print(ANDROID_LOG_DEBUG, "Debug", filename); } AAssetDir_close(assetDir);

También estoy usando OSG. Establecí la imagen como una textura en mi sombreador con el siguiente código:

texture->setImage(osgDB::readImageFile(fileNameWithPath));

Pero ese nombre de archivo debe incluir la ruta absoluta también, ya que no se encuentra en el mismo directorio. Sin embargo, descubrí que no puedo obtener la ruta absoluta para el directorio de activos, ya que está comprimido junto con el APK.

Siendo que no puedo acceder al camino absoluto, ¿qué otra forma podría usar para obtener la imagen? También para tener en cuenta, quiero mantener los archivos en la carpeta de activos como apuntar a la tarjeta SD.


Puede leer la imagen del activo con AAssetManager_open y AAsset_read , pero como el activo se encuentra en la aplicación, no puede obtener un nombre de ruta de archivo, también está comprimido allí. Puede guardar los datos en un archivo y leerlos posteriormente o puede procesar directamente el fragmento que obtuvo de su archivo de activos si OSG lo permite.

Desde here :

AAssetDir* assetDir = AAssetManager_openDir(mgr, ""); const char* filename = (const char*)NULL; while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) { AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING); char buf[BUFSIZ]; int nb_read = 0; FILE* out = fopen(filename, "w"); while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0) fwrite(buf, nb_read, 1, out); fclose(out); AAsset_close(asset); } AAssetDir_close(assetDir);


Una cosa más que vale la pena mencionar es que Android pone restricciones en el tamaño de los activos que se pueden leer en el momento, a 1Mb. En caso de que su archivo sea más grande, debe dividirlo en fragmentos. Aquí está mi solución de trabajo que carga el archivo en trozos al vector de caracteres:

AAssetManager * mgr = app->activity->assetManager; AAssetDir* assetDir = AAssetManager_openDir(mgr, ""); const char* filename; std::vector<char> buffer; while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) { //search for desired file if(!strcmp(filename, /* searched file name */)) { AAsset *asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING); //holds size of searched file off64_t length = AAsset_getLength64(asset); //keeps track of remaining bytes to read off64_t remaining = AAsset_getRemainingLength64(asset); size_t Mb = 1000 *1024; // 1Mb is maximum chunk size for compressed assets size_t currChunk; buffer.reserve(length); //while we have still some data to read while (remaining != 0) { //set proper size for our next chunk if(remaining >= Mb) { currChunk = Mb; } else { currChunk = remaining; } char chunk[currChunk]; //read data chunk if(AAsset_read(asset, chunk, currChunk) > 0) // returns less than 0 on error { //and append it to our vector buffer.insert(buffer.end(),chunk, chunk + currChunk); remaining = AAsset_getRemainingLength64(asset); } } AAsset_close(asset); } }