AMarquez94 AMarquez94 - 27 days ago 9
C++ Question

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

I'm trying to make an app in Android that uses

. The problem I am facing 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
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:


EDIT 3 (Solved):

Solved! The solution is the answer provided by @PavneetSingh, it was a permission problem in Android 6.0 (Marshmallow). Had to ask for runtime permissions. (See his answer to full information).


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