String Path = "music/bg.mp3"; // The correct parameter // string Path = "assets/music/bg.mp3"; // The error parameter // string Path = "file: /// android_asset/music/bg.mp3 "; // The error parameter // string Path ="/music/bg.mp3 "; // The error parameter assetfiledescriptor assetfiledescritor = mcontext. getassets (). openfd (PATH); mediaplayer. setdatasource (assetfiledescritor. getfiledescriptor (), assetfiledescritor. getstartoffset (), assetfiledescritor. getlength (); assetfiledescritor. close ();
1. The path parameters of assetmanager in Java code cannot contain "assets /",
2. However, in ndk programming, if the C Code uses zip to access the assets file, it must contain "assets /"
//ReadAssets fileName = assets/rabbit/img/banana_skin.png
off_t readFileFromAsset(const char* fileName, char ** buffer)
{
logd("ReadAssets fileName = %s", fileNmae);
struct zip* apkArchive=zip_open(assetPath, 0, NULL);
struct zip_stat fstat;
struct zip_file* file = zip_fopen(apkArchive, fileName, 0); if (!file) { loge("Error opening %s from APK", fileName); return -1; } zip_stat(apkArchive,fileName,0,&fstat); off_t bfsize = fstat.size; *buffer=(char *)malloc(bfsize+1); memset(*buffer, 0x0, bfsize+1); int numBytesRead = zip_fread(file, *buffer,bfsize);; zip_fclose(file); return bfsize;}
In the above Code, assetpath is transmitted at the Java layer. It is passed to the C ++ layer by calling string assetpath = context. getpackageresourcepath ().
Const char * assetpath = env-> getstringutfchars (jassetpath, false );
Env-> releasestringutfchars (jassetpath, assetpath );
.
3. aassetmanager must start with "assets/" in the C ++ layer.
AAsset* asset = AAssetManager_open(assetMgr, realPath, AASSET_MODE_UNKNOWN); off_t bufferSize = AAsset_getLength(asset); char* buffer=(char*)malloc(bufferSize+1); memset(buffer, 0, bufferSize); buffer[bufferSize]=0; int numBytesRead = AAsset_read(asset, buffer, bufferSize); AAsset_close(asset);