Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. How to get file path from fileurl in qt android

How to get file path from fileurl in qt android

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
androidqt 5.4file dialogfileurlmobile
5 Posts 4 Posters 1.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    HemantSuryawanshi
    wrote on last edited by
    #1

    I am working on qt 5.14.1 with ndk version 21 and sdk version 28. I want to open a kml file using file dialog in qt android. I get a fileurl from file dialog like this,

    "content://com.android.externalstorage.documents/document/primary%3Adocuments%2FAeroGCS%2FAeroGCSWorkspace%2FAbc5%2FBbb%2FBbb.kml"
    

    but I didnt know how to convert this url into simple path and read the data from file. Please tell me how can I convert this url into proper android path.

    JonBJ 1 Reply Last reply
    0
    • H HemantSuryawanshi

      I am working on qt 5.14.1 with ndk version 21 and sdk version 28. I want to open a kml file using file dialog in qt android. I get a fileurl from file dialog like this,

      "content://com.android.externalstorage.documents/document/primary%3Adocuments%2FAeroGCS%2FAeroGCSWorkspace%2FAbc5%2FBbb%2FBbb.kml"
      

      but I didnt know how to convert this url into simple path and read the data from file. Please tell me how can I convert this url into proper android path.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @HemantSuryawanshi
      I don't know anything about Android, but did you try passing that string to QFile() directly? Or, what about via QString QUrl::toLocalFile() const? Just a thought, may not help....

      H 1 Reply Last reply
      0
      • JonBJ JonB

        @HemantSuryawanshi
        I don't know anything about Android, but did you try passing that string to QFile() directly? Or, what about via QString QUrl::toLocalFile() const? Just a thought, may not help....

        H Offline
        H Offline
        HemantSuryawanshi
        wrote on last edited by
        #3

        @JonB yes I tried but its giving message that the file is not found.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          Soviet-Ball
          wrote on last edited by
          #4

          @HemantSuryawanshi
          Hi,
          maybe you can try this function below.

          static QString getRealPathFromUri(const QUrl &url)
          {
              QString path = "";
          
              QFileInfo info = QFileInfo(url.toString());
              if(info.isFile())
              {
                  QString abs = QFileInfo(url.toString()).absoluteFilePath();
                  if(!abs.isEmpty() && abs != url.toString() && QFileInfo(abs).isFile())
                  {
                      return abs;
                  }
              }
              else if(info.isDir())
              {
                  QString abs = QFileInfo(url.toString()).absolutePath();
                  if(!abs.isEmpty() && abs != url.toString() && QFileInfo(abs).isDir())
                  {
                      return abs;
                  }
              }
              QString localfile = url.toLocalFile();
              if((QFileInfo(localfile).isFile() || QFileInfo(localfile).isDir()) && localfile != url.toString())
              {
                  return localfile;
              }
          #ifdef Q_OS_ANDROID
              QJniObject jUrl = QJniObject::fromString(url.toString());
              QJniObject jContext = QtAndroidPrivate::context();
              QJniObject jContentResolver = jContext.callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;");
              QJniObject jUri = QJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", jUrl.object<jstring>());
              QJniObject jCursor = jContentResolver.callObjectMethod("query", "(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;", jUri.object<jobject>(), nullptr, nullptr, nullptr, nullptr);
              QJniObject jScheme = jUri.callObjectMethod("getScheme", "()Ljava/lang/String;");
              QJniObject authority;
              if(jScheme.isValid())
              {
                  authority = jUri.callObjectMethod("getAuthority", "()Ljava/lang/String;");
              }
              if(authority.isValid() && authority.toString() == "com.android.externalstorage.documents")
              {
                  QJniObject jPath = jUri.callObjectMethod("getPath", "()Ljava/lang/String;");
                  path = jPath.toString();
              }
              else if(jCursor.isValid() && jCursor.callMethod<jboolean>("moveToFirst"))
              {
                  QJniObject jColumnIndex = QJniObject::fromString("_data");
                  jint columnIndex = jCursor.callMethod<jint>("getColumnIndexOrThrow", "(Ljava/lang/String;)I", jColumnIndex.object<jstring>());
                  QJniObject jRealPath = jCursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex);
                  path = jRealPath.toString();
                  if(authority.isValid() && authority.toString().startsWith("com.android.providers") && !url.toString().startsWith("content://media/external/"))
                  {
                      QStringList list = path.split(":");
                      if(list.count() == 2)
                      {
                          QString type = list.at(0);
                          QString id = list.at(1);
                          if(type == "image")
                              type = type + "s";
                          if(type == "document" || type == "documents")
                              type = "file";
                          if(type == "msf")
                              type = "downloads";
                          if(QList<QString>({"images","video","audio"}).contains(type))
                              type = type + "/media";
                          path = "content://media/external/"+type;
                          path = path + "/" + id;
                          return getRealPathFromUri(path);
                      }
                  }
              }
              else
              {
                  QJniObject jPath = jUri.callObjectMethod("getPath", "()Ljava/lang/String;");
                  path = jPath.toString();
              }
          
              if(path.startsWith("primary:"))
              {
                  path = path.remove(0,QString("primary:").length());
                  path = "/sdcard/" + path;
              }
              else if(path.startsWith("/document/primary:"))
              {
                  path = path.remove(0,QString("/document/primary:").length());
                  path = "/sdcard/" + path;
              }
              else if(path.startsWith("/tree/primary:"))
              {
                  path = path.remove(0,QString("/tree/primary:").length());
                  path = "/sdcard/" + path;
              }
              else if(path.startsWith("/storage/emulated/0/"))
              {
                  path = path.remove(0,QString("/storage/emulated/0/").length());
                  path = "/sdcard/" + path;
              }
              else if(path.startsWith("/tree//"))
              {
                  path = path.remove(0,QString("/tree//").length());
                  path = "/" + path;
              }
              if(!QFileInfo(path).isFile() && !QFileInfo(path).isDir() && !path.startsWith("/data"))
                  return url.toString();
              return path;
          #else
              return url.toString();
          #endif
          
          }
          
          ekkescornerE 1 Reply Last reply
          0
          • S Soviet-Ball

            @HemantSuryawanshi
            Hi,
            maybe you can try this function below.

            static QString getRealPathFromUri(const QUrl &url)
            {
                QString path = "";
            
                QFileInfo info = QFileInfo(url.toString());
                if(info.isFile())
                {
                    QString abs = QFileInfo(url.toString()).absoluteFilePath();
                    if(!abs.isEmpty() && abs != url.toString() && QFileInfo(abs).isFile())
                    {
                        return abs;
                    }
                }
                else if(info.isDir())
                {
                    QString abs = QFileInfo(url.toString()).absolutePath();
                    if(!abs.isEmpty() && abs != url.toString() && QFileInfo(abs).isDir())
                    {
                        return abs;
                    }
                }
                QString localfile = url.toLocalFile();
                if((QFileInfo(localfile).isFile() || QFileInfo(localfile).isDir()) && localfile != url.toString())
                {
                    return localfile;
                }
            #ifdef Q_OS_ANDROID
                QJniObject jUrl = QJniObject::fromString(url.toString());
                QJniObject jContext = QtAndroidPrivate::context();
                QJniObject jContentResolver = jContext.callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;");
                QJniObject jUri = QJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", jUrl.object<jstring>());
                QJniObject jCursor = jContentResolver.callObjectMethod("query", "(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;", jUri.object<jobject>(), nullptr, nullptr, nullptr, nullptr);
                QJniObject jScheme = jUri.callObjectMethod("getScheme", "()Ljava/lang/String;");
                QJniObject authority;
                if(jScheme.isValid())
                {
                    authority = jUri.callObjectMethod("getAuthority", "()Ljava/lang/String;");
                }
                if(authority.isValid() && authority.toString() == "com.android.externalstorage.documents")
                {
                    QJniObject jPath = jUri.callObjectMethod("getPath", "()Ljava/lang/String;");
                    path = jPath.toString();
                }
                else if(jCursor.isValid() && jCursor.callMethod<jboolean>("moveToFirst"))
                {
                    QJniObject jColumnIndex = QJniObject::fromString("_data");
                    jint columnIndex = jCursor.callMethod<jint>("getColumnIndexOrThrow", "(Ljava/lang/String;)I", jColumnIndex.object<jstring>());
                    QJniObject jRealPath = jCursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex);
                    path = jRealPath.toString();
                    if(authority.isValid() && authority.toString().startsWith("com.android.providers") && !url.toString().startsWith("content://media/external/"))
                    {
                        QStringList list = path.split(":");
                        if(list.count() == 2)
                        {
                            QString type = list.at(0);
                            QString id = list.at(1);
                            if(type == "image")
                                type = type + "s";
                            if(type == "document" || type == "documents")
                                type = "file";
                            if(type == "msf")
                                type = "downloads";
                            if(QList<QString>({"images","video","audio"}).contains(type))
                                type = type + "/media";
                            path = "content://media/external/"+type;
                            path = path + "/" + id;
                            return getRealPathFromUri(path);
                        }
                    }
                }
                else
                {
                    QJniObject jPath = jUri.callObjectMethod("getPath", "()Ljava/lang/String;");
                    path = jPath.toString();
                }
            
                if(path.startsWith("primary:"))
                {
                    path = path.remove(0,QString("primary:").length());
                    path = "/sdcard/" + path;
                }
                else if(path.startsWith("/document/primary:"))
                {
                    path = path.remove(0,QString("/document/primary:").length());
                    path = "/sdcard/" + path;
                }
                else if(path.startsWith("/tree/primary:"))
                {
                    path = path.remove(0,QString("/tree/primary:").length());
                    path = "/sdcard/" + path;
                }
                else if(path.startsWith("/storage/emulated/0/"))
                {
                    path = path.remove(0,QString("/storage/emulated/0/").length());
                    path = "/sdcard/" + path;
                }
                else if(path.startsWith("/tree//"))
                {
                    path = path.remove(0,QString("/tree//").length());
                    path = "/" + path;
                }
                if(!QFileInfo(path).isFile() && !QFileInfo(path).isDir() && !path.startsWith("/data"))
                    return url.toString();
                return path;
            #else
                return url.toString();
            #endif
            
            }
            
            ekkescornerE Offline
            ekkescornerE Offline
            ekkescorner
            Qt Champions 2016
            wrote on last edited by
            #5

            @Soviet-Ball you don't need this anmore in Qt 6.6:
            FileDialog on Android supports content URLs.

            QFileInfo().fileName()
            

            gives you the file path
            so easy now :)

            ekke ... Qt Champion 2016 | 2024 ... mobile business apps
            5.15 --> 6.8 https://t1p.de/ekkeChecklist
            QMake --> CMake https://t1p.de/ekkeCMakeMobileApps

            1 Reply Last reply
            1

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved