cel*_*vek 25 android android-ndk
我正在尝试构建一个利用NativeActivityNDK设施的Android应用程序.我有以下结构:
/system/vendor/<company>; 我正在使用自定义构建的Android映像,因此使用具有适当权限和所有内容的库是没有问题的NativeActivity依次依赖于上面提到的库安装在/ system/vendor中的库和我的应用程序使用几个配置文件.使用标准C API读取它们没有问题
fopen/fclose.但是那些库和我的应用程序还需要存储一些文件作为其操作的结果,如配置,一些运行时参数,校准数据,日志文件等.随着文件的存储,有一个小问题因为我是不允许写入/system/vendor/...(因为"/ system/..."下的文件系统是以只读方式挂载的,我不想破解它).
那么创建和存储这些文件的最佳方式是什么?哪些是最符合"Android"存储区域的?
我一直在阅读android-ndk谷歌组中的几个主题,在这里提到内部应用程序私有存储或外部SD卡,但由于我没有Android的扩展经验,我不知道是什么将是正确的方法.如果该方法涉及某些特定的Android API,那么C++中的一个小代码示例将非常有用; 我已经看过几个涉及Java和JNI的例子(例如在这个SO问题中),但我现在想远离它.从C++使用本机活动的internalDataPath/externalDataPath配对(一个使它们总是为NULL的错误)似乎也存在问题
.
cel*_*vek 27
对于相对较小的文件(应用程序配置文件,参数文件,日志文件等),最好使用内部应用程序私有存储,即/data/data/<package>/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>
Run Code Online (Sandbox Code Playgroud)
对于内部应用程序,可以使用私有存储fopen/fclose(或C++流等效项,如果可用)API.以下示例说明如何使用Android NDK AssetManager检索和读取配置文件.该文件必须放在assets本机应用程序的项目文件夹内的目录中,以便NDK构建可以将它们打包到APK中.internalDataPath/externalDataPath我在问题中提到的错误是针对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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32961 次 |
| 最近记录: |