比較的小さなファイル(アプリケーション設定ファイル、パラメータファイル、ログファイルなど)の場合 は、内部アプリケーションのプライベートストレージ(/data/data/<package>/files
)を使用することをお勧めします。 頻繁なアクセスや更新を必要としない大容量のファイルには、外部記憶装置が存在する場合(SDカードであるかどうかにかかわらず)、外部記憶装置を使用する必要があります。 APIかもしれない(利用可能な場合またはC++ストリーム同等物)
<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
の場合
:外部データストレージ用
は、ネイティブアプリケーションは、アプリケーションのAndroidManifest.xml
中に「要求」適切な権限を持っています中古。次の例は、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);
}
}
}