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 return QStringList(type.name()) + type.aliases();
154 const QStringList mimeTypeFilters = options()->mimeTypeFilters();
155 const QStringList nameFilters = options()->nameFilters();
156 QStringList mimeTypes;
157 mimeTypes.reserve(mimeTypeFilters.size() + nameFilters.size());
158 for (
const QString &filter : mimeTypeFilters) {
159 const QMimeType type = db.mimeTypeForName(filter);
161 mimeTypes.append(mimeTypeNames(type));
163 mimeTypes.append(filter);
166 if (!nameFilters.isEmpty()) {
167 for (
auto filter : nameFilters) {
168 if (!filter.isEmpty()) {
169 for (
const QString &filter : nameFilterExtensions(filter)) {
170 const QMimeType type =
171 db.mimeTypeForFile(filter, QMimeDatabase::MatchExtension);
172 mimeTypes.append(mimeTypeNames(type));
177 mimeTypes.removeDuplicates();
179 const QString initialType = mimeTypes.size() == 1 ? mimeTypes.at(0) :
"*/*"_L1;
180 m_intent.callObjectMethod(
"setType",
"(Ljava/lang/String;)Landroid/content/Intent;",
181 QJniObject::fromString(initialType).object());
183 if (!mimeTypes.isEmpty()) {
184 const QJniObject extraMimeType = QJniObject::getStaticObjectField(
185 JniIntentClass,
"EXTRA_MIME_TYPES",
"Ljava/lang/String;");
187 const QJniObject mimeTypesArray = QJniObject::callStaticObjectMethod(
188 "org/qtproject/qt/android/QtNative",
190 "(Ljava/lang/String;)[Ljava/lang/String;",
191 QJniObject::fromString(mimeTypes.join(
",")).object());
193 m_intent.callObjectMethod(
194 "putExtra",
"(Ljava/lang/String;[Ljava/lang/String;)Landroid/content/Intent;",
195 extraMimeType.object(), mimeTypesArray.object());
201 const QJniObject ACTION_OPEN_DOCUMENT = QJniObject::getStaticObjectField(
202 JniIntentClass, intentType.toLatin1(),
"Ljava/lang/String;");
204 ACTION_OPEN_DOCUMENT.object());
209 Q_UNUSED(windowFlags);
210 Q_UNUSED(windowModality);
213 bool isDirDialog =
false;
215 m_selectedFile.clear();
217 if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
218 m_intent = getFileDialogIntent(
"ACTION_CREATE_DOCUMENT");
219 const QList<QUrl> selectedFiles = options()->initiallySelectedFiles();
220 if (selectedFiles.size() > 0)
221 setInitialFileName(selectedFiles.first().fileName());
222 }
else if (options()->acceptMode() == QFileDialogOptions::AcceptOpen) {
223 switch (options()->fileMode()) {
224 case QFileDialogOptions::FileMode::DirectoryOnly:
225 case QFileDialogOptions::FileMode::Directory:
226 m_intent = getFileDialogIntent(
"ACTION_OPEN_DOCUMENT_TREE");
229 case QFileDialogOptions::FileMode::ExistingFiles:
230 m_intent = getFileDialogIntent(
"ACTION_OPEN_DOCUMENT");
231 setAllowMultipleSelections(
true);
233 case QFileDialogOptions::FileMode::AnyFile:
234 case QFileDialogOptions::FileMode::ExistingFile:
235 m_intent = getFileDialogIntent(
"ACTION_OPEN_DOCUMENT");
241 setOpenableCategory();
245 setInitialDirectoryUri(m_directory.toString());
247 QtAndroidPrivate::registerActivityResultListener(
this);
248 m_activity.callMethod<
void>(
"startActivityForResult",
"(Landroid/content/Intent;I)V",
255 if (m_eventLoop.isRunning())
257 QtAndroidPrivate::unregisterActivityResultListener(
this);
262 m_directory = directory;
267 m_eventLoop.exec(QEventLoop::DialogExec);