How to Get File in Assets from Android Ndk

How To Get File In Assets From Android NDK

You can read the image from an asset with AAssetManager_open & AAsset_read, but since asset lies in apk you can't get a file path name for it - it is also compressed there. You can save the data to a file and read from that file later or you can directly process the chunk you got from your asset file if OSG allows.

From here:

AAssetDir* assetDir = AAssetManager_openDir(mgr, "");
const char* filename = (const char*)NULL;
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING);
char buf[BUFSIZ];
int nb_read = 0;
FILE* out = fopen(filename, "w");
while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0)
fwrite(buf, nb_read, 1, out);
fclose(out);
AAsset_close(asset);
}
AAssetDir_close(assetDir);

Android NDK: read file from assets inside of shared library

You can simply use the AAssetManager class in C++.

Basically you need to:

  • During the init of you library get a pointer on: AAssetManager* assetManager
  • Use it to read your file:

    // Open your file
    AAsset* file = AAssetManager_open(assetManager, filePath, AASSET_MODE_BUFFER);
    // Get the file length
    size_t fileLength = AAsset_getLength(file);

    // Allocate memory to read your file
    char* fileContent = new char[fileLength+1];

    // Read your file
    AAsset_read(file, fileContent, fileLength);
    // For safety you can add a 0 terminating character at the end of your file ...
    fileContent[fileLength] = '\0';

    // Do whatever you want with the content of the file

    // Free the memoery you allocated earlier
    delete [] fileContent;

You can find the official ndk documentation here.

Edit:
To get the AAssetManager object:

  • In a native activity, you main function as a paramater android_app* app, you just need to get it here: app->activity->assetManager
  • If you have a Java activity, you need so send throught JNI an instance of the java object AssetManager and then use the function AAssetManager_fromJava()

How to use Asset Manager API in NDK to read raw data?

You must initialize mAssetManager to begin with, we usually get it from Java via a JNI call, see e.g. this answer. You can obtain this Java object in your C++ code like this, but this still needs JNIEnv.

If you really really want to extract an asset from your APK with no JNI interaction, it not impossible. The trick is to find your APK file and trust that it is a ZIP file under the hood.

Android read text file from asset folder using C (ndk)

Here is the code I used to read file from android assets folder using asset_manager ndk lib

    AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
AAsset* asset = AAssetManager_open(mgr, (const char *) js, AASSET_MODE_UNKNOWN);
if (NULL == asset) {
__android_log_print(ANDROID_LOG_ERROR, NF_LOG_TAG, "_ASSET_NOT_FOUND_");
return JNI_FALSE;
}
long size = AAsset_getLength(asset);
char* buffer = (char*) malloc (sizeof(char)*size);
AAsset_read (asset,buffer,size);
__android_log_print(ANDROID_LOG_ERROR, NF_LOG_TAG, buffer);
AAsset_close(asset);

Added following line to my Android.mk

# for native asset manager
LOCAL_LDLIBS += -landroid

And don't forget the include in source file

#include <android/asset_manager.h>

Android Asset FileNotFound Exception Using Kotlin and Android NDK C++

The issue was I grabbed my asset manager using

manager = Resources.getSystem().assets

which only gets me access to system resources, not application resources. Instead, I should have passed my context from my surface view class to the renderer class

//Surface View Class
class glSurfaceView(context: Context, attrs: AttributeSet) : GLSurfaceView(context, attrs)
//Renderer Class
class glRenderer(private val context: Context) : GLSurfaceView.Renderer

so that I could get my asset manager simply using

manager = context.assets

Thanks to @Michael for pointing that out



Related Topics



Leave a reply



Submit