Câu trả lời ngắn
lập bản đồ số AFAIK fread/fopen trong C++ để AAssetManager là không thể. Và nếu nó có thể sẽ giới hạn bạn vào các tập tin trong thư mục tài sản. Tuy nhiên, có một cách giải quyết khác, nhưng nó không đơn giản.
dài trả lời
Nó LÀ thể truy cập bất kỳ tập tin bất cứ nơi nào trong APK sử dụng zlib và libzip trong C++. Yêu cầu: một số java, zlib và/hoặc libzip (để dễ sử dụng, vì vậy đó là những gì tôi đã giải quyết). Bạn có thể tải libzip tại đây: http://www.nih.at/libzip/
libzip có thể cần một số tinkering để làm cho nó hoạt động trên Android, nhưng không có gì nghiêm trọng.
Bước 1: lấy apk vị trí trong Java và vượt qua JNI/C++
String PathToAPK;
ApplicationInfo appInfo = null;
PackageManager packMgmr = parent.getPackageManager();
try {
appInfo = packMgmr.getApplicationInfo("com.your.application", 0);
} catch (NameNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("Unable to locate APK...");
}
PathToAPK = appInfo.sourceDir;
Đi qua PathToAPK C++/JNI
JNIEXPORT jlong JNICALL Java_com_your_app(JNIEnv *env, jobject obj, jstring PathToAPK)
{
// convert strings
const char *apk_location = env->GetStringUTFChars(PathToAPK, 0);
// Do some assigning, data init, whatever...
// insert code here
//release strings
env->ReleaseStringUTFChars(PathToAPK, apk_location);
return 0;
}
Giả sử bây giờ bạn có một std :: string với vị trí APK của bạn và bạn có zlib trên libzip hoạt động, bạn có thể làm điều gì đó như sau:
if(apk_open == false)
{
apk_file = zip_open(apk_location.c_str(), 0, NULL);
if(apk_file == NULL)
{
LOGE("Error opening APK!");
result = ASSET_APK_NOT_FOUND_ERROR;
}else
{
apk_open = true;
result = ASSET_NO_ERROR;
}
}
Và để đọc một tập tin từ APK:
if(apk_file != NULL){
// file you wish to read; **any** file from the APK, you're not limited to regular assets
const char *file_name = "path/to/file.png";
int file_index;
zip_file *file;
struct zip_stat file_stat;
file_index = zip_name_locate(apk_file, file_name, 0);
if(file_index == -1)
{
zip_close(apk_file);
apk_open = false;
return;
}
file = zip_fopen_index(apk_file, file_index, 0);
if(file == NULL)
{
zip_close(apk_file);
apk_open = false;
return;
}
// get the file stats
zip_stat_init(&file_stat);
zip_stat(apk_file, file_name, 0, &file_stat);
char *buffer = new char[file_stat.size];
// read the file
int result = zip_fread(file, buffer, file_stat.size);
if(result == -1)
{
delete[] buffer;
zip_fclose(file);
zip_close(apk_file);
apk_open = false;
return;
}
// do something with the file
// code goes here
// delete the buffer, close the file and apk
delete[] buffer;
zip_fclose(file);
zip_close(apk_file);
apk_open = false;
Không chính xác fopen/fread nhưng nó được công việc làm. Nó sẽ được khá dễ dàng để bọc này vào chức năng đọc tập tin của riêng bạn để trừu tượng lớp zip.
Vì nội dung không phải là tệp, câu trả lời có thể là "không". Nội dung là các mục nhập trong kho lưu trữ ZIP là APK. – CommonsWare
'Tis là một điểm tốt ... –
Về mặt kỹ thuật, vì APK không có gì hơn một tệp zip lạ mắt, bạn hoàn toàn có thể truy cập bất kỳ tệp nào ở bất kỳ đâu trong APK như thể đó là tệp zip trong C++. Nó tuy nhiên yêu cầu * một số * java, nhưng chỉ để có được vị trí cài đặt apk của bạn. Tôi biết để thực tế là không phải là một vấn đề nhưng tôi chưa bao giờ thử viết một APK. – Erik