我在我的引擎中使用纯C ++在android中创建游戏引擎。没有单个java文件。基本上它是一个只应存储到外部存储器的游戏。当我通过adb手动将资产数据移动到我的外部SD卡时,游戏运行良好且稳定。
adb push ..\..\Bin\Data /sdcard/Android/data/com.fantasyhaze.%SMALL_PACKAGE_NAME%/files/Data/
这不是一个好的解决方案,因为它无法交付。因此,我在Assets文件夹中有我的资产数据 在构建过程中使用以下结构移动到apk文件中:
资产/数据/ MoreFolders / Withsubfolders 资产/数据/ EngineData.zip 资产/数据/ ScriptData.zip
但我不知道这些文件在文件系统上的位置,以便用c ++代码访问它们。
所以我试图获取文件目录的路径。并且由于本机活动状态中的错误 我必须以正常代码检索信息。
// bug in 2.3 internalDataPath / externalDataPath = null using jni code instead
//FHZ_PRINTF("INTERNAL inter PATH = %s\n", state->activity->internalDataPath);
//FHZ_PRINTF("EXTERNAL inter PATH = %s\n", state->activity->externalDataPath);
c ++代码,相当于android.os.Environment.getFilesDir() 和android.os.Environment.getExternalStorageState()等
// getPath() - java
JNIEnv *jni_env = Core::HAZEOS::GetJNIEnv();
jclass cls_Env = jni_env->FindClass("android/app/NativeActivity");
jmethodID mid_getExtStorage = jni_env->GetMethodID(cls_Env, "getFilesDir","()Ljava/io/File;");
jobject obj_File = jni_env->CallObjectMethod( gstate->activity->clazz, mid_getExtStorage);
jclass cls_File = jni_env->FindClass("java/io/File");
jmethodID mid_getPath = jni_env->GetMethodID(cls_File, "getPath","()Ljava/lang/String;");
jstring obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath);
const char* path = jni_env->GetStringUTFChars(obj_Path, NULL);
FHZ_PRINTF("INTERNAL PATH = %s\n", path);
jni_env->ReleaseStringUTFChars(obj_Path, path);
// getCacheDir() - java
mid_getExtStorage = jni_env->GetMethodID( cls_Env,"getCacheDir", "()Ljava/io/File;");
obj_File = jni_env->CallObjectMethod(gstate->activity->clazz, mid_getExtStorage, NULL);
cls_File = jni_env->FindClass("java/io/File");
mid_getPath = jni_env->GetMethodID(cls_File, "getAbsolutePath", "()Ljava/lang/String;");
obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath);
path = jni_env->GetStringUTFChars(obj_Path, NULL);
FHZ_PRINTF("CACHE DIR = %s\n", path);
jni_env->ReleaseStringUTFChars(obj_Path, path);
// getExternalFilesDir() - java
mid_getExtStorage = jni_env->GetMethodID( cls_Env,"getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;");
obj_File = jni_env->CallObjectMethod(gstate->activity->clazz, mid_getExtStorage, NULL);
cls_File = jni_env->FindClass("java/io/File");
mid_getPath = jni_env->GetMethodID(cls_File, "getPath", "()Ljava/lang/String;");
obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath);
path = jni_env->GetStringUTFChars(obj_Path, NULL);
FHZ_PRINTF("EXTERNAL PATH = %s\n", path);
jni_env->ReleaseStringUTFChars(obj_Path, path);
//getPackageCodePath() - java
mid_getPath = jni_env->GetMethodID(cls_Env, "getPackageCodePath", "()Ljava/lang/String;");
obj_File = jni_env->CallObjectMethod(gstate->activity->clazz, mid_getPath);
obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath);
path = jni_env->GetStringUTFChars(obj_Path, NULL);
FHZ_PRINTF("Looked up package code path = %s\n", path);
效果很好并导致
INTERNAL PATH = /data/data/com.fantasyhaze.rememory/files
CACHE DIR = /data/data/com.fantasyhaze.rememory/cache
EXTERNAL PATH = /mnt/sdcard/Android/data/com.fantasyhaze.rememory/files
查找包代码路径= /mnt/asec/com.fantasyhaze.rememory-2/pkg.apk
但资产文件夹中没有文件...
我需要访问一个文件夹作为正常工作目录来读取文件。
中可行的/mnt/sdcard/Android/data/com.fantasyhaze.rememory/files/Data
但是,通过资产管理器将资产文件夹(无论它在何处)的所有数据移动到此文件夹,会导致内存消耗增加一倍。
资产> 1GB意味着资产> 2GB,这是没有意义的。不仅如此,assert文件夹似乎不能反复使用,仅适用于小型数据文件 这在使用更大的pak文件时是不可能的。也许这些文件可以在使用时直接从apk访问 解压缩系统,然后解压缩我的资源文件,但因此我必须选择apk路径。
所以我的问题:
我希望有人可以帮助我:)。
编辑:添加了缓存目录和软件包目录代码(以及它的输出路径),为其他需要它的人提供源代码。
答案 0 :(得分:2)
我发布了一个答案,而不是将其标记为重复,因为从技术上讲,您要求提供的详细信息比我在此处链接的问题/答案中提供的更多。因此,要回答您的4个积分中的第一个,请参阅Obtaining the name of an Android APK using C++ and the NativeActivity class。
至于检查SD卡是否已安装,应该相当简单。只需尝试打开SD卡上的目录或文件(您知道应该在那里),如果失败,您就知道SD卡不可用。请参阅What's the best way to check if a file exists in C? (cross platform)。
答案 1 :(得分:2)
您可能需要查看“扩展文件”,请参阅APK Expansion Files。
据我所知,这为您提供了一个自动将资源文件(您的扩展文件)放在“共享存储位置”的系统。
所以我认为这可以解决重复数据的问题。
还有一个简短的介绍post on the android-developers blog。