Acceda a los datos de activos APK de Android directamente en c ++ sin Asset Manager y copiando

Estoy usando puro C + + en mi motor para crear un motor de juego en android. No hay ningún archivo java único. Básicamente es un juego que sólo debe almacenarse en la memoria externa. Cuando muevo mis datos de activos manualmente a través de adb a mi tarjeta sd externa, el juego ya funciona bien y es estable.

adb push ..\..\Bin\Data /sdcard/Android/data/com.fantasyhaze.%SMALL_PACKAGE_NAME%/files/Data/ 

Esta no es una buena solución porque no puede ser entregada. Por lo tanto, tengo mis datos de activos en la carpeta de activos que se mueve en el archivo apk durante el proceso de construcción con la siguiente estructura:

Activos / Datos / Más Carpetas / Carpeta de Comandos Activos / Datos / Datos de EngineData.zip / Datos / ScriptData.zip

Pero no sé dónde están esos archivos en los sistemas de archivos para acceder a ellos en código c ++.

Así que traté de obtener la ruta a los directorios de archivos. Y debido a un error en el estado de actividad nativa debo recuperar la información en código normal.

 // bug in 2.3 internalDataPath / externalDataPath = null using jni code instead //FHZ_PRINTF("INTERNAL inter PATH = %s\n", state->activity->internalDataPath); //FHZ_PRINTF("EXTERNAL inter PATH = %s\n", state->activity->externalDataPath); 

C + + código para su equivalente a android.os.Environment.getFilesDir () y android.os.Environment.getExternalStorageState () ect

  // getPath() - java JNIEnv *jni_env = Core::HAZEOS::GetJNIEnv(); jclass cls_Env = jni_env->FindClass("android/app/NativeActivity"); jmethodID mid_getExtStorage = jni_env->GetMethodID(cls_Env, "getFilesDir","()Ljava/io/File;"); jobject obj_File = jni_env->CallObjectMethod( gstate->activity->clazz, mid_getExtStorage); jclass cls_File = jni_env->FindClass("java/io/File"); jmethodID mid_getPath = jni_env->GetMethodID(cls_File, "getPath","()Ljava/lang/String;"); jstring obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath); const char* path = jni_env->GetStringUTFChars(obj_Path, NULL); FHZ_PRINTF("INTERNAL PATH = %s\n", path); jni_env->ReleaseStringUTFChars(obj_Path, path); // getCacheDir() - java mid_getExtStorage = jni_env->GetMethodID( cls_Env,"getCacheDir", "()Ljava/io/File;"); obj_File = jni_env->CallObjectMethod(gstate->activity->clazz, mid_getExtStorage, NULL); cls_File = jni_env->FindClass("java/io/File"); mid_getPath = jni_env->GetMethodID(cls_File, "getAbsolutePath", "()Ljava/lang/String;"); obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath); path = jni_env->GetStringUTFChars(obj_Path, NULL); FHZ_PRINTF("CACHE DIR = %s\n", path); jni_env->ReleaseStringUTFChars(obj_Path, path); // getExternalFilesDir() - java mid_getExtStorage = jni_env->GetMethodID( cls_Env,"getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;"); obj_File = jni_env->CallObjectMethod(gstate->activity->clazz, mid_getExtStorage, NULL); cls_File = jni_env->FindClass("java/io/File"); mid_getPath = jni_env->GetMethodID(cls_File, "getPath", "()Ljava/lang/String;"); obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath); path = jni_env->GetStringUTFChars(obj_Path, NULL); FHZ_PRINTF("EXTERNAL PATH = %s\n", path); jni_env->ReleaseStringUTFChars(obj_Path, path); //getPackageCodePath() - java mid_getPath = jni_env->GetMethodID(cls_Env, "getPackageCodePath", "()Ljava/lang/String;"); obj_File = jni_env->CallObjectMethod(gstate->activity->clazz, mid_getPath); obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath); path = jni_env->GetStringUTFChars(obj_Path, NULL); FHZ_PRINTF("Looked up package code path = %s\n", path); 

Que funciona bastante bien y da como resultado

CAMINO INTERNO = /data/data/com.fantasyhaze.rememory/files

CACHE DIR = /data/data/com.fantasyhaze.rememory/cache

CAMINO EXTERNO = /mnt/sdcard/Android/data/com.fantasyhaze.rememory/files

Consultado código de paquete path = /mnt/asec/com.fantasyhaze.rememory-2/pkg.apk

Pero no hay archivos de las carpetas de activos …

Y tengo que acceder a una carpeta como directorio de trabajo normal para leer los archivos. Que sería posible en

/mnt/sdcard/Android/data/com.fantasyhaze.rememory/files/Data

Pero mover todos los datos de la carpeta de activos (dondequiera que esté) a través del gestor de activos a esta carpeta, provoca un consumo duplicado de memoria.

Activos> 1GB significaría activos> 2GB que no tiene sentido. Más que eso, la carpeta assert parece no funcionar recusivamente y sólo para archivos de datos pequeños que no es posible cuando se utilizan archivos pak más grandes. Tal vez los archivos se puede acceder directamente desde el apk cuando se utiliza el sistema descomprimir y luego uzip mis archivos de recursos, pero por lo tanto tengo que optain la ruta de APK de todos modos.

Así que mis preguntas:

  1. ¿Dónde está la carpeta de activos en el apk en el sistema de archivos?
  2. ¿Cuál sería el código (c ++) para recuperar la ubicación apk o la ubicación del archivo ejecutable
  3. ¿Puedo acceder a él directamente con un método abierto de archivo normal o sólo si lo descomprime. Si puedo usarlo sin desembalar, ¿cómo?
  4. ¿Cuál sería el código (c ++) para recuperar la información si la tarjeta sd está montada?

Espero que alguien pueda ayudarme 🙂

Editar: Añadido directorio de caché y el código del directorio de paquetes (y sus rutas de salida), para proporcionar la fuente para todos los demás que lo necesitan.

    Estoy publicando una respuesta en lugar de marcar esto como un duplicado, porque técnicamente, usted está pidiendo más detalles que se proporcionan en la pregunta / respuesta que voy a vincular aquí. Por lo tanto, para responder al primero de sus 4 puntos, consulte Obtención del nombre de un APK de Android con C ++ y la clase NativeActivity .

    En cuanto a la comprobación para ver si la tarjeta SD está montado, que debería ser más bien simple. Simplemente intente abrir el directorio o un archivo en la tarjeta SD (que usted sabe que debe estar allí) y si falla, usted sabe que la tarjeta SD no está disponible. Consulte ¿Cuál es la mejor manera de comprobar si existe un archivo en C? (Plataforma cruzada) .

    Puede que desee ver los "Archivos de expansión", consulte Archivos de expansión APK .

    Por lo que se entiende esto, esto le da un sistema que pone automáticamente los archivos de recursos (su archivo de expansión) en la "ubicación de almacenamiento compartido".

    Así que creo que esto resolvería su problema de datos duplicados.

    También hay un breve post de introducción en el blog de desarrolladores de Android .

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.