Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android NDK: read file from assets inside of shared library

In my app I have to pass a file from assets folder to shared library. I cannot do it with use of jni right now. I'm using precompiled shared library in my project, in which I have hardcoded path to my file, but I'm getting error "No such file or directory". So in my .apk file I have .so file in libs/armeabi-v7a folder and my file in /assets folder.

I have tried to do it like this:

char *cert_file = "/assets/cacert.cert";
av_strdup(cert_file);

And some other paths, but it doesn't work.

Is it possible at all?

like image 629
Pavel S. Avatar asked Apr 29 '14 18:04

Pavel S.


2 Answers

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()
like image 165
Sistr Avatar answered Nov 11 '22 20:11

Sistr


Your assets are packaged into your apk, so you can't refer to them directly during runtime like in the sample code you provided. You have 2 options here:

  • Process the assets as an input stream, using

Context.getAssets().open('cacert.cert')

  • Copy out your asset to a local file in your files dir, and then reference the filename of the copied file.
like image 3
user868459 Avatar answered Nov 11 '22 19:11

user868459