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
Forum Updated to NodeBB v4.3 + New Features

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.4k Views 1 Watching
  • 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 30 Sept 2020, 10:36 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.

    J 1 Reply Last reply 30 Sept 2020, 10:41
    0
    • H HemantSuryawanshi
      30 Sept 2020, 10:36

      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.

      J Offline
      J Offline
      JonB
      wrote on 30 Sept 2020, 10:41 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 30 Sept 2020, 11:08
      0
      • J JonB
        30 Sept 2020, 10:41

        @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 30 Sept 2020, 11:08 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 13 Apr 2024, 13:23 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
          
          }
          
          E 1 Reply Last reply 15 Apr 2024, 10:51
          0
          • S Soviet-Ball
            13 Apr 2024, 13:23

            @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
            
            }
            
            E Offline
            E Offline
            ekkescorner
            Qt Champions 2016
            wrote on 15 Apr 2024, 10:51 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