Android – escribir / guardar archivos de código nativo solamente

Estoy tratando de construir una aplicación para Android que hace uso de la instalación NativeActivity del NDK. Tengo la siguiente estructura:

  • Un montón de bibliotecas compartidas nativas instaladas en /system/vendor/<company> ; Estoy trabajando con una imagen personalizada de Android, por lo que no hay problema con las bibliotecas allí con los permisos adecuados y todo
  • Un par de aplicaciones que utilizan la NativeActivity que dependen a su vez de las bibliotecas mencionadas anteriormente

Las bibliotecas instaladas en / system / vendor y mis aplicaciones utilizan un par de archivos de configuración. No hay problema al leerlos usando la API C estándar fopen/fclose . Pero esas bibliotecas y mi aplicación también necesitan almacenar algunos archivos como resultado de su operación, como la configuración, algunos parámetros de tiempo de ejecución, datos de calibración, archivos de registro, etc. Con el almacenamiento de los archivos hay un pequeño problema, ya que estoy No está permitido escribir en /system/vendor/... (como el sistema de archivos en "/ system / …" está montado de sólo lectura y no quiero hackear eso).

Entonces, ¿cuál sería la mejor manera de crear y almacenar esos archivos y dónde sería el mejor "conformes con Android" área de almacenamiento?

He estado leyendo un par de hilos en el grupo android-ndk de Google y aquí en SO que mencionan el almacenamiento privado de la aplicación interna o la tarjeta SD externa , pero como no tengo experiencia ampliada con Android no estoy seguro de qué Sería el enfoque adecuado. Si el enfoque involucra alguna API específica de Android, un pequeño ejemplo de código en C ++ sería muy útil; He visto un par de ejemplos que implican Java y JNI ( por ejemplo, en esta pregunta SO ), pero me gustaría estar lejos de eso ahora. También parece haber un problema con el uso de C ++ el internalDataPath/externalDataPath la actividad nativa internalDataPath/externalDataPath par ( un error que los hace ser siempre NULL ).

Para archivos relativamente pequeños (archivos de configuración de aplicaciones, archivos de parámetros, archivos de registro, etc.) es mejor utilizar el almacenamiento privado de aplicaciones internas, es decir, /data/data/<package>/files . El almacenamiento externo si existe en absoluto (ya sea tarjeta SD o no) debe utilizarse para archivos grandes que no necesitan acceso frecuente o actualizaciones.

Para el almacenamiento de datos externos, la aplicación nativa tiene que "solicitar" los permisos correctos en AndroidManifest.xml la aplicación:

 <manifest> ... <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"> </uses-permission> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"> </uses-permission> </manifest> 

Para la aplicación interna se podría utilizar el API de almacenamiento privado fopen/fclose (o equivalentes de flujos C ++ si está disponible). El siguiente ejemplo ilustra el uso de Android NDK AssetManager para recuperar y leer un archivo de configuración. El archivo debe colocarse en el directorio de assets dentro de la carpeta del proyecto de la aplicación nativa para que la compilación de NDK pueda empaquetarlos dentro del APK. El error internalDataPath/externalDataPath que estaba mencionando en la pregunta fue corregido para la versión NDK r8.

 ... void android_main(struct android_app* state) { // Make sure glue isn't stripped app_dummy(); ANativeActivity* nativeActivity = state->activity; const char* internalPath = nativeActivity->internalDataPath; std::string dataPath(internalPath); // internalDataPath points directly to the files/ directory std::string configFile = dataPath + "/app_config.xml"; // sometimes if this is the first time we run the app // then we need to create the internal storage "files" directory struct stat sb; int32_t res = stat(dataPath.c_str(), &sb); if (0 == res && sb.st_mode & S_IFDIR) { LOGD("'files/' dir already in app's internal data storage."); } else if (ENOENT == errno) { res = mkdir(dataPath.c_str(), 0770); } if (0 == res) { // test to see if the config file is already present res = stat(configFile.c_str(), &sb); if (0 == res && sb.st_mode & S_IFREG) { LOGI("Application config file already present"); } else { LOGI("Application config file does not exist. Creating it ..."); // read our application config file from the assets inside the apk // save the config file contents in the application's internal storage LOGD("Reading config file using the asset manager.\n"); AAssetManager* assetManager = nativeActivity->assetManager; AAsset* configFileAsset = AAssetManager_open(assetManager, "app_config.xml", AASSET_MODE_BUFFER); const void* configData = AAsset_getBuffer(configFileAsset); const off_t configLen = AAsset_getLength(configFileAsset); FILE* appConfigFile = std::fopen(configFile.c_str(), "w+"); if (NULL == appConfigFile) { LOGE("Could not create app configuration file.\n"); } else { LOGI("App config file created successfully. Writing config data ...\n"); res = std::fwrite(configData, sizeof(char), configLen, appConfigFile); if (configLen != res) { LOGE("Error generating app configuration file.\n"); } } std::fclose(appConfigFile); AAsset_close(configFileAsset); } } } 
  • Los símbolos se quitan cuando se construye código nativo usando Gradle
  • ndk-gdb y ndk-gdb.py Errores
  • ¿Cómo incluir correctamente una biblioteca estática pre-construida en el archivo Android.mk de Android NDK?
  • ¿Cómo compilar la última FFmpeg Library para Android?
  • Añadir archivos .so pre-construidos en el proyecto utilizando Android Gradle plugin 0.7.3
  • Construyendo ICU con NDK
  • Prevenir / dificultar el parche de montaje binario
  • Mapas normales versus coordenadas normales
  • ¿Cómo llamar a una función en el archivo CPP desde el archivo C y viceversa en ANDROID NDK?
  • Android NDK - NativeActivity vs JNI lib
  • GCC: Prueba de herencia simple falla
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.