2013-08-08 12 views
5

Używam OBB do przechowywania moich danych i muszę korzystać z Android NDK, aby uzyskać dostęp do danych. Jednak nie mogę zamontować pliku obb w celu pobrania danych. Nazwę moje obb po schemacie zgodnie z APK Expansion Files documentation.Problemy z odczytem zawartości pliku OBB za pomocą Androida NDK

np main.1.com.example.native_activity.obb

I następnie umieścić go w folderze /data/Android/obb/com.example.native_activity sugerowane przez doc internetowym powyżej.

Jednakże, używając następującego kodu, nie mogę dokonać montażu ÖBB:

AStorageManager* man = AStorageManager_new(); 
char* data = malloc(256); 
AStorageManager_mountObb(man, "main.1.com.example.native_activity.obb", "somekey", my_obbCallbackFunc, data); 
char* obbPath = AStorageManager_getMountedObbPath(man, "main.1.com.example.native_activity.obb"); 

LOGI("mounted path: %s", obbPath); 
free(data); 
data = NULL; 
AStorageManager_delete(man); 
man = NULL; 

obbPath okazał się być zawsze pusty. Nie wiem, jak uzyskać właściwy klucz, więc była to tylko randomizacja.

UPDATE:

poprawiłem dwa problemy z mojej strony.

Po pierwsze, plik obb nie został utworzony za pomocą narzędzia Android jobb, ale zmieniono jego nazwę z pliku zip. Więc odtworzył plik za pomocą:

jobb -d assets/ -o obb/main.1.com.example.native_activity.obb -k mykey -pn com.example.native_activity -pv 11 

i pchnął go pod

/sdcard/Android/obb/com.example.native_activity/ 

Potem użył klucza i funkcji zwrotnej w wywołaniu mountObb z kodem jak poniżej:

char obbPath[256]; 
sprintf(obbPath, "/sdcard/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb"); 
struct stat sts; 
if(stat(obbPath, &sts) == -1) 
{ 
    LOGI("File not found: %s\n", obbPath); 
} 
else 
{ 
    LOGI("File found: %s", obbPath); 
} 

AStorageManager* man = AStorageManager_new(); 
char* data = malloc(256); 
AStorageManager_mountObb(man, obbPath, "mykey", my_obbCallbackFunc, data); 
char* mntPath = AStorageManager_getMountedObbPath(man, obbPath); 

int isMounted = AStorageManager_isObbMounted(man, obbPath); 

LOGI("mounted path: %s, already mounted?: %d", mntPath, isMounted); 
free(data); 
data = NULL; 
AStorageManager_delete(man); 
man = NULL; 
return 1; 

i wywołanie zwrotne

void my_obbCallbackFunc(const char* filename, const int32_t state, void* data) 
{ 
    LOGI("my_obbCallbackFunc: %d", state); 
} 

Wyjście Logcat mam:

08-09 08:45:15.960: I/native-activity(9166): Touched screen. 
08-09 08:45:15.960: I/native-activity(9166): File found: /sdcard/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb 
08-09 08:45:15.960: E/Parcel(9166): Reading a NULL string not supported here. 
08-09 08:45:15.960: I/native-activity(9166): mounted path: , already mounted?: 0 
08-09 08:45:15.970: I/native-activity(9166): Touched screen. 
08-09 08:45:15.970: I/native-activity(9166): File found: /sdcard/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb 
08-09 08:45:15.970: E/Parcel(9166): Reading a NULL string not supported here. 
08-09 08:45:15.970: I/native-activity(9166): mounted path: , already mounted?: 0 
08-09 08:45:16.030: I/native-activity(9166): my_obbCallbackFunc: 1 
08-09 08:45:16.030: I/native-activity(9166): my_obbCallbackFunc: 24 
08-09 08:45:16.030: I/native-activity(9166): my_obbCallbackFunc: 24 
08-09 08:45:16.030: I/native-activity(9166): my_obbCallbackFunc: 24 
08-09 08:45:16.030: I/native-activity(9166): my_obbCallbackFunc: 24 
08-09 08:45:16.030: I/native-activity(9166): my_obbCallbackFunc: 24 
08-09 08:45:16.030: I/native-activity(9166): my_obbCallbackFunc: 24 

Według android-ndk-r8d/platforms/android-9/arch-arm/usr/include/android/storage_manager.h kod błędu z zwrotnego oznacza

AOBB_STATE_MOUNTED = 1, 
AOBB_STATE_ERROR_ALREADY_MOUNTED = 24, 

to jednak sprzeczne z logcat wydrukować wartości zwracanej AStorageManager_isObbMounted() połączenia, co oznacza, że ​​nie jest jeszcze zamontowany.

Jestem całkowicie zdezorientowany.

Odpowiedz

4

Sam to rozwiązałem.

Istnieje zdecydowanie sprzeczne z intuicją API montowania zapytań, ponieważ obb został zamontowany w katalogu/mnt/obb/kiedy sprawdzam system plików, ale interfejs API ciągle zwraca wartość 0 i odmawia podania mi ścieżki. Prawdopodobnie (szczegóły semantyczne nie są nigdzie udokumentowane) oznacza, że ​​bardzo nie udało się uzyskać połączenia obb, chociaż plik został już wcześniej zamontowany (kod błędu 24 z wywołania zwrotnego).

Więc jeśli odmontuję pierwszy przed ponownym zamontowaniem w kodzie, powinno być dobrze.Więc w zasadzie dodać to:

AStorageManager_unmountObb(man, obbPath, 1, my_obbCallbackFunc, data); 

przed

AStorageManager_mountObb(man, obbPath, "mykey", my_obbCallbackFunc, data); 

I z zwrotnego:

void my_obbCallbackFunc(const char* filename, const int32_t state, void* data) 
{ 
    LOGI("my_obbCallbackFunc: %d", state); 

    AStorageManager* man = AStorageManager_new(); 
    int isMounted = AStorageManager_isObbMounted(man, filename); 
    char* mntPath = AStorageManager_getMountedObbPath(man, filename); 

    LOGI("my_obbCallbackFunc: fn: %s: mounted path: %s, already mounted?: %d", filename, mntPath, isMounted); 
    AStorageManager_delete(man); 
} 

pomyślne wyjście:

08-09 10:41:53.060: I/native-activity(10753): File found: /sdcard/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb 
08-09 10:41:53.070: E/Parcel(10753): Reading a NULL string not supported here. 
08-09 10:41:53.070: I/native-activity(10753): mounted path: , already mounted?: 0 
08-09 10:41:53.080: I/native-activity(10753): Touched screen. 
08-09 10:41:53.080: I/native-activity(10753): File found: /sdcard/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb 
08-09 10:41:53.110: I/native-activity(10753): my_obbCallbackFunc: 2 
08-09 10:41:53.110: E/Parcel(10753): Reading a NULL string not supported here. 
08-09 10:41:53.110: I/native-activity(10753): mounted path: , already mounted?: 0 
08-09 10:41:53.110: E/Parcel(10753): Reading a NULL string not supported here. 
08-09 10:41:53.110: I/native-activity(10753): my_obbCallbackFunc: fn: /storage/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb: mounted path: , already mounted?: 0 
08-09 10:41:53.110: I/native-activity(10753): Touched screen. 
08-09 10:41:53.110: I/native-activity(10753): File found: /sdcard/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb 
08-09 10:41:53.110: E/Parcel(10753): Reading a NULL string not supported here. 
08-09 10:41:53.110: I/native-activity(10753): mounted path: , already mounted?: 0 
08-09 10:41:53.130: I/native-activity(10753): Touched screen. 
08-09 10:41:53.130: I/native-activity(10753): File found: /sdcard/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb 
08-09 10:41:53.130: E/Parcel(10753): Reading a NULL string not supported here. 
08-09 10:41:53.130: I/native-activity(10753): mounted path: , already mounted?: 0 
08-09 10:41:53.260: I/native-activity(10753): my_obbCallbackFunc: 1 
08-09 10:41:53.300: I/native-activity(10753): my_obbCallbackFunc: 2 
08-09 10:41:53.300: E/Parcel(10753): Reading a NULL string not supported here. 
08-09 10:41:53.300: I/native-activity(10753): my_obbCallbackFunc: fn: /storage/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb: mounted path: , already mounted?: 1 
08-09 10:41:53.300: E/Parcel(10753): Reading a NULL string not supported here. 
08-09 10:41:53.300: I/native-activity(10753): my_obbCallbackFunc: fn: /storage/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb: mounted path: , already mounted?: 0 
08-09 10:41:53.490: I/native-activity(10753): my_obbCallbackFunc: 1 
08-09 10:41:53.520: I/native-activity(10753): my_obbCallbackFunc: 2 
08-09 10:41:53.520: E/Parcel(10753): Reading a NULL string not supported here. 
08-09 10:41:53.520: I/native-activity(10753): my_obbCallbackFunc: fn: /storage/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb: mounted path: , already mounted?: 0 
08-09 10:41:53.520: E/Parcel(10753): Reading a NULL string not supported here. 
08-09 10:41:53.520: I/native-activity(10753): my_obbCallbackFunc: fn: /storage/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb: mounted path: , already mounted?: 1 
08-09 10:41:53.680: I/native-activity(10753): my_obbCallbackFunc: 1 
08-09 10:41:53.720: I/native-activity(10753): my_obbCallbackFunc: 2 
08-09 10:41:53.720: E/Parcel(10753): Reading a NULL string not supported here. 
08-09 10:41:53.720: I/native-activity(10753): my_obbCallbackFunc: fn: /storage/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb: mounted path: , already mounted?: 1 
08-09 10:41:53.720: E/Parcel(10753): Reading a NULL string not supported here. 
08-09 10:41:53.720: I/native-activity(10753): my_obbCallbackFunc: fn: /storage/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb: mounted path: , already mounted?: 0 
08-09 10:41:53.870: I/native-activity(10753): my_obbCallbackFunc: 1 
08-09 10:41:53.880: I/native-activity(10753): my_obbCallbackFunc: fn: /storage/Android/obb/com.example.native_activity/main.1.com.example.native_activity.obb: mounted path: /mnt/obb/437f5d6d13a1da1d3b41bb46963e3720, already mounted?: 1 

UPDATE: Jeszcze kilka skrętów, które miałem naprawić, zanim się to całkowicie pracy:

  1. Przy tworzeniu ÖBB użyciu jobb, oprócz prawidłowego nazywania pliku, opcja -pv musi być używany z poprawną versionCode jak w manifest.
  2. Ilekroć konieczna jest aktualizacja do tego samego OBB, np. Kod wersji w nazwie OBB pozostaje taki sam, ale zawartość uległa zmianie, OBB już na urządzeniu musi zostać jawnie usunięte jako pierwsze. W przeciwnym razie prosty OBb-pchnięty OBB nie będzie działać. Ciągle otrzymasz AOBB_STATE_ERROR_COULD_NOT_MOUNT (kod błędu 21) w oddzwanianiu od góry. To zachęca do używania wersji, ale sprawia, że ​​testowanie ad-hoc na tym samym OBB jest trudne, tzn. Nie jest "zalecane", aby kontynuować zmianę OBB bez zwiększania wersji. Oznacza to, że najpierw musisz usunąć OBB, aby "nadpisać" dokładnie ten sam plik OBB.
  3. Wiele samouczków skupia się na nauce korzystania z biblioteki pobierania i robieniu/przesłaniu do/z aplikacji GooglePlay. Jest całkowicie nie do zniesienia, jeśli chcesz tylko sprawdzić, czy OBB uzyskuje dostęp lokalnie.
+0

Dziękuję bardzo za poświęcenie czasu na napisanie tego, walczę teraz z .obbs, a to było bardzo cenne. Dla innych osób czytających to, mogę dodać, że narzędzie jobb daje Fat Full błędy, jeśli masz zbyt mało plików w jakimś katalogu. Uff, praca z obbs była piekłem. –

+0

Jedna uwaga, wydaje się, że zakładasz, że wywołania zwrotne są wykonywane synchronicznie, ale zamontowanie obb jest (o ile widzę) operacją asynchroniczną. Czy to może być powód, dla którego masz pustą ścieżkę? (Uwaga: obecnie, wydaje mi się, że w ogóle nie otrzymuję żadnych wywołań zwrotnych, mój obb nie jest montowany ... debugowanie ...) –

Powiązane problemy