How to get file path from fileurl in qt android
Unsolved
Mobile and Embedded
-
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.
-
@HemantSuryawanshi
I don't know anything about Android, but did you try passing that string toQFile()
directly? Or, what about viaQString QUrl::toLocalFile() const
? Just a thought, may not help.... -
@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 }
-
@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 :)