Here is a detailed example of how to read a file located in the apk,
from within native code, using an AssetFileDescriptor:
The file name is myFile.mp3 (I use the .mp3 suffix to avoid file
compression), and it is located in the res/raw/ directory.
--------------------------------------------
--------------------------------------------
In the Java side:
package com.myApp;
public final class myClass{
        public static int init(MyActivity activity)
        {
                AssetFileDescriptor afd =
activity.getApplicationContext().getResources().openRawResourceFd(R.raw.myF
ile);
                int res = 0;
                if (afd != null)
                {
                        FileDescriptor fd = afd.getFileDescriptor();
                        int off = (int) afd.getStartOffset();
                        int len = (int) afd.getLength();
                        res = initNative(fd, off, len);
                }
                return res;
        }
        public static native int initNative(FileDescriptor fd, long
off, long
len);
}
-------------------------------------------
-------------------------------------------
In C++ side:
in the .h file:
----------------
#include <stdio.h>
#include <jni.h>
extern "C" {
JNIEXPORT jint JNICALL Java_com_myApp_myClass_initNative
  (JNIEnv * env, jclass thiz, jobject fd_sys, jlong off, jlong len);
}
in the .cpp file:
--------------------
#define
SUCCESS
0
#define ERROR_CODE_CANNOT_OPEN_MYFILE                           100
#define ERROR_CODE_CANNOT_GET_DESCRIPTOR_FIELD                  101
#define ERROR_CODE_CANNOT_GET_FILE_DESCRIPTOR_CLASS             102
JNIEXPORT jint JNICALL Java_com_myApp_myClass_initNative
(JNIEnv * env, jclass thiz, jobject fd_sys, jlong off, jlong len)
{
        jclass fdClass = env->FindClass("java/io/FileDescriptor");
        if (fdClass != NULL){
                jfieldID fdClassDescriptorFieldID = env-
>GetFieldID(fdClass,
"descriptor", "I");
                if (fdClassDescriptorFieldID != NULL && fd_sys != NULL)
{
                        jint fd = env->GetIntField(fd_sys,
fdClassDescriptorFieldID);
                        int myfd = dup(fd);
                        FILE* myFile = fdopen(myfd, "rb");
                        if (myFile){
                                fseek(myFile, off, SEEK_SET);
                                /
***************************************************
                                    here myFile is a regular FILE*
pointing to
                                    the file I want to read.
                                    I use the fscanf function:
 
***************************************************/
                                fscanf(fp, "%d%d", &var1, &var2);
                                fscanf(fp, "%d%d", &var3, &var4);
                                ...
                                ...
                                ...
                                return (jint)SUCCESS;
                        }
                        else {
                                return (jint)
ERROR_CODE_CANNOT_OPEN_MYFILE;
                        }
                }
                else {
                        return
(jint)ERROR_CODE_CANNOT_GET_DESCRIPTOR_FIELD;
                }
        }
        else {
                return
(jint)ERROR_CODE_CANNOT_GET_FILE_DESCRIPTOR_CLASS;
        }
}
Just a short warning, quoting fadden (
http://groups.google.com/group/
android-ndk/browse_thread/thread/a69084018e87a5a8):
>"descriptor" is a package-private field inside FileDescriptor, and as
>such isn't part of the API, is subject to change, etc.
"descriptor" field is used in the C++ code, so pay attention that the
above code is using non API fields, and may crash in the future.
I hope that until this happens, the NDK team will come up with an
official solution to reading assets in native code :-).
Hope this helps,
Fulanito.
> You can see the whole source file here:
http://wlan-lj.net/browser/trunk/meshapp/android/meshapp/src/net/wlan...