首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android -只从本机代码中写入/保存文件

Android -只从本机代码中写入/保存文件
EN

Stack Overflow用户
提问于 2012-07-02 13:16:27
回答 1查看 38.6K关注 0票数 28

我正在尝试构建一个安卓应用程序,它利用了NDK的NativeActivity工具。我的结构如下:

  • 安装在/system/vendor/<company>中的一堆本地共享库;我正在使用自定义构建的Android映像,因此拥有适当权限的库和所有东西都没有问题
  • 几个使用NativeActivity的应用程序,它们依赖于上面提到的库

安装在/system/供应商和我的应用程序中的库使用几个配置文件。使用标准的C fopen/fclose阅读它们是没有问题的。但是这些库和我的应用程序也需要存储一些文件,比如配置、一些运行时参数、校准数据、日志文件等等。在存储这些文件时,有一个小问题,因为我不允许写入/system/vendor/... (作为“/ system /.”下的文件系统)。是只读挂载的,我不想黑)。

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

我在Android组中读了几条帖子,这里提到了the internal application private storagethe external SD card,但是由于我没有扩展安卓的经验,所以我不确定什么是合适的方法。如果这种方法涉及到一些特定的Android,那么C++中的一个小代码示例将非常有用;我已经看到了一些涉及Java (e.g. in this SO question)的例子,但我现在想不谈这个问题。此外,使用来自C++的本机活动的internalDataPath/externalDataPath对(a bug that makes them be always NULL)似乎也有问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-18 08:49:30

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

对于外部数据存储,本机应用程序必须在应用程序的AndroidManifest.xml中“请求”正确的权限

代码语言:javascript
运行
复制
<manifest>
    ... 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
    </uses-permission>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"> 
    </uses-permission>
</manifest>  

对于内部应用程序,可以使用私有存储fopen/fclose(如果可用的话也可以使用C++流等效项) API。下面的示例说明如何使用Android AssetManager检索和读取配置文件。该文件必须放在本机应用程序的项目文件夹内的assets目录中,以便NDK构建可以将它们打包到APK中。我在问题中提到的internalDataPath/externalDataPath错误是为NDK r8版本修正的。

代码语言:javascript
运行
复制
...
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);
        }
    }
}
票数 30
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11294487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档