2016-08-17 12 views
0

私はAndroidで簡単なアプリケーションを作っています。 NDNを使用してJNIコールを作成しています。私はネイティブのC + +コードからアクセスする必要があるリソースのサブフォルダ(生)にファイルがあります。私は、例えば "ifstream"関数を使ってネイティブからそれを読んでみたいですが、私はそれをやり遂げません。私のC++コードですjni nativeファイルからrawファイルを取得するには

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); 
    } 

私のJavaコードです

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); 
} 

は、誰もが私を助けることができますか?私は必死です。ありがとう!

+0

あなたはファイル記述子を使うことができますが、 'std :: istream'を得ることができるかどうかわかりません – Selvin

+0

生のフォルダはアンパックされていないzipファイルのapkの中にあります。したがって、通常のファイル読み取りメソッドは機能しません。 Java AssetManagerクラスが役立つかもしれません。あるいは、Java側でrawからファイルを抽出して保存したり、メッセージパッシングプロトコルを使用してファイルのバイトをJavaからC++側に転送することもできます。別の方法は、あなたのAPKを開くためにzlibを使うことです。 –

答えて

0

ファイルはAPK内に保存されますが、拡張子を.PNGのように変更すると圧縮されません。ファイルをassetsフォルダに入れてください(res/rawではなく)。

あなたは、このような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(); 
    } 
} 

コール:

findAPKFile("model.png", MyActivity.this); 

その後APK内のあなたのリソースのオフセットを見つける

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; 
} 

をあなたのC++を呼び出してoffsetfileSizeapkFilepathを渡すことができます。 JNI。ファイルを開き、先にoffsetバイトを探し、fileSizeバイトのデータを読み込みます。

this questionに受け入れられた回答は、別の方法を示していますが、私はそれを保証することはできません。

関連する問題