diff options
Diffstat (limited to 'src/plugins/platforms/android/qandroidplatformservices.cpp')
-rw-r--r-- | src/plugins/platforms/android/qandroidplatformservices.cpp | 58 |
1 files changed, 43 insertions, 15 deletions
diff --git a/src/plugins/platforms/android/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp index 2599fe6db2..34edc64751 100644 --- a/src/plugins/platforms/android/qandroidplatformservices.cpp +++ b/src/plugins/platforms/android/qandroidplatformservices.cpp @@ -24,17 +24,22 @@ QAndroidPlatformServices::QAndroidPlatformServices() QtAndroidPrivate::registerNewIntentListener(this); - QMetaObject::invokeMethod( - this, - [this] { - QJniObject context = QJniObject(QtAndroidPrivate::context()); - QJniObject intent = - context.callObjectMethod("getIntent", "()Landroid/content/Intent;"); - handleNewIntent(nullptr, intent.object()); - }, - Qt::QueuedConnection); + // Qt applications without Activity contexts cannot retrieve intents from the Activity. + if (QNativeInterface::QAndroidApplication::isActivityContext()) { + QMetaObject::invokeMethod( + this, + [this] { + QJniObject context = QJniObject(QtAndroidPrivate::context()); + QJniObject intent = + context.callObjectMethod("getIntent", "()Landroid/content/Intent;"); + handleNewIntent(nullptr, intent.object()); + }, + Qt::QueuedConnection); + } } +Q_DECLARE_JNI_CLASS(FileProvider, "androidx/core/content/FileProvider"); + bool QAndroidPlatformServices::openUrl(const QUrl &theUrl) { QString mime; @@ -55,13 +60,36 @@ bool QAndroidPlatformServices::openUrl(const QUrl &theUrl) if (url.scheme() == fileScheme) mime = QMimeDatabase().mimeTypeForUrl(url).name(); + const QJniObject mimeString = QJniObject::fromString(mime); + using namespace QNativeInterface; - QJniObject urlString = QJniObject::fromString(url.toString()); - QJniObject mimeString = QJniObject::fromString(mime); - return QJniObject::callStaticMethod<jboolean>( - QtAndroid::applicationClass(), "openURL", - "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Z", - QAndroidApplication::context(), urlString.object(), mimeString.object()); + + auto openUrl = [mimeString](const QJniObject &url) { + return QJniObject::callStaticMethod<jboolean>(QtAndroid::applicationClass(), "openURL", + QAndroidApplication::context(), url.object<jstring>(), mimeString.object<jstring>()); + }; + + if (url.scheme() != fileScheme || QNativeInterface::QAndroidApplication::sdkVersion() < 24) + return openUrl(QJniObject::fromString(url.toString())); + + // Use FileProvider for file scheme with sdk >= 24 + const QJniObject context = QAndroidApplication::context(); + const auto appId = context.callMethod<jstring>("getPackageName").toString(); + const auto providerName = QJniObject::fromString(appId + ".qtprovider"_L1); + + const auto urlPath = QJniObject::fromString(url.path()); + const auto urlFile = QJniObject(QtJniTypes::Traits<QtJniTypes::File>::className(), + urlPath.object<jstring>()); + + const auto fileProviderUri = QJniObject::callStaticMethod<QtJniTypes::Uri>( + QtJniTypes::Traits<QtJniTypes::FileProvider>::className(), "getUriForFile", + QAndroidApplication::context(), providerName.object<jstring>(), + urlFile.object<QtJniTypes::File>()); + + if (fileProviderUri.isValid()) + return openUrl(fileProviderUri.callMethod<jstring>("toString")); + + return false; } bool QAndroidPlatformServices::openDocument(const QUrl &url) |