Saturday, June 28, 2014

Resolving Folder reading issue from SD Card in BB10

There was a tricky bug in Audiobook Reader BB10 version for quite a some time which I was trying to resolve. Issue was that, for some folder in SD card, I was not able to browse it using QDir Qt API or Posix API. Though API was showing the folder, but when I try to find out folder's content, it reports folder as empty.

This was causing serious usability issue with Audiobook Reader application, as user were not able to add book from SD card. I debugged it long and tried to use various approach to resolve the issue but could not find any satisfactory solution.

I read it somewhere it causes issue if SD card was formatted with PC software and issue is resolved if you format SD card with BB10 setting. But this also looks hassle to user.

Finally, I decided to see how directory structure looks like and what is folders permission using SSH to device. When I used linux command like ls and cd, I was able to see folder's content fine. And I decide to use those command to resolve directory browsing issue.

Following is my code, if someone else is also facing similar issue. First I am escaping special character in filepath, else linux command will not work. Then I am creating "ls" command with sorting and with output which list directory content in absolute file path. Once we have proper command I am using popen API to run command and then using IO api to read command's output.
QStringList BookListModel::getFileList(const QString& dir) {

 QString filePath(dir);
 filePath.replace(" ","\\ ");
 filePath.replace("'","\\'");
 filePath.replace("`","\\`");
 filePath.replace("!","\\!");
 filePath.replace("$","\\$");
 filePath.replace("&","\\&");
 filePath.replace("*","\\*");
 filePath.replace("\"","\\\"");
 filePath.replace("(","\\(");
 filePath.replace(")","\\)");
 filePath.replace("[","\\[");
 filePath.replace("]","\\]");

 qDebug() << filePath;
 QString cmd = QString("ls -1 %1/*").arg(filePath);
 qDebug() << cmd;

 QStringList files;
 char path[1035];
 FILE* fp = popen(cmd.toStdString().c_str(), "r");
 if (fp == NULL) {
  qDebug() << "Failed to run command";
  return files;
 }

 while (fgets(path, sizeof(path)-1, fp) != NULL) {
  QString file = QString(path).trimmed();
  QFileInfo fileInfo(file);
  if (fileInfo.isFile() && FileModel::isSupportedMedia(fileInfo.fileName()) ){
   files << file;
  }
 }

 qDebug() << files;

 pclose(fp);
}
That's all, hope it will be helpful to someone.

No comments:

Post a Comment