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

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

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

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

Активы/Data/MoreFolders/Withsubfolders Активы /Data/EngineData.zip Активы/Data/ScriptData.zip

Но я не знаю, где эти файлы находятся в файловых системах для доступа к ним в коде С++.

Итак, я попытался получить путь к файловым каталогам. И из-за ошибки в состоянии родной активности Я должен получить информацию в нормальном коде.

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

С++ код для его эквивалента 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​​p >

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

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

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

  • Где находится папка "Активы" в apk в файловой системе?
  • Каким будет код (С++) для извлечения местоположения apk или местоположения исполняемого файла
  • Можно ли получить доступ к нему напрямую с помощью обычного метода открытия файла или только при его распаковке. Если я могу использовать его без распаковки, как?
  • Каким будет код (С++) для извлечения информации, если установлена ​​SD-карта?

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

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

Ответ 1

Я отправляю ответ вместо того, чтобы отмечать это как дубликат, потому что технически вы запрашиваете больше информации, чем указано в вопросе/ответе, который я собираюсь связать здесь. Итак, чтобы ответить на первый из ваших 4 баллов, см. Получение имени Android APK с использованием С++ и класса NativeActivity.

Что касается проверки того, установлена ​​ли SD-карта, это должно быть довольно просто. Просто попробуйте открыть каталог или файл на SD-карте (который, как вы знаете, должен быть там), и если он не работает, вы знаете, что SD-карта недоступна. См. Каков наилучший способ проверить, существует ли файл в C? (кросс-платформа).

Ответ 2

Вы можете посмотреть "Файлы расширения", см. Файлы расширения APK.

Насколько я понимаю, это дает вам систему, которая автоматически помещает файлы ресурсов (ваш файл расширения) в "общую папку хранения".

Итак, я думаю, что это решит вашу проблему дублированных данных.

В блоге разработчиков Android также есть короткое сообщение .