2012-04-15 12 views
11

Używam czystego C++ w moim silniku, aby stworzyć silnik gry na Androida. Nie ma jednego pliku java. Zasadniczo jest to gra, która powinna być przechowywana tylko w pamięci zewnętrznej. Kiedy ręcznie przesuję dane o zasobach przez adb na moją zewnętrzną kartę SD, gra działa już dobrze i jest stabilna.Uzyskaj dostęp do danych Android APK Asset bezpośrednio w C++ bez Asset Manager i kopiowania

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

To nie jest dobre rozwiązanie, ponieważ nie można go dostarczyć. Dlatego mam majątkowej danych w folderze aktywów, które zostanie przeniesione do pliku apk w trakcie procesu budowlanego o następującej strukturze:

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

Ale nie wiem, gdzie te pliki znajdują się w systemach plików, aby uzyskać do nich dostęp w kodzie C++.

Więc próbowałem uzyskać ścieżkę do katalogów plików. A z powodu błędu w natywnym stanie działania muszę odzyskać informacje w normalnym kodzie.

// 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++ kod dla jego odpowiednik android.os.Environment.getFilesDir() i 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); 

który działa całkiem dobrze, a wyniki w

wewnętrznej ścieżki = /data/data/com.fantasyhaze.rememory/files

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

ZEWNĘTRZNE path = /mnt/sdcard/Android/data/com.fantasyhaze.rememory/files

Spojrzał w górę ścieżka kod pakiet = /mnt/asec/com.fantasyhaze.rememory-2/pkg.apk

Ale nie ma plików z folderów zasobów ...

i potrzebuję uzyskać dostęp do folderu jako normalny katalog roboczy do odczytu plików. co byłoby możliwe w

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

Ale przeniesienie wszystkich danych z folderu aktywów (gdziekolwiek to jest) przez zarządzającego aktywami w tym folderze , powoduje dwukrotne zużycie pamięci.

aktywa> 1 GB oznaczałoby aktywa> 2 GB, co nie ma sensu. Co więcej, wydaje się, że folder assert nie działa w trybie recuratywnym i tylko w przypadku małych plików z danymi , co nie jest możliwe, gdy używane są większe pliki Pak. Być może pliki mogą być dostępne bezpośrednio z apk przy użyciu systemu rozpakowywania, a następnie uzip moje pliki ressource, ale w związku z tym i tak muszę optować na ścieżkę apk.

więc moje pytania:

  1. Gdzie jest folder Aktywa w apk w systemie plików?
  2. Jaki byłby kod (C++) do pobrania lokalizacji apk lub lokalizacji pliku wykonywalnego?
  3. Czy mogę uzyskać do niego bezpośredni dostęp za pomocą normalnej metody otwierania plików lub tylko wtedy, gdy ją rozpakuję. Jeśli mogę go użyć bez rozpakowywania, jak?
  4. Jaki byłby kod (C++), aby pobrać informacje, jeśli karta SD jest zamontowana?

Mam nadzieję, że ktoś może mnie :)

Edit pomóc: Dodane katalogu pamięci podręcznej oraz kod pakiet katalogów (i to ścieżki wyjścia), aby zapewnić źródło dla każdego, kto jej potrzebuje.

+0

Pobieranie zasobów od strony NDK jest trudne i niewiarygodne z powodu błędu w niektórych wersjach natywnej implementacji Androida. Pozwól, że znajdę to nfo i wrócę do ciebie. –

+0

Jeśli nie używasz NativeActivity, możesz użyć tej metody (tylko w celu późniejszego odniesienia), aby znaleźć APK i załadować zasoby. http://androgeek.info/?p=275 –

+0

Witam, próbuję użyć tego kodu w tym pytaniu. Muszę uzyskać ścieżkę "getPackageCodePath" dla pliku .apk i ścieżki do katalogu wewnętrznego. ale ciągle wyrzuca mi błąd, którego nie mogę zadzwonić. ktoś może mi pomóc? z góry dziękuję. w MainActivity Mam: public native int test(); i wczytaj bibliotekę. w kodzie C Wywołuję metodę JNI i tę samą podaną "ścieżkę kodu pakietu" dla błędu .apk: – RKosamia

Odpowiedz

3

Zamieszczam odpowiedź zamiast oznaczać to jako duplikat, ponieważ technicznie, prosisz o więcej szczegółów, niż podano w pytaniu/odpowiedzi, którą tutaj zamieścisz. Aby odpowiedzieć na pierwsze z 4 punktów, zobacz Obtaining the name of an Android APK using C++ and the NativeActivity class.

Jeśli chodzi o sprawdzenie, czy karta SD jest zamontowana, powinno to być raczej proste. Po prostu spróbuj otworzyć katalog lub plik na karcie SD (o której powinieneś wiedzieć), a jeśli się nie uda, wiesz, że karta SD jest niedostępna. Zobacz What's the best way to check if a file exists in C? (cross platform).

+0

Thx za informacje, tak długo go wyszukałem, ale nie mogłem znaleźć tego posta w linku 2! Dzięki tym informacjom w końcu mogłem odzyskać lokalizację apk :) Dodałem kod w pierwszym poście, aby dostarczyć go w innej formie niż ta z linku. Sprawdzanie plików jest w porządku, ale pomyślałem, że może być jakiś sposób sprawdzenia, czy karta SD jest zamontowana w kodzie c podobnym do: 'android.os.Environment.getExternalStorageState(). Equals (android.os.Environment.MEDIA_MOUNTED) ; 'jak widać w [link] (http://stackoverflow.com/questions/902089/how-to-tell-if-the-sdcard-is-mounted-in-android) – odbb

2

Możesz chcieć rzucić okiem na "Pliki rozszerzeń", patrz APK Expansion Files.

Jak na razie rozumiem, to daje system, który automatycznie umieszcza pliki zasobów (plik rozszerzenia) w "udostępnionej lokalizacji przechowywania".

Uważam, że rozwiąże to problem powielonych danych.

Istnieje również krótkie wprowadzenie post on the android-developers blog.

+0

Nie wiedziałem, że istnieje ograniczenie do 50 MB !!! w sprawie rozmiaru pliku APK? To okropne, a te pliki rozszerzeń mogą rozwiązać problem, ale czy jest jeszcze jakieś źródło do korzystania z AStorageManager w C/C++, aby uzyskać dostęp do plików odb? Wydaje się, że dużo pracy wymaga ponownego zaimportowania rzeczy z downloadera w natywnym c: / – odbb

Powiązane problemy