Android-仅从本机代码写入/保存文件

Android-仅从本机代码写入/保存文件,android,android-ndk,Android,Android Ndk,我正在尝试构建一个Android应用程序,它利用NDK的NativeActivity功能。 我的结构如下: 安装在/system/vendor/中的一组本机共享库;我在工作 有一个定制的安卓镜像,所以没有任何问题 适当的权限和一切 两个应用程序使用NativeActivity,它们依次依赖于库 上述 安装在/system/vendor和我的应用程序中的库使用了几个 配置文件。使用标准的C API读取它们没有问题 fopen/fclose。但是这些库和我的应用程序还需要存储一些文件 由于它们的

我正在尝试构建一个Android应用程序,它利用NDK的
NativeActivity
功能。 我的结构如下:

  • 安装在
    /system/vendor/
    中的一组本机共享库;我在工作 有一个定制的安卓镜像,所以没有任何问题 适当的权限和一切
  • 两个应用程序使用
    NativeActivity
    ,它们依次依赖于库 上述
安装在/system/vendor和我的应用程序中的库使用了几个 配置文件。使用标准的C API读取它们没有问题
fopen/fclose
。但是这些库和我的应用程序还需要存储一些文件 由于它们的操作,如配置、一些运行时参数、校准 数据、日志文件等。随着文件的存储,出现了一个小问题,因为我不允许写入
/system/vendor/…
(因为“/system/…”下的文件系统是只读安装的,我不想对此进行攻击)

那么,创建和存储这些文件的最佳方式是什么呢 最佳“符合Android”存储区

我已经阅读了安卓ndk谷歌小组的一些帖子,在这里我提到了或者,但是由于我没有安卓的丰富经验,我不确定什么是正确的方法。如果该方法涉及到一些特定的Android API,C++中的小代码示例会非常有用;我已经看到了几个涉及Java和JNI()的示例,但我现在不想讨论这个问题。 同样,从C++中使用本地活动似乎有问题。
internalDataPath/externalDataPath
pair()。

用于相对较小的文件(应用程序配置文件、参数文件、日志文件等) 最好使用内部应用程序专用存储,即
/data/data//files
。 外部存储器(无论是否为SD卡)应用于不需要频繁访问或更新的大型文件

对于外部数据存储,本机应用程序必须在应用程序的
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>  
...
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);
        }
    }
}