Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qstandardpaths_android.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qstandardpaths.h"
5
6#ifndef QT_NO_STANDARDPATHS
7
8#include <QtCore/qjniobject.h>
9#include <QtCore/qmap.h>
10#include <QtCore/qcoreapplication.h>
11#include <QDir>
12
14
15Q_DECLARE_JNI_CLASS(Environment, "android/os/Environment");
16Q_DECLARE_JNI_CLASS(File, "java/io/File");
17
18using namespace QNativeInterface;
19using namespace Qt::StringLiterals;
20
21typedef QMap<QString, QString> AndroidDirCache;
22Q_GLOBAL_STATIC(AndroidDirCache, androidDirCache)
23
25{
26 return QStandardPaths::isTestModeEnabled() ? "/qttest"_L1 : ""_L1;
27}
28
30{
31 QJniObject path = file.callMethod<jstring>("getAbsolutePath");
32
33 if (!path.isValid())
34 return QString();
35
36 return path.toString();
37}
38
39/*
40 * The root of the external storage
41 *
42 */
44{
45 QString &path = (*androidDirCache)[QStringLiteral("EXT_ROOT")];
46 if (!path.isEmpty())
47 return path;
48
49 QJniObject file = QJniObject::callStaticMethod<QtJniTypes::File>("android/os/Environment",
50 "getExternalStorageDirectory");
51 if (!file.isValid())
52 return QString();
53
54 return (path = getAbsolutePath(file));
55}
56
57/*
58 * Locations where applications can place user files shared by all apps (public).
59 * E.g., /storage/Music
60 */
61static QString getExternalStoragePublicDirectory(const char *directoryField)
62{
63 QString &path = (*androidDirCache)[QLatin1String(directoryField)];
64 if (!path.isEmpty())
65 return path;
66
67 QJniObject dirField = QJniObject::getStaticField<jstring>("android/os/Environment",
68 directoryField);
69 if (!dirField.isValid())
70 return QString();
71
72 QJniObject file = QJniObject::callStaticMethod<QtJniTypes::File>("android/os/Environment",
73 "getExternalStoragePublicDirectory",
74 dirField.object<jstring>());
75 if (!file.isValid())
76 return QString();
77
78 return (path = getAbsolutePath(file));
79}
80
81/*
82 * Locations where applications can place persistent files it owns.
83 * E.g., /storage/org.app/Music
84 */
85static QString getExternalFilesDir(const char *directoryField = nullptr)
86{
87 QString &path = (*androidDirCache)["APPNAME_%1"_L1.arg(QLatin1StringView(directoryField))];
88 if (!path.isEmpty())
89 return path;
90
91 QJniObject appCtx = QAndroidApplication::context();
92 if (!appCtx.isValid())
93 return QString();
94
95 QJniObject dirField = QJniObject::fromString(""_L1);
96 if (directoryField && strlen(directoryField) > 0) {
97 dirField = QJniObject::getStaticField<QtJniTypes::Environment, jstring>(directoryField);
98 if (!dirField.isValid())
99 return QString();
100 }
101
102 QJniObject file = appCtx.callMethod<QtJniTypes::File>("getExternalFilesDir",
103 dirField.object<jstring>());
104
105 if (!file.isValid())
106 return QString();
107
108 return (path = getAbsolutePath(file));
109}
110
111/*
112 * Directory where applications can store cache files it owns (public).
113 * E.g., /storage/org.app/
114 */
116{
117 QString &path = (*androidDirCache)[QStringLiteral("APPNAME_CACHE")];
118 if (!path.isEmpty())
119 return path;
120
121 QJniObject appCtx = QAndroidApplication::context();
122 if (!appCtx.isValid())
123 return QString();
124
125 QJniObject file = appCtx.callMethod<QtJniTypes::File>("getExternalCacheDir");
126
127 if (!file.isValid())
128 return QString();
129
130 return (path = getAbsolutePath(file));
131}
132
133/*
134 * Directory where applications can store cache files it owns (private).
135 */
137{
138 QString &path = (*androidDirCache)[QStringLiteral("APPROOT_CACHE")];
139 if (!path.isEmpty())
140 return path;
141
142 QJniObject appCtx = QAndroidApplication::context();
143 if (!appCtx.isValid())
144 return QString();
145
146 QJniObject file = appCtx.callMethod<QtJniTypes::File>("getCacheDir");
147 if (!file.isValid())
148 return QString();
149
150 return (path = getAbsolutePath(file));
151}
152
153/*
154 * Directory where applications can store files it owns (private).
155 * (Same location as $HOME)
156 */
158{
159 QString &path = (*androidDirCache)[QStringLiteral("APPROOT_FILES")];
160 if (!path.isEmpty())
161 return path;
162
163 QJniObject appCtx = QAndroidApplication::context();
164 if (!appCtx.isValid())
165 return QString();
166
167 QJniObject file = appCtx.callMethod<QtJniTypes::File>("getFilesDir");
168 if (!file.isValid())
169 return QString();
170
171 return (path = getAbsolutePath(file));
172}
173
174static QString getSdkBasedExternalDir(const char *directoryField = nullptr)
175{
176 return (QNativeInterface::QAndroidApplication::sdkVersion() >= 30)
177 ? getExternalFilesDir(directoryField)
178 : getExternalStoragePublicDirectory(directoryField);
179}
180
182{
183 switch (type) {
185 return getSdkBasedExternalDir("DIRECTORY_MUSIC");
187 return getSdkBasedExternalDir("DIRECTORY_MOVIES");
189 return getSdkBasedExternalDir("DIRECTORY_PICTURES");
191 return getSdkBasedExternalDir("DIRECTORY_DOCUMENTS");
193 return getSdkBasedExternalDir("DIRECTORY_DOWNLOADS");
197 return getFilesDir() + testDir() + "/settings"_L1;
200 return getFilesDir() + testDir() + "/state"_L1;
202 {
203 return QAndroidApplication::sdkVersion() >= 30 ?
205 }
208 return getFilesDir() + testDir();
213 return getCacheDir() + testDir();
216 return getFilesDir();
221 default:
222 break;
223 }
224
225 return QString();
226}
227
229{
231
232 if (type == MusicLocation) {
233 locations << getExternalFilesDir("DIRECTORY_MUSIC");
234 // Place the public dirs before the app own dirs
235 if (QNativeInterface::QAndroidApplication::sdkVersion() < 30) {
236 locations << getExternalStoragePublicDirectory("DIRECTORY_PODCASTS")
237 << getExternalStoragePublicDirectory("DIRECTORY_NOTIFICATIONS")
238 << getExternalStoragePublicDirectory("DIRECTORY_ALARMS");
239 }
240 locations << getExternalFilesDir("DIRECTORY_PODCASTS")
241 << getExternalFilesDir("DIRECTORY_NOTIFICATIONS")
242 << getExternalFilesDir("DIRECTORY_ALARMS");
243 } else if (type == MoviesLocation) {
244 locations << getExternalFilesDir("DIRECTORY_MOVIES");
245 } else if (type == PicturesLocation) {
246 locations << getExternalFilesDir("DIRECTORY_PICTURES");
247 } else if (type == DocumentsLocation) {
248 locations << getExternalFilesDir("DIRECTORY_DOCUMENTS");
249 } else if (type == DownloadLocation) {
250 locations << getExternalFilesDir("DIRECTORY_DOWNLOADS");
251 } else if (type == AppDataLocation || type == AppLocalDataLocation) {
253 } else if (type == CacheLocation) {
255 } else if (type == FontsLocation) {
256 QString &fontLocation = (*androidDirCache)[QStringLiteral("FONT_LOCATION")];
257 if (!fontLocation.isEmpty()) {
258 locations << fontLocation;
259 } else {
260 const QByteArray ba = qgetenv("QT_ANDROID_FONT_LOCATION");
261 if (!ba.isEmpty()) {
263 } else {
264 // Don't cache the fallback, as we might just have been called before
265 // QT_ANDROID_FONT_LOCATION has been set.
266 locations << "/system/fonts"_L1;
267 }
268 }
269 }
270
271 const QString writable = writableLocation(type);
272 if (!writable.isEmpty())
273 locations.prepend(writable);
274
275 locations.removeDuplicates();
276 return locations;
277}
278
280
281#endif // QT_NO_STANDARDPATHS
\inmodule QtCore
Definition qbytearray.h:57
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
static QString cleanPath(const QString &path)
Returns path with directory separators normalized (that is, platform-native separators converted to "...
Definition qdir.cpp:2398
\inmodule QtCore
static bool isTestModeEnabled()
static QStringList standardLocations(StandardLocation type)
static QString writableLocation(StandardLocation type)
StandardLocation
This enum describes the different locations that can be queried using methods such as QStandardPaths:...
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5949
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
Combined button and popup list for selecting options.
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
GLenum type
GLsizei const GLchar *const * path
GLuint const GLint * locations
static QString getExternalCacheDir()
static QString getExternalStorageDirectory()
static QString getExternalFilesDir(const char *directoryField=nullptr)
static QString getSdkBasedExternalDir(const char *directoryField=nullptr)
static QString getExternalStoragePublicDirectory(const char *directoryField)
static QString getAbsolutePath(const QJniObject &file)
QT_BEGIN_NAMESPACE Q_DECLARE_JNI_CLASS(Environment, "android/os/Environment")
QMap< QString, QString > AndroidDirCache
static QString getCacheDir()
static QString getFilesDir()
static QString testDir()
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
QByteArray ba
[0]
QFile file
[0]