Open and read text file in c++ with Android (ndk)
The file
is not yet opened, you have to call file.open()
function to associate the stream with current file before is_open
check.
file.open();
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
AMarquez94
Young programmer that just finished Computer Engineering Degree at University. Passionated about technology and video games. Real world problems, here I go!
Updated on June 04, 2022Comments
-
AMarquez94 almost 2 years
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:
Recognizer.cpp:
#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; __android_log_print(ANDROID_LOG_DEBUG,"NOMBRE","%s",name.c_str()); } 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>()); descriptors.push_back(Mat()); 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 */ viewNames.push_back(word); String aux = word; __android_log_print(ANDROID_LOG_DEBUG, "VISTA NOMBRE", "%s", aux.c_str()); } i++; } Object obj = Object(name, keypoints, descriptors, corners, viewNames, easy); if(add){ this->objects.push_back(obj); } file.close(); 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 ...do 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!
EDIT 1:
Changed code to this:
__android_log_print(ANDROID_LOG_DEBUG,"path","%s",(path + "/info.txt").c_str()); ifstream file; file.open((path + "/info.txt").c_str()); if (!file.is_open()){ //always enters here return Object(true); //null object } else{ //never enters here ...do stuff... }
Still having the same problem.
EDIT 2
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:
-
AMarquez94 over 7 yearsworked like a charm, thank you very much! (I upvoted your answer, but it says it will not show because I have less than 15 rep points, sorry).