Доступ к данным активов Android APK непосредственно в C++ без Asset Manager и копирования

Я использую чистый C++ в своем движке для создания игрового движка в Android. Нет единого java-файла. По сути, это игра, которую следует хранить только во внешней памяти. Когда я вручную перемещаю данные актива через adb на внешнюю SD-карту, игра уже работает нормально и стабильно.

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

Это не очень хорошее решение, потому что оно не может быть доставлено. Поэтому у меня есть данные о моих активах -в папке «Активы». который перемещается в файл apk в процессе сборки со следующей структурой:

Assets/Data/MoreFolders/Withsubfolders. Активы/данные/EngineData.zip Assets/Data/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);

, который работает довольно хорошо и приводит к

INTERNAL 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

Но перемещение всех данных из папки активов (, где бы они ни находились )через менеджер активов в эта папка, вызывает двойное потребление памяти.

активы >1 ГБ означают активы >2 ГБ, что не имеет смысла. Более того, папка assert, похоже, не работает рекурсивно и только для небольших файлов данных. что невозможно при использовании больших pak-файлов. Возможно, файлы могут быть доступны непосредственно из apk при использовании разархивируйте систему, а затем разархивируйте мои файлы ресурсов, но поэтому я все равно должен выбрать путь apk.

Итак, мои вопросы:

  1. Где находится папка Assets в apk в файловой системе?
  2. Каким должен быть код (c++ )для получения местоположения apk или исполняемого файла
  3. Могу ли я получить к нему доступ напрямую с помощью обычного метода открытия файла или только после его распаковки. Если я могу использовать его без распаковки, то как?
  4. Каким должен быть код (c++ )для получения информации, если SD-карта смонтирована?

Я надеюсь, что кто-нибудь может мне помочь.:)

Редактировать:Добавлен каталог кеша и код каталога пакета (и его выходные пути ), чтобы предоставить исходный код всем, кому он нужен.

11
задан 16 April 2012 в 09:50
поделиться