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

11,404

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

Share:
11,404
AMarquez94
Author by

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, 2022

Comments

  • AMarquez94
    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:

    Photo

  • AMarquez94
    AMarquez94 over 7 years
    worked 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).