20#include "mauiandroid.h"
22#include <QCoreApplication>
29#include <QMimeDatabase>
33#include <android/bitmap.h>
35#define FLAG_TRANSLUCENT_STATUS 0x04000000
36#define FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS 0x80000000
38#define SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 0x00002000
39#define SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR 0x00000010
41class InterfaceConnFailedException :
public QException
48 InterfaceConnFailedException *clone()
const
50 return new InterfaceConnFailedException(*
this);
56MAUIAndroid::MAUIAndroid(
QObject *parent)
69static QAndroidJniObject getAndroidWindow()
71 QAndroidJniObject
window = QtAndroid::androidActivity().callObjectMethod(
"getWindow",
"()Landroid/view/Window;");
72 window.callMethod<
void>(
"addFlags",
"(I)V", FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
73 window.callMethod<
void>(
"clearFlags",
"(I)V", FLAG_TRANSLUCENT_STATUS);
79 if (QtAndroid::androidSdkVersion() <= 23)
82 QtAndroid::runOnAndroidThread([=]() {
83 QAndroidJniObject window = getAndroidWindow();
84 QAndroidJniObject view = window.callObjectMethod(
"getDecorView",
"()Landroid/view/View;");
85 int visibility = view.callMethod<
int>(
"getSystemUiVisibility",
"()I");
87 visibility |= SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
89 visibility &= ~SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
90 view.callMethod<
void>(
"setSystemUiVisibility",
"(I)V", visibility);
91 window.callMethod<
void>(
"setStatusBarColor",
"(I)V",
QColor(bg).
rgba());
97 if (QtAndroid::androidSdkVersion() <= 23)
100 QtAndroid::runOnAndroidThread([=]() {
101 QAndroidJniObject window = getAndroidWindow();
102 QAndroidJniObject view = window.callObjectMethod(
"getDecorView",
"()Landroid/view/View;");
103 int visibility = view.callMethod<
int>(
"getSystemUiVisibility",
"()I");
105 visibility |= SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
107 visibility &= ~SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
108 view.callMethod<
void>(
"setSystemUiVisibility",
"(I)V", visibility);
109 window.callMethod<
void>(
"setNavigationBarColor",
"(I)V",
QColor(bg).
rgba());
115 QAndroidJniEnvironment _env;
116 QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod(
"org/qtproject/qt5/android/QtNative",
"activity",
"()Landroid/app/Activity;");
117 if (_env->ExceptionCheck()) {
118 _env->ExceptionClear();
119 throw InterfaceConnFailedException();
125 if (activity.isValid())
127 qDebug() <<
"trying to share dialog << valid";
132 jobjectArray stringArray = _env->NewObjectArray(urls.
count(), _env->FindClass(
"java/lang/String"), NULL);
137 _env->SetObjectArrayElement(stringArray, ++index, QAndroidJniObject::fromString(url.toLocalFile()).object<jstring>());
140 QAndroidJniObject::callStaticMethod<void>(
"com/kde/maui/tools/SendIntent",
142 "(Landroid/app/Activity;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
143 activity.object<jobject>(),
144 QAndroidJniObject::fromLocalRef(stringArray).object<jobjectArray>(),
145 QAndroidJniObject::fromString(mimeType).object<jstring>(),
146 QAndroidJniObject::fromString(
QString(
"%1.fileprovider").arg(qApp->organizationDomain())).object<jstring>());
148 if (_env->ExceptionCheck())
150 qDebug() <<
"trying to share dialog << exception";
152 _env->ExceptionClear();
153 throw InterfaceConnFailedException();
156 throw InterfaceConnFailedException();
162 qDebug() <<
"trying to share text";
163 QAndroidJniEnvironment _env;
164 QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod(
"org/qtproject/qt5/android/QtNative",
"activity",
"()Landroid/app/Activity;");
165 if (_env->ExceptionCheck()) {
166 _env->ExceptionClear();
167 throw InterfaceConnFailedException();
169 if (activity.isValid()) {
170 QAndroidJniObject::callStaticMethod<void>(
"com/kde/maui/tools/SendIntent",
"sendText",
"(Landroid/app/Activity;Ljava/lang/String;)V", activity.object<jobject>(), QAndroidJniObject::fromString(text).object<jstring>());
172 if (_env->ExceptionCheck()) {
173 _env->ExceptionClear();
174 throw InterfaceConnFailedException();
177 throw InterfaceConnFailedException();
182 qDebug() <<
"trying to share link";
183 QAndroidJniEnvironment _env;
184 QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod(
"org/qtproject/qt5/android/QtNative",
"activity",
"()Landroid/app/Activity;");
185 if (_env->ExceptionCheck()) {
186 _env->ExceptionClear();
187 throw InterfaceConnFailedException();
189 if (activity.isValid()) {
190 QAndroidJniObject::callStaticMethod<void>(
"com/kde/maui/tools/SendIntent",
"sendUrl",
"(Landroid/app/Activity;Ljava/lang/String;)V", activity.object<jobject>(), QAndroidJniObject::fromString(link).object<jstring>());
192 if (_env->ExceptionCheck()) {
193 _env->ExceptionClear();
194 throw InterfaceConnFailedException();
197 throw InterfaceConnFailedException();
202 qDebug() <<
"trying to open file with";
203 QAndroidJniEnvironment _env;
204 QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod(
"org/qtproject/qt5/android/QtNative",
"activity",
"()Landroid/app/Activity;");
205 if (_env->ExceptionCheck()) {
206 _env->ExceptionClear();
207 throw InterfaceConnFailedException();
209 if (activity.isValid()) {
210 QAndroidJniObject::callStaticMethod<void>(
"com/kde/maui/tools/SendIntent",
212 "(Landroid/app/Activity;Ljava/lang/String;Ljava/lang/String;)V",
213 activity.object<jobject>(),
214 QAndroidJniObject::fromString(url.
toLocalFile()).object<jstring>(),
215 QAndroidJniObject::fromString(
QString(
"%1.fileprovider").arg(qApp->organizationDomain())).object<jstring>());
217 if (_env->ExceptionCheck()) {
218 _env->ExceptionClear();
219 throw InterfaceConnFailedException();
222 throw InterfaceConnFailedException();
227 QAndroidJniObject mediaDir = QAndroidJniObject::callStaticObjectMethod(
"android/os/Environment",
"getExternalStorageDirectory",
"()Ljava/io/File;");
228 QAndroidJniObject mediaPath = mediaDir.callObjectMethod(
"getAbsolutePath",
"()Ljava/lang/String;");
230 return mediaPath.toString();
262 QAndroidJniEnvironment _env;
263 QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod(
"org/qtproject/qt5/android/QtNative",
"activity",
"()Landroid/app/Activity;");
264 if (_env->ExceptionCheck()) {
265 _env->ExceptionClear();
266 throw InterfaceConnFailedException();
268 if (activity.isValid()) {
269 QAndroidJniObject::callStaticMethod<void>(
"com/example/android/tools/SendIntent",
"fileChooser",
"(Landroid/app/Activity;)V", activity.object<jobject>());
270 if (_env->ExceptionCheck()) {
271 _env->ExceptionClear();
272 throw InterfaceConnFailedException();
275 throw InterfaceConnFailedException();
278QVariantList MAUIAndroid::transform(
const QAndroidJniObject &obj)
281 const auto size = obj.callMethod<jint>(
"size",
"()I");
283 for (
auto i = 0; i < size; i++) {
284 QAndroidJniObject hashObj = obj.callObjectMethod(
"get",
"(I)Ljava/lang/Object;", i);
285 res << createVariantMap(hashObj.object<jobject>());
291QVariantMap MAUIAndroid::createVariantMap(jobject data)
295 QAndroidJniEnvironment env;
299 jclass jclass_of_hashmap = (env)->GetObjectClass(data);
302 jmethodID entrySetMethod = (env)->GetMethodID(jclass_of_hashmap,
"entrySet",
"()Ljava/util/Set;");
305 jobject jobject_of_entryset = env->CallObjectMethod(data, entrySetMethod);
308 jclass jclass_of_set = (env)->FindClass(
"java/util/Set");
310 if (jclass_of_set == 0) {
311 qWarning() <<
"java/util/Set lookup failed\n";
316 jmethodID iteratorMethod = env->GetMethodID(jclass_of_set,
"iterator",
"()Ljava/util/Iterator;");
319 jobject jobject_of_iterator = env->CallObjectMethod(jobject_of_entryset, iteratorMethod);
322 jclass jclass_of_iterator = (env)->FindClass(
"java/util/Iterator");
325 jmethodID hasNextMethod = env->GetMethodID(jclass_of_iterator,
"hasNext",
"()Z");
327 jmethodID nextMethod = env->GetMethodID(jclass_of_iterator,
"next",
"()Ljava/lang/Object;");
329 while (env->CallBooleanMethod(jobject_of_iterator, hasNextMethod)) {
330 jobject jEntry = env->CallObjectMethod(jobject_of_iterator, nextMethod);
331 QAndroidJniObject entry = QAndroidJniObject(jEntry);
332 QAndroidJniObject key = entry.callObjectMethod(
"getKey",
"()Ljava/lang/Object;");
333 QAndroidJniObject value = entry.callObjectMethod(
"getValue",
"()Ljava/lang/Object;");
338 env->DeleteLocalRef(jEntry);
347 if (env->ExceptionOccurred()) {
348 env->ExceptionDescribe();
349 env->ExceptionClear();
352 env->DeleteLocalRef(jclass_of_hashmap);
353 env->DeleteLocalRef(jobject_of_entryset);
354 env->DeleteLocalRef(jclass_of_set);
355 env->DeleteLocalRef(jobject_of_iterator);
356 env->DeleteLocalRef(jclass_of_iterator);
363 qDebug() <<
"CHECKIGN PERMISSSIONS";
365 for (
const auto &permission : permissions) {
366 QtAndroid::PermissionResult r = QtAndroid::checkPermission(permission);
367 if (r == QtAndroid::PermissionResult::Denied) {
368 QtAndroid::requestPermissionsSync({permission});
369 r = QtAndroid::checkPermission(permission);
370 if (r == QtAndroid::PermissionResult::Denied) {
371 qWarning() <<
"Permission denied";
377 qDebug() <<
"Permissions granted!";
381bool MAUIAndroid::hasKeyboard()
383 QAndroidJniObject context = QtAndroid::androidContext().object<jobject>();
385 if (context.isValid()) {
386 QAndroidJniObject resources = context.callObjectMethod(
"getResources",
"()Landroid/content/res/Resources;");
387 QAndroidJniObject config = resources.callObjectMethod(
"getConfiguration",
"()Landroid/content/res/Configuration;");
388 int value = config.getField<jint>(
"keyboard");
390 qDebug() <<
"KEYBOARD" << value;
392 return value == 2 || value == 3;
395 throw InterfaceConnFailedException();
398bool MAUIAndroid::hasMouse()
403void MAUIAndroid::handleActivityResult(
int receiverRequestCode,
int resultCode,
const QAndroidJniObject &data)
405 qDebug() <<
"ACTIVITY RESULTS" << receiverRequestCode;
406 emit this->hasKeyboardChanged();
407 jint RESULT_OK = QAndroidJniObject::getStaticField<jint>(
"android/app/Activity",
"RESULT_OK");
409 if (receiverRequestCode == 42 && resultCode == RESULT_OK) {
410 QString url = data.callObjectMethod(
"getData",
"()Landroid/net/Uri;").callObjectMethod(
"getPath",
"()Ljava/lang/String;").toString();
416bool MAUIAndroid::darkModeEnabled()
418 jint res = QAndroidJniObject::callStaticMethod<jint>(
419 "com/kde/maui/tools/ConfigActivity",
421 "(Landroid/content/Context;)I",
422 QtAndroid::androidActivity().
object());
static bool checkRunTimePermissions(const QStringList &permissions)
checkRunTimePermissions
void folderPicked(QString path)
folderPicked
void shareText(const QString &text) override final
shareText
static void shareLink(const QString &link)
shareLink
static QString homePath()
homePath
static void openUrl(const QUrl &url)
openUrl
static QStringList sdDirs()
sdDirs
static void navBarColor(const QString &bg, const bool &light)
navBarColor
static void fileChooser()
fileChooser
static void statusbarColor(const QString &bg, const bool &light)
statusbarColor
void shareFiles(const QList< QUrl > &urls) override final
shareFiles
KGUIADDONS_EXPORT QWindow * window(QObject *job)
qsizetype count() const const
bool isEmpty() const const
QMimeType mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode) const const
QString toLocalFile() const const
bool isNull() const const
QString toString() const const