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
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
27 // Qt applications without Activity contexts cannot retrieve intents from the Activity.
28 if (QNativeInterface::QAndroidApplication::isActivityContext()) {
30 this,
31 [this] {
33 QJniObject intent =
34 context.callObjectMethod("getIntent", "()Landroid/content/Intent;");
35 handleNewIntent(nullptr, intent.object());
36 },
38 }
39}
40
41Q_DECLARE_JNI_CLASS(UriType, "android/net/Uri")
42Q_DECLARE_JNI_CLASS(FileType, "java/io/File")
43Q_DECLARE_JNI_CLASS(File, "java/io/File")
44Q_DECLARE_JNI_CLASS(FileProvider, "androidx/core/content/FileProvider");
45
46bool QAndroidPlatformServices::openUrl(const QUrl &theUrl)
47{
49 QUrl url(theUrl);
50
51 // avoid recursing back into self
52 if (url == m_handlingUrl)
53 return false;
54
55 // if the file is local, we need to pass the MIME type, otherwise Android
56 // does not start an Intent to view this file
57 const auto fileScheme = "file"_L1;
58
59 // a real URL including the scheme is needed, else the Intent can not be started
60 if (url.scheme().isEmpty())
62
63 if (url.scheme() == fileScheme)
65
66 const QJniObject mimeString = QJniObject::fromString(mime);
67
68 using namespace QNativeInterface;
69
70 auto openUrl = [mimeString](const QJniObject &url) {
71 return QJniObject::callStaticMethod<jboolean>(QtAndroid::applicationClass(), "openURL",
72 QAndroidApplication::context(), url.object<jstring>(), mimeString.object<jstring>());
73 };
74
75 if (url.scheme() != fileScheme || QNativeInterface::QAndroidApplication::sdkVersion() < 24)
76 return openUrl(QJniObject::fromString(url.toString()));
77
78 // Use FileProvider for file scheme with sdk >= 24
79 const QJniObject context = QAndroidApplication::context();
80 const auto appId = context.callMethod<jstring>("getPackageName").toString();
81 const auto providerName = QJniObject::fromString(appId + ".qtprovider"_L1);
82
83 const auto urlPath = QJniObject::fromString(url.path());
84 const auto urlFile = QJniObject(QtJniTypes::Traits<QtJniTypes::File>::className(),
85 urlPath.object<jstring>());
86
87 const auto fileProviderUri = QJniObject::callStaticMethod<QtJniTypes::UriType>(
88 QtJniTypes::Traits<QtJniTypes::FileProvider>::className(), "getUriForFile",
89 QAndroidApplication::context(), providerName.object<jstring>(),
90 urlFile.object<QtJniTypes::FileType>());
91
92 if (fileProviderUri.isValid())
93 return openUrl(fileProviderUri.callMethod<jstring>("toString"));
94
95 return false;
96}
97
99{
100 return openUrl(url);
101}
102
107
108bool QAndroidPlatformServices::handleNewIntent(JNIEnv *env, jobject intent)
109{
110 Q_UNUSED(env);
111
112 const QJniObject jniIntent(intent);
113
114 const QString action = jniIntent.callObjectMethod<jstring>("getAction").toString();
115 if (action != m_actionView)
116 return false;
117
118 const QString url = jniIntent.callObjectMethod<jstring>("getDataString").toString();
119 QScopedValueRollback<QUrl> rollback(m_handlingUrl, url);
121}
122
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:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
\inmodule QtCore
Definition qurl.h:94
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1991
void setScheme(const QString &scheme)
Sets the scheme of the URL to scheme.
Definition qurl.cpp:1967
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2831
QString path(ComponentFormattingOptions options=FullyDecoded) const
Returns the path of the URL.
Definition qurl.cpp:2468
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")
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#define Q_UNUSED(x)
static QString fileScheme()
Definition qurl.cpp:425
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...