Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qandroidplatformservices.cpp
Go to the documentation of this file.
1// Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
2// Copyright (C) 2021 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
6
7#include <QDebug>
8#include <QDesktopServices>
9#include <QFile>
10#include <QMimeDatabase>
11#include <QtCore/QJniObject>
12#include <QtCore/qcoreapplication.h>
13#include <QtCore/qscopedvaluerollback.h>
14
16
17using namespace Qt::StringLiterals;
18
20{
21 m_actionView = QJniObject::getStaticObjectField("android/content/Intent", "ACTION_VIEW",
22 "Ljava/lang/String;")
23 .toString();
24
26
28 this,
29 [this] {
31 QJniObject intent =
32 context.callObjectMethod("getIntent", "()Landroid/content/Intent;");
33 handleNewIntent(nullptr, intent.object());
34 },
36}
37
38Q_DECLARE_JNI_TYPE(UriType, "Landroid/net/Uri;")
39Q_DECLARE_JNI_TYPE(FileType, "Ljava/io/File;")
40Q_DECLARE_JNI_CLASS(File, "java/io/File")
41Q_DECLARE_JNI_CLASS(FileProvider, "androidx/core/content/FileProvider");
42
43bool QAndroidPlatformServices::openUrl(const QUrl &theUrl)
44{
46 QUrl url(theUrl);
47
48 // avoid recursing back into self
49 if (url == m_handlingUrl)
50 return false;
51
52 // if the file is local, we need to pass the MIME type, otherwise Android
53 // does not start an Intent to view this file
54 const auto fileScheme = "file"_L1;
55
56 // a real URL including the scheme is needed, else the Intent can not be started
57 if (url.scheme().isEmpty())
59
60 if (url.scheme() == fileScheme)
62
63 const QJniObject mimeString = QJniObject::fromString(mime);
64
65 using namespace QNativeInterface;
66
67 auto openUrl = [mimeString](const QJniObject &url) {
68 return QJniObject::callStaticMethod<jboolean>(QtAndroid::applicationClass(), "openURL",
69 QAndroidApplication::context(), url.object<jstring>(), mimeString.object<jstring>());
70 };
71
72 if (url.scheme() != fileScheme || QNativeInterface::QAndroidApplication::sdkVersion() < 24)
73 return openUrl(QJniObject::fromString(url.toString()));
74
75 // Use FileProvider for file scheme with sdk >= 24
76 const QJniObject context = QAndroidApplication::context();
77 const auto appId = context.callMethod<jstring>("getPackageName").toString();
78 const auto providerName = QJniObject::fromString(appId + ".qtprovider"_L1);
79
80 const auto urlPath = QJniObject::fromString(url.path());
81 const auto urlFile = QJniObject(QtJniTypes::className<QtJniTypes::File>(),
82 urlPath.object<jstring>());
83
84 const auto fileProviderUri = QJniObject::callStaticMethod<QtJniTypes::UriType>(
85 QtJniTypes::className<QtJniTypes::FileProvider>(), "getUriForFile",
86 QAndroidApplication::context(), providerName.object<jstring>(),
87 urlFile.object<QtJniTypes::FileType>());
88
89 if (fileProviderUri.isValid())
90 return openUrl(fileProviderUri.callMethod<jstring>("toString"));
91
92 return false;
93}
94
96{
97 return openUrl(url);
98}
99
101{
102 return QByteArray("Android");
103}
104
105bool QAndroidPlatformServices::handleNewIntent(JNIEnv *env, jobject intent)
106{
107 Q_UNUSED(env);
108
109 const QJniObject jniIntent(intent);
110
111 const QString action = jniIntent.callObjectMethod<jstring>("getAction").toString();
112 if (action != m_actionView)
113 return false;
114
115 const QString url = jniIntent.callObjectMethod<jstring>("getDataString").toString();
116 QScopedValueRollback<QUrl> rollback(m_handlingUrl, url);
118}
119
QByteArray desktopEnvironment() const override
QPlatformServices::desktopEnvironment returns the active desktop environment.
bool handleNewIntent(JNIEnv *env, jobject intent) override
bool openDocument(const QUrl &url) override
bool openUrl(const QUrl &url) override
\inmodule QtCore
Definition qbytearray.h:57
static bool openUrl(const QUrl &url)
Opens the given url in the appropriate Web browser for the user's desktop environment,...
\inmodule QtCore
\inmodule QtCore
QMimeType mimeTypeForUrl(const QUrl &url) const
Returns a MIME type for url.
QString name
the name of the MIME type
Definition qmimetype.h:29
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
\inmodule QtCore
Definition qurl.h:94
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1983
void setScheme(const QString &scheme)
Sets the scheme of the URL to scheme.
Definition qurl.cpp:1959
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2828
QString path(ComponentFormattingOptions options=FullyDecoded) const
Returns the path of the URL.
Definition qurl.cpp:2465
Combined button and popup list for selecting options.
Q_CORE_EXPORT void registerNewIntentListener(NewIntentListener *listener)
Q_CORE_EXPORT QtJniTypes::Context context()
jclass applicationClass()
@ QueuedConnection
static void * context
Q_DECLARE_JNI_CLASS(FileProvider, "androidx/core/content/FileProvider")
Q_DECLARE_JNI_TYPE(File, "Ljava/io/File;")
#define Q_UNUSED(x)
static QString fileScheme()
Definition qurl.cpp:423
QUrl url("example.com")
[constructor-url-reference]
application x qt windows mime
[2]
char * toString(const MyType &t)
[31]
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...