Greifen Sie auf Android APK-Asset-Daten direkt in c ++ zu, ohne Asset Manager und Kopieren

Ich verwende reines C ++ in meiner Engine, um eine Game-Engine in Android zu erstellen. Es gibt keine einzelne Java-Datei. Grundsätzlich handelt es sich um ein Spiel, das nur in einem externen Speicher abgelegt werden sollte. Wenn ich meine Asset-Daten manuell über ADB auf meine externe SD-Karte verschiebe, funktioniert das Spiel bereits einwandfrei und stabil.

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

Dies ist keine gute Lösung, da sie nicht geliefert werden kann. Daher habe ich meine Assets-Daten im Assets-Ordner, die während des Erstellungsprozesses in die APK-Datei verschoben werden.

Assets / Data / MoreFolders / Withsubfolders Assets / Data / EngineData.zip Assets / Data / ScriptData.zip

Ich weiß jedoch nicht, wo sich diese Dateien in den Dateisystemen befinden, um in C ++ auf sie zuzugreifen.

Also habe ich versucht, den Pfad zu den Dateiverzeichnissen zu ermitteln. Und wegen eines Fehlers im ursprünglichen Aktivitätsstatus muss ich die Informationen im normalen Code abrufen.

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

c ++ - Code für sein Äquivalent zu android.os.Environment.getFilesDir () und android.os.Environment.getExternalStorageState () ect

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

das funktioniert ganz gut und ergibt

INTERNER PFAD = /data/data/com.fantasyhaze.rememory/files

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

EXTERNAL PATH = /mnt/sdcard/Android/data/com.fantasyhaze.rememory/files

Nachgeschlagener Paketcode path = /mnt/asec/com.fantasyhaze.rememory-2/pkg.apk

Es sind jedoch keine Dateien aus den Assets-Ordnern vorhanden ...

und ich muss auf einen Ordner als normales Arbeitsverzeichnis zugreifen, um die Dateien zu lesen. was wäre möglich in

/mnt/sdcard/Android/data/com.fantasyhaze.rememory/files/Data

Das Verschieben aller Daten aus dem Asset-Ordner (wo auch immer) über den Asset-Manager in diesen Ordner führt jedoch zu einer doppelten Speicherbelegung.

Vermögenswerte> 1 GB bedeuten Vermögenswerte> 2 GB, was keinen Sinn ergibt. Darüber hinaus scheint der Assert-Ordner nicht wiederverwendbar zu sein und nur für kleine Datendateien, was bei Verwendung größerer Pak-Dateien nicht möglich ist. Vielleicht können die Dateien direkt vom Apk aus geöffnet werden, wenn Sie das Entpack-System verwenden und dann meine Ressourcendateien entpacken, aber deshalb muss ich den Apk-Pfad trotzdem angeben.

Also meine Fragen:

Wo ist der Assets-Ordner in der apk auf dem Dateisystem?Wie lautet der Code (c ++) zum Abrufen des apk-Speicherorts oder des Speicherorts der ausführbaren Datei?Kann ich mit einer normalen Methode zum Öffnen von Dateien direkt darauf zugreifen oder nur, wenn ich es entpacke? Wenn ich es ohne Auspacken verwenden kann, wie?Was wäre der Code (c ++), um die Informationen abzurufen, wenn die SD-Karte eingehängt ist?

Ich hoffe jemand kann mir helfen :)

Bearbeiten: Das Cache-Verzeichnis und der Paketverzeichniscode (und seine Ausgabepfade) wurden hinzugefügt, um die Quelle für alle anderen Benutzer bereitzustellen, die sie benötigen.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage