直接在C ++中没有资产管理和复制访问的Android APK资产数据(Access Android

2019-07-29 00:33发布

我使用的是纯C ++在我的引擎打造android的游戏引擎。 没有单一的java文件。 基本上,它是一个应该只被存储到外部存储器中的游戏。 当我手动移动我的资产数据通过ADB我的外置SD卡的游戏作品已经精细,稳定。

adb push ..\..\Bin\Data /sdcard/Android/data/com.fantasyhaze.%SMALL_PACKAGE_NAME%/files/Data/

这不是一个很好的解决方案,因为它无法传递。 因此,我有而它与下面的结构建设过程中转移到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代码()ECT

            // 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);

这工作得很好,并导致

内部路径= /data/data/com.fantasyhaze.rememory/files

CACHE DIR = /data/data/com.fantasyhaze.rememory/cache

外部路径= /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这没有任何意义。 更重要的是断言文件夹似乎不小数据文件中使用更大的小唐文件时,这是不可能recusively,只有工作。 也许文件可使用当解压缩系统,然后uzip我的ressource文件,但因此我无论如何都要optain的APK路径是直接从APK访问。

所以我的问题:

  1. 哪里是在文件系统上的APK资产文件夹?
  2. 什么是代码(C ++)来检索APK位置或可执行文件的位置
  3. 我可以直接与一个正常的文件打开方法或只有当我解压访问它。 如果我可以使用它没有拆包,怎么样?
  4. 如果SD卡安装,会是什么代码(C ++)来获取这些信息?

我希望有一个人可以帮助我 :)

编辑:新增的缓存目录,包目录代码(和它的输出路径),提供其他人谁需要它的来源。

Answer 1:

我张贴标识这是一个重复的,因为从技术上说,你要求比在提问/回答,我要在这里链接提供了更多细节的答案吧。 因此,要回答的第一个你的4分,看到使用C ++和NativeActivity的类获得的Android APK的名称 。

至于检查是否SD卡安装,这应该是相当简单的。 只要尝试打开该目录或在SD卡(你知道应该有),如果失败,你知道SD卡是不可用的文件。 见什么是检查文件是否用C存在的最好方法? (跨平台) 。



Answer 2:

你可能想看看“扩展文件”看APK扩展文件 。

据也是我明白这一点,这给你一个系统,该系统会自动将在“共享存储位置”资源文件(您的扩展文件)。

所以,我认为这将解决您的复制数据的问题。

还有一个简短的介绍对Android的开发者博客文章 。



文章来源: Access Android APK Asset data directly in c++ without Asset Manager and copying