23#define REQUEST_CODE 1305
28 : QPlatformFileDialogHelper(),
29 m_activity(QtAndroidPrivate::activity())
43 const QJniObject intent = QJniObject::fromLocalRef(data);
45 const QJniObject uri = intent.callObjectMethod(
"getData",
"()Landroid/net/Uri;");
47 takePersistableUriPermission(uri);
48 m_selectedFile.append(QUrl(uri.toString()));
49 Q_EMIT fileSelected(m_selectedFile.constFirst());
50 Q_EMIT currentChanged(m_selectedFile.constFirst());
56 const QJniObject uriClipData =
57 intent.callObjectMethod(
"getClipData",
"()Landroid/content/ClipData;");
58 if (uriClipData.isValid()) {
59 const int size = uriClipData.callMethod<jint>(
"getItemCount");
60 for (
int i = 0; i < size; ++i) {
61 QJniObject item = uriClipData.callObjectMethod(
62 "getItemAt",
"(I)Landroid/content/ClipData$Item;", i);
64 QJniObject itemUri = item.callObjectMethod(
"getUri",
"()Landroid/net/Uri;");
65 takePersistableUriPermission(itemUri);
66 m_selectedFile.append(itemUri.toString());
68 Q_EMIT filesSelected(m_selectedFile);
69 Q_EMIT currentChanged(m_selectedFile.constFirst());
78 int modeFlags = QJniObject::getStaticField<jint>(
79 JniIntentClass,
"FLAG_GRANT_READ_URI_PERMISSION");
81 if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
82 modeFlags |= QJniObject::getStaticField<jint>(
83 JniIntentClass,
"FLAG_GRANT_WRITE_URI_PERMISSION");
86 QJniObject contentResolver = m_activity.callObjectMethod(
87 "getContentResolver",
"()Landroid/content/ContentResolver;");
88 contentResolver.callMethod<
void>(
"takePersistableUriPermission",
"(Landroid/net/Uri;I)V",
89 uri.object(), modeFlags);
94 const QJniObject extraTitle = QJniObject::getStaticObjectField(
95 JniIntentClass,
"EXTRA_TITLE",
"Ljava/lang/String;");
96 m_intent.callObjectMethod(
"putExtra",
97 "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
98 extraTitle.object(), QJniObject::fromString(title).object());
103 if (directory.isEmpty())
106 if (QNativeInterface::QAndroidApplication::sdkVersion() < 26)
109 const auto extraInitialUri = QJniObject::getStaticObjectField(
110 "android/provider/DocumentsContract",
"EXTRA_INITIAL_URI",
"Ljava/lang/String;");
111 m_intent.callObjectMethod(
"putExtra",
112 "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
113 extraInitialUri.object(),
114 QJniObject::fromString(directory).object());
119 const QJniObject CATEGORY_OPENABLE = QJniObject::getStaticObjectField(
120 JniIntentClass,
"CATEGORY_OPENABLE",
"Ljava/lang/String;");
121 m_intent.callObjectMethod(
"addCategory",
"(Ljava/lang/String;)Landroid/content/Intent;",
122 CATEGORY_OPENABLE.object());
127 const QJniObject allowMultipleSelections = QJniObject::getStaticObjectField(
128 JniIntentClass,
"EXTRA_ALLOW_MULTIPLE",
"Ljava/lang/String;");
129 m_intent.callObjectMethod(
"putExtra",
"(Ljava/lang/String;Z)Landroid/content/Intent;",
130 allowMultipleSelections.object(), allowMultiple);
136#if QT_CONFIG(regularexpression)
137 QRegularExpression re(
"(\\*\\.[a-z0-9 .]+)");
138 QRegularExpressionMatchIterator i = re.globalMatch(nameFilters);
140 ret << i.next().captured(1).trimmed();
148 QStringList mimeTypes = options()->mimeTypeFilters();
149 const QStringList nameFilters = options()->nameFilters();
151 if (!nameFilters.isEmpty()) {
153 for (
auto filter : nameFilters) {
154 if (!filter.isEmpty()) {
155 for (
const QString &filter : nameFilterExtensions(filter))
156 mimeTypes.append(db.mimeTypeForFile(filter, QMimeDatabase::MatchExtension).name());
161 const QString initialType = mimeTypes.size() == 1 ? mimeTypes.at(0) :
"*/*"_L1;
162 m_intent.callObjectMethod(
"setType",
"(Ljava/lang/String;)Landroid/content/Intent;",
163 QJniObject::fromString(initialType).object());
165 if (!mimeTypes.isEmpty()) {
166 const QJniObject extraMimeType = QJniObject::getStaticObjectField(
167 JniIntentClass,
"EXTRA_MIME_TYPES",
"Ljava/lang/String;");
169 const QJniObject mimeTypesArray = QJniObject::callStaticObjectMethod(
170 "org/qtproject/qt/android/QtNative",
172 "(Ljava/lang/String;)[Ljava/lang/String;",
173 QJniObject::fromString(mimeTypes.join(
",")).object());
175 m_intent.callObjectMethod(
176 "putExtra",
"(Ljava/lang/String;[Ljava/lang/String;)Landroid/content/Intent;",
177 extraMimeType.object(), mimeTypesArray.object());
183 const QJniObject ACTION_OPEN_DOCUMENT = QJniObject::getStaticObjectField(
184 JniIntentClass, intentType.toLatin1(),
"Ljava/lang/String;");
186 ACTION_OPEN_DOCUMENT.object());
191 Q_UNUSED(windowFlags);
192 Q_UNUSED(windowModality);
195 bool isDirDialog =
false;
197 m_selectedFile.clear();
199 if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
200 m_intent = getFileDialogIntent(
"ACTION_CREATE_DOCUMENT");
201 const QList<QUrl> selectedFiles = options()->initiallySelectedFiles();
202 if (selectedFiles.size() > 0)
203 setInitialFileName(selectedFiles.first().fileName());
204 }
else if (options()->acceptMode() == QFileDialogOptions::AcceptOpen) {
205 switch (options()->fileMode()) {
206 case QFileDialogOptions::FileMode::DirectoryOnly:
207 case QFileDialogOptions::FileMode::Directory:
208 m_intent = getFileDialogIntent(
"ACTION_OPEN_DOCUMENT_TREE");
211 case QFileDialogOptions::FileMode::ExistingFiles:
212 m_intent = getFileDialogIntent(
"ACTION_OPEN_DOCUMENT");
213 setAllowMultipleSelections(
true);
215 case QFileDialogOptions::FileMode::AnyFile:
216 case QFileDialogOptions::FileMode::ExistingFile:
217 m_intent = getFileDialogIntent(
"ACTION_OPEN_DOCUMENT");
223 setOpenableCategory();
227 setInitialDirectoryUri(m_directory.toString());
229 QtAndroidPrivate::registerActivityResultListener(
this);
230 m_activity.callMethod<
void>(
"startActivityForResult",
"(Landroid/content/Intent;I)V",
237 if (m_eventLoop.isRunning())
239 QtAndroidPrivate::unregisterActivityResultListener(
this);
244 m_directory = directory;
249 m_eventLoop.exec(QEventLoop::DialogExec);