Android - writing/saving files from native code only -
i'm trying build android app makes use of nativeactivity facility of ndk. i'm having following structure:
- a bunch of native shared libraries installed in
/system/vendor/<company>; i'm working custom built android image there's no problem having libraries there proper permissions , everything - a couple of applications using
nativeactivitydepend in turn on libraries mentioned above
the libraries installed in /system/vendor , applications use couple of configuration files. there's no problem reading them using standard c api fopen/fclose. libraries , application need store files result of operation, configuration, run-time parameters, calibration data, log files etc. storing of files there slight issue i'm not allowed write /system/vendor/... (as file system under "/system/..." mounted read-only , not want hack on that).
so best way create , store files , best "conforming android" storage area ?
i've been reading couple of threads in android-ndk google group , here on mention either the internal application private storage or the external sd card, not have extended experience android i'm not sure proper approach. if approach involves specific android api small code example in c++ helpful; i've seen couple of examples involving java , jni (e.g. in question) stay away right now. there seems problem using c++ native activity's internaldatapath/externaldatapath pair (a bug makes them null).
for relatively small files(application config files, parameter files, log files etc.) best use internal application private storage, /data/data/<package>/files. external storage if exists @ (being sd card or not) should used large files not need frequent access or updates.
for external data storage native application has "request" correct permissions in application's androidmanifest.xml:
<manifest> ... <uses-permission android:name="android.permission.write_external_storage"> </uses-permission> <uses-permission android:name="android.permission.read_external_storage"> </uses-permission> </manifest> for internal application private storage fopen/fclose(or c++ stream equivalents if available) api used. following example illustrates using android ndk assetmanager retrieve , read configuration file. file must placed assets directory inside native application’s project folder ndk build pack them inside apk. internaldatapath/externaldatapath bug mentioning in question fixed ndk r8 version.
... 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 files/ directory std::string configfile = datapath + "/app_config.xml"; // if first time run app // need create 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 in app's internal data storage."); } else if (enoent == errno) { res = mkdir(datapath.c_str(), 0770); } if (0 == res) { // test see if config file present res = stat(configfile.c_str(), &sb); if (0 == res && sb.st_mode & s_ifreg) { logi("application config file present"); } else { logi("application config file not exist. creating ..."); // read our application config file assets inside apk // save config file contents in application's internal storage logd("reading config file using 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); } } }
Comments
Post a Comment