2012-04-15 24 views
11

Tôi đang sử dụng C++ thuần túy trong công cụ của mình để tạo công cụ trò chơi trong Android. Không có tệp java đơn lẻ nào. Về cơ bản nó là một trò chơi mà chỉ nên được lưu trữ vào bộ nhớ bên ngoài. Khi tôi di chuyển dữ liệu tài sản của mình theo cách thủ công thông qua adb vào thẻ sd bên ngoài của tôi, trò chơi hoạt động tốt và ổn định.Truy cập dữ liệu Nội dung APK Android Truy cập trực tiếp bằng C++ mà không cần Quản lý tài sản và sao chép

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

Đây không phải là giải pháp tốt vì không thể gửi được. Vì vậy, tôi có tôi tài sản dữ liệu trong thư mục tài sản mà được chuyển sang các tập tin apk trong quá trình xây dựng với cấu trúc sau:

Assets/Dữ liệu/MoreFolders/Withsubfolders Assets/Dữ liệu/EngineData.zip Assets/Dữ liệu/ScriptData.zip

Nhưng tôi không biết các tệp đó nằm trong hệ thống tệp để truy cập chúng trong mã C++.

Vì vậy, tôi đã cố gắng lấy đường dẫn đến thư mục tệp. Và vì lỗi trong trạng thái hoạt động gốc Tôi phải truy xuất thông tin trong mã thông thường.

// 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++ mã cho tương đương với android.os.Environment.getFilesDir() và android.os.Environment.getExternalStorageState() vv

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

mà hoạt động khá tốt và kết quả trong

PATH NỘI = /data/data/com.fantasyhaze.rememory/files

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

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

Nhìn lên con đường mã gói = /mnt/asec/com.fantasyhaze.rememory-2/pkg.apk

Nhưng không có tệp nào từ thư mục nội dung ...

và tôi cần truy cập thư mục làm thư mục làm việc bình thường để đọc tệp. đó sẽ là có thể trong

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

Nhưng di chuyển tất cả dữ liệu từ thư mục tài sản (bất cứ nơi nào nó là) thông qua quản lý tài sản vào thư mục này , gây ra tiêu thụ gấp đôi bộ nhớ.

nội dung> 1GB có nghĩa là nội dung> 2 GB không có ý nghĩa. Hơn thế nữa thư mục khẳng định dường như không hoạt động lặp lại và chỉ cho các tệp dữ liệu nhỏ mà không thể thực hiện được khi sử dụng tệp pak lớn hơn. Có thể các tệp có thể truy cập trực tiếp từ gói ứng dụng khi sử dụng hệ thống giải nén và sau đó uzip các tệp nguồn của tôi, nhưng do đó tôi phải mở đường dẫn apk.

Vì vậy, câu hỏi của tôi:

  1. đâu là thư mục tài sản trong gói ứng dụng trên hệ thống tập tin?
  2. Mã sẽ là gì (C++) để truy xuất vị trí apk hoặc vị trí của tệp thực thi
  3. Tôi có thể truy cập trực tiếp bằng phương pháp mở tệp bình thường hoặc chỉ khi tôi giải nén nó. Nếu tôi có thể sử dụng nó mà không giải nén, làm thế nào?
  4. Mã sẽ là gì (C++) để truy xuất thông tin nếu thẻ sd được lắp?

Tôi hy vọng ai đó có thể giúp tôi :)

Edit: Added thư mục bộ nhớ cache và mã thư mục gói (và đó là con đường đầu ra), để cung cấp nguồn cho tất cả mọi người cần nó.

+0

Nhận nội dung từ phía NDK là khó khăn và không đáng tin cậy do lỗi trong một số phiên bản của việc triển khai Android gốc. Hãy để tôi tìm thấy rằng nfo và lấy lại cho bạn. –

+0

Nếu bạn không muốn sử dụng NativeActivity, bạn có thể sử dụng phương thức này (chỉ để tham khảo trong tương lai) để tìm APK và tải nội dung. http://androgeek.info/?p=275 –

+0

Xin chào, tôi đang cố gắng sử dụng mã này trong câu hỏi này. Tôi cần phải có được "getPackageCodePath" đường dẫn cho tập tin .apk và đường dẫn thư mục nội bộ. nhưng nó tiếp tục ném cho tôi lỗi không thể gọi. bất cứ ai có thể giúp tôi ?? cảm ơn trước. trong MainActivity tôi có: thử nghiệm int native native(); và tải thư viện. trong mã C Tôi đang gọi phương thức JNI và cùng một "đường dẫn mã gói" cho .apk: – RKosamia

Trả lời

3

Tôi đăng câu trả lời thay vì đánh dấu mục này là trùng lặp vì về mặt kỹ thuật, bạn đang yêu cầu cung cấp thêm chi tiết hơn được cung cấp trong câu hỏi/câu trả lời tôi sẽ liên kết tại đây. Vì vậy, để trả lời câu hỏi đầu tiên trong số 4 điểm của bạn, hãy xem Obtaining the name of an Android APK using C++ and the NativeActivity class.

Để kiểm tra xem thẻ SD đã được lắp chưa, điều đó khá đơn giản. Chỉ cần cố gắng mở thư mục hoặc tệp trên SDcard (bạn biết là có) và nếu không thành công, bạn biết thẻ SD không khả dụng. Xem What's the best way to check if a file exists in C? (cross platform).

+0

Thx cho thông tin, được rao giảng quá lâu cho nó nhưng không thể tìm thấy bài đăng này trong liên kết 2! Với các thông tin ở đó tôi cuối cùng có thể lấy vị trí của apk :) Nhập mã trong bài đầu tiên để cung cấp nó trong một hình thức khác với một từ liên kết. Kiểm tra các tập tin là ok, nhưng tôi nghĩ rằng có thể có một số phương pháp để kiểm tra xem thẻ sd được gắn trong mã c tương tự như: 'android.os.Environment.getExternalStorageState(). Equals (android.os.Environment.MEDIA_MOUNTED) ; 'như đã thấy trong [link] (http://stackoverflow.com/questions/902089/how-to-tell-if-the-sdcard-is-mounted-in-android) – odbb

2

Bạn có thể muốn xem "Tệp mở rộng", xem APK Expansion Files.

Theo tôi hiểu điều này, điều này mang lại cho bạn một hệ thống tự động đặt các tệp tài nguyên (tệp mở rộng của bạn) vào "vị trí lưu trữ được chia sẻ".

Vì vậy, tôi nghĩ rằng điều này sẽ giải quyết vấn đề của bạn về dữ liệu trùng lặp.

Ngoài ra còn có phần giới thiệu ngắn post on the android-developers blog.

+0

Tôi không biết rằng có một giới hạn 50MB !!! trên kích thước tập tin apk? Đó là khủng khiếp và những tập tin mở rộng có thể giải quyết vấn đề, nhưng một lần nữa là có bất kỳ nguồn cho việc sử dụng AStorageManager trong C/C++ để truy cập vào các tập tin odb? Dường như có rất nhiều công việc reimplementing các công cụ downloader trong bản địa c: / – odbb

Các vấn đề liên quan