I'm making a simple app in Android. I'm using NDK to make JNI calls. I have a file in a resource subfolder (raw), which I need to access from native c++ code. I want to read it from native using for example "ifstream" function but I don't get to do that.
That's my Java code:
Algorithm algorithm = new Algorithm();
InputStream isModel = getResources().openRawResource(R.raw.model);
String model = algorithm.ReadResourceFile(isModel);
if(imgInput != null && txtResults != null)
{
Bitmap bmp = ((BitmapDrawable)imgInput.getDrawable()).getBitmap();
//Convert Bitmap to Mat
Mat image = new Mat(bmp.getHeight(), bmp.getWidth(), CvType.CV_8U);
//Print results on txtResults
String results = algorithm.DetectEmotionByImage(image.nativeObj, model);
txtResults.setText(results);
}
That's my C++ code:
JNIEXPORT jstring JNICALL
Java_org_ctic_emoplay_1android_algorithm_Algorithm_DetectEmotionByImage(JNIEnv *env,
jobject instance,
jlong image,
jstring fileModel_,
jstring fileRange_,
jstring fileModelFlandmarks_,
jstring fileHaarCascade_)
{
const char *fileModel = env->GetStringUTFChars(fileModel_, NULL);
SVM_testing testing;
Mat* imageInput= (Mat*)image;
Mat& inImageInput = *(Mat*) imageInput;
string results = testing.TestModel(inImageInput, fileModel);
const char* final_results = results.c_str();
env->ReleaseStringUTFChars(fileModel_, fileModel);
return env->NewStringUTF(final_results);
}
Anyone can help me? I'm desperated. Thanks!
The file will be stored inside the APK, but if you rename the file extension to something like .PNG then it will not be compressed. Put the file in the assets
folder, not res/raw
.
You can get the APK file path like this:
public static String getAPKFilepath(Context context) {
// Get the path
String apkFilePath = null;
ApplicationInfo appInfo = null;
PackageManager packMgmr = context.getPackageManager();
String packageName = context.getApplicationContext().getPackageName();
try {
appInfo = packMgmr.getApplicationInfo(packageName, 0);
apkFilePath = appInfo.sourceDir;
} catch (NameNotFoundException e) {
}
return apkFilePath;
}
Then find the offset of your resource inside the APK:
public static void findAPKFile(String filepath, Context context) {
String apkFilepath = getAPKFilepath(context);
// Get the offset and length for the file: theUrl, that is in your
// assets folder
AssetManager assetManager = context.getAssets();
try {
AssetFileDescriptor assFD = assetManager.openFd(filepath);
if (assFD != null) {
long offset = assFD.getStartOffset();
long fileSize = assFD.getLength();
assFD.close();
// **** offset and fileSize are the offset and size
// **** in bytes of the asset inside the APK
}
} catch (IOException e) {
e.printStackTrace();
}
}
Call like this:
findAPKFile("model.png", MyActivity.this);
You can call your C++ and pass offset
, fileSize
and apkFilepath
via JNI. Open the file, seek past offset
bytes and then read out fileSize
bytes of data.
The accepted answer to this question shows an alternative method but I haven't tried doing it that way so I can't vouch for it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.