gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 22:14:38 29 4
gpt4 key购买 nike

我正在尝试构建一个使用 NativeActivity 的 Android 应用程序。 NDK的设施。我有以下结构:

  • /system/vendor/<company> 中安装了一堆 native 共享库;我在工作使用自定义构建的 Android 图像,因此库没有问题适当的权限和一切
  • 几个使用 NativeActivity 的应用程序这又取决于库上面提到的

/system/vendor 中安装的库和我的应用程序使用了几个配置文件。使用标准 C API 读取它们没有问题 fopen/fclose .但是那些库和我的应用程序也需要存储一些文件作为它们操作的结果,例如配置、一些运行时参数、校准数据、日志文件等。文件的存储有一个小问题,因为我不允许写入 /system/vendor/... (因为“/system/...”下的文件系统是只读安装的,我不想破解它)。

那么创建和存储这些文件的最佳方式是什么?最好的“符合安卓”的存储区?

我一直在阅读 android-ndk Google 组中的几个线程,并且在这里提到了 the internal application private storagethe external SD card ,但由于我对 Android 没有丰富的经验,我不确定什么是正确的方法。如果该方法涉及某些特定的 Android API,则 C++ 中的小代码示例将非常有帮助;我见过几个涉及 Java 和 JNI (e.g. in this SO question) 的示例,但我现在想远离它。从 C++ 使用 native Activity 似乎也存在问题 internalDataPath/externalDataPath对 (a bug that makes them be always NULL)。

最佳答案

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

对于外部数据存储, native 应用程序必须在应用程序的 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>

用于内部应用私有(private)存储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);
}
}
}

关于Android - 仅从 native 代码写入/保存文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11294487/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com