AMarquez94 AMarquez94 - 24 days ago 9x
Android Question

Open and read text file in c++ with Android (ndk)

I'm trying to make an app in Android that uses OpenCV in C++. The problem I face is that I want to open a text file from the native part to read it word by word, but it won't open. My code is the following:

JNI method:

JNIEXPORT jboolean JNICALL Java_com_alejandro_nativeopencv_NativeClass_initRecognizer(JNIEnv * env, jclass clazz){

recognizer = Recognizer("ORB","ORB","BruteForce-Hamming");
recognizer.createObject("/storage/emulated/0/TFG/Fotos/Carpeta", true);
recognizer.createObject("/storage/emulated/0/TFG/Fotos/Cereales", true);

return true;

And the Recognizer::createObject method that I am using:


#include "headers/Recognizer.h"
#include <fstream>
#include <iostream>
#include <string>
#include <android/log.h>

using namespace std;
using namespace cv;

//...other methods, constructors and stuff...

Object Recognizer::createObject(String path, bool add) {
__android_log_print(ANDROID_LOG_DEBUG,"path","%s",(path + "/info.txt").c_str());
ifstream file((path + "/info.txt").c_str());
if (!file.is_open()){
//always enters here
return Object(true); //null object
} else{
//never enters here
String name;
vector < vector<KeyPoint> > keypoints;
vector <Mat> descriptors;
vector < vector<Point2f> > corners;
vector <String> viewNames;
bool easy;

string word;
int i = 0;
while (file >> word)
if(i == 0){

/* Object name */
name = word;


} else if(i == 1){

/* Object easy or not */
easy = (word == "true");
__android_log_print(ANDROID_LOG_DEBUG, "EASY", "%d", easy);
} else if(i%2 == 0){

/* Object image view*/
keypoints.push_back(vector <KeyPoint>());
corners.push_back(vector <Point2f>(4));

Mat image = imread(path + "/" + word, CV_LOAD_IMAGE_GRAYSCALE);
this->detector->detect(image, keypoints[(i/2)-1]);
this->extractor->compute(image, keypoints[(i/2)-1], descriptors[(i/2)-1]);
corners[(i/2)-1][0] = cvPoint(0,0);
corners[(i/2)-1][1] = cvPoint(image.cols,0);
corners[(i/2)-1][2] = cvPoint(image.cols, image.rows);
corners[(i/2)-1][3] = cvPoint(0, image.rows);
__android_log_print(ANDROID_LOG_DEBUG, "VISTA", "%d", (i/2)-1);
} else{

/* Object name view */

String aux = word;
__android_log_print(ANDROID_LOG_DEBUG, "VISTA NOMBRE", "%s", aux.c_str());

Object obj = Object(name, keypoints, descriptors, corners, viewNames, easy);



return obj;

The problem is here:

__android_log_print(ANDROID_LOG_DEBUG,"path","%s",(path + "/info.txt").c_str());
ifstream file((path + "/info.txt").c_str());
if (!file.is_open()){
//always enters here
return Object(true); //null object
} else{
//never enters here stuff...

In the JNI method, I pass as parameter the path where the info.txt file that I want to read is located, but it doesn't open it (no error, it just enters in the first if statement. I first tried putting the folder in the sdcard of my mobile phone, and after that in my internal storage, but it doesn't work in any way. I checked in my phone, and I guess the path is correct:

Link to the image showing the folder path

Also I have in the Android Manifest the read and write external storage permission.

Do you know where or what is the problem here?

Thank you very much!


Changed code to this:

__android_log_print(ANDROID_LOG_DEBUG,"path","%s",(path + "/info.txt").c_str());
ifstream file; + "/info.txt").c_str());
if (!file.is_open()){
//always enters here
return Object(true); //null object
} else{
//never enters here stuff...

Still having the same problem.


The log results I'm getting are these (they correspond with the paths it's trying to access):

D/path: /storage/emulated/0/TFG/Fotos/Carpeta/info.txt
D/path: /storage/emulated/0/TFG/Fotos/Cereales/info.txt

The file info.txt is in that path according to my device:



The file is not yet opened, you have to call function to associate the stream with current file before is_open check.;
 if (!file.is_open()){
        return Object(true); 

Update : The other reason could be that you don't have runtime permission model . try the official docs and this link for precise example