From 25af67f6a17c2dd8577d5043d1589b72dc7f293d Mon Sep 17 00:00:00 2001 From: SeeLook <seelook@gmail.com> Date: Mon, 12 Apr 2021 14:06:21 +0200 Subject: [PATCH] [Android] Do not ask for access permission at very beginning - ask only when user will really need access to any file --- src/dialogs/tlevelcreatoritem.cpp | 7 +++++++ src/dialogs/tlevelselector.cpp | 7 ++++++- src/libs/core/Android/tandroid.cpp | 27 +++++++++++++++------------ src/libs/core/Android/tandroid.h | 4 +++- src/libs/core/Android/tfiledialog.cpp | 1 + src/libs/core/exam/texam.cpp | 8 +++++++- src/libs/core/tglobals.cpp | 23 ++++++++++++++--------- src/libs/core/tnootkaqml.cpp | 8 ++++++++ src/main.cpp | 13 ++++++++----- src/main/texamexecutor.cpp | 7 +++++++ src/main/tstartexamitem.cpp | 2 ++ 11 files changed, 78 insertions(+), 29 deletions(-) diff --git a/src/dialogs/tlevelcreatoritem.cpp b/src/dialogs/tlevelcreatoritem.cpp index a3d776031..0aec202d6 100644 --- a/src/dialogs/tlevelcreatoritem.cpp +++ b/src/dialogs/tlevelcreatoritem.cpp @@ -24,6 +24,9 @@ #include <tglobals.h> #include <texamparams.h> #include <Android/tfiledialog.h> +#if defined (Q_OS_ANDROID) + #include <Android/tandroid.h> +#endif #include <QtCore/qtimer.h> #include <QtCore/qfileinfo.h> @@ -92,6 +95,10 @@ void TlevelCreatorItem::continueLevelSave(const QString& name, const QString& de m_level->name = name; m_level->desc = desc; +#if defined (Q_OS_ANDROID) + if (GLOB->E->levelsDir.isEmpty()) + GLOB->E->levelsDir = Tandroid::getExternalPath(); +#endif // Saving to file QLatin1String dotNel(".nel"); QString fName = QDir::toNativeSeparators(GLOB->E->levelsDir + QLatin1String("/") + m_level->name); diff --git a/src/dialogs/tlevelselector.cpp b/src/dialogs/tlevelselector.cpp index 47efd0d1c..9784384ba 100644 --- a/src/dialogs/tlevelselector.cpp +++ b/src/dialogs/tlevelselector.cpp @@ -24,6 +24,9 @@ #include <tglobals.h> #include <tpath.h> #include <Android/tfiledialog.h> +#if defined (Q_OS_ANDROID) + #include <Android/tandroid.h> +#endif #include <QtCore/qsettings.h> #include <QtCore/qdiriterator.h> @@ -177,7 +180,9 @@ QString TlevelSelector::levelFile(int id) const { void TlevelSelector::loadFromFile(QString levelFile) { if (levelFile.isEmpty()) #if defined (Q_OS_ANDROID) - levelFile = TfileDialog::getOpenFileName(GLOB->E->levelsDir, QStringLiteral("nel")); + if (GLOB->E->levelsDir.isEmpty()) + GLOB->E->levelsDir = Tandroid::getExternalPath(); + levelFile = TfileDialog::getOpenFileName(GLOB->E->levelsDir, QStringLiteral("nel")); #else levelFile = TfileDialog::getOpenFileName(tr("Load exam level"), GLOB->E->levelsDir, levelFilterTxt() + QLatin1String(" (*.nel)")); #endif diff --git a/src/libs/core/Android/tandroid.cpp b/src/libs/core/Android/tandroid.cpp index 40a1e8310..05503d5fa 100644 --- a/src/libs/core/Android/tandroid.cpp +++ b/src/libs/core/Android/tandroid.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2015-2020 by Tomasz Bojczuk * + * Copyright (C) 2015-2021 by Tomasz Bojczuk * * seelook@gmail.com * * * * This program is free software; you can redistribute it and/or modify * @@ -24,6 +24,7 @@ #include <QtCore/qfileinfo.h> #include <QtWidgets/qmessagebox.h> #include <QtWidgets/qapplication.h> +#include <QtCore/qstandardpaths.h> #include <QtCore/qdebug.h> @@ -76,13 +77,20 @@ bool Tandroid::hasWriteAccess() { } +void Tandroid::askForWriteAcces() { + if (QtAndroid::androidSdkVersion() >= 23) { + const QString writeID("android.permission.WRITE_EXTERNAL_STORAGE"); + if (QtAndroid::checkPermission(writeID) != QtAndroid::PermissionResult::Granted) { + auto perms = QtAndroid::requestPermissionsSync(QStringList() << writeID); + qDebug() << writeID << (perms[writeID] == QtAndroid::PermissionResult::Granted); + } + } +} + QString Tandroid::getExternalPath() { QString extPath; if (getAPIlevelNr() < 19) { // look for SD card only before Kitkat, otherwise it is inaccessible extPath = qgetenv("SECONDARY_STORAGE"); - // QAndroidJniObject mediaDir = QAndroidJniObject::callStaticObjectMethod("android/os/Environment", - // "getExternalStorageDirectory", "()Ljava/io/File;"); - // QString extPath = mediaDir.callObjectMethod("getAbsolutePath", "()Ljava/lang/String;").toString(); if (!extPath.isEmpty()) { if (!QFileInfo(extPath).isWritable()) { qDebug() << "[Tandroid] No write access to secondary storage!"; @@ -91,16 +99,11 @@ QString Tandroid::getExternalPath() { } } - if(QtAndroid::androidSdkVersion() >= 23) { - const QString PermissionID("android.permission.WRITE_EXTERNAL_STORAGE"); - if (QtAndroid::checkPermission(PermissionID) != QtAndroid::PermissionResult::Granted) { - auto perms = QtAndroid::requestPermissionsSync(QStringList() << PermissionID); - qDebug() << PermissionID << (perms[PermissionID] == QtAndroid::PermissionResult::Granted); - } - } + askForWriteAcces(); if (extPath.isEmpty()) - extPath = qgetenv("EXTERNAL_STORAGE"); // return primary storage path (device internal) + extPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); +// extPath = qgetenv("EXTERNAL_STORAGE"); // return primary storage path (device internal) if (!QFileInfo(extPath).isWritable()) { qDebug() << "[Tandroid] No write access to primary storage!"; extPath.clear(); diff --git a/src/libs/core/Android/tandroid.h b/src/libs/core/Android/tandroid.h index 0a23c04a8..6f66871ff 100644 --- a/src/libs/core/Android/tandroid.h +++ b/src/libs/core/Android/tandroid.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2015-2020 by Tomasz Bojczuk * + * Copyright (C) 2015-2021 by Tomasz Bojczuk * * seelook@gmail.com * * * * This program is free software; you can redistribute it and/or modify * @@ -47,6 +47,8 @@ namespace Tandroid { */ bool hasWriteAccess(); + void askForWriteAcces(); + /** * Returns command line argument (usually exam/level file name. */ diff --git a/src/libs/core/Android/tfiledialog.cpp b/src/libs/core/Android/tfiledialog.cpp index 9233ae007..70f277203 100644 --- a/src/libs/core/Android/tfiledialog.cpp +++ b/src/libs/core/Android/tfiledialog.cpp @@ -163,6 +163,7 @@ TfileDialog::TfileDialog(const QString& directory, const QString& filter, Eaccep { showMaximized(); + Tandroid::askForWriteAcces(); // left side menu m_menu = new QListWidget(this); m_menu->setIconSize(QSize(60, 60)); diff --git a/src/libs/core/exam/texam.cpp b/src/libs/core/exam/texam.cpp index a522d37cd..7a28a32de 100644 --- a/src/libs/core/exam/texam.cpp +++ b/src/libs/core/exam/texam.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2011-2020 by Tomasz Bojczuk * + * Copyright (C) 2011-2021 by Tomasz Bojczuk * * seelook@gmail.com * * * * This program is free software; you can redistribute it and/or modify * @@ -26,6 +26,9 @@ #include <QtCore/qdir.h> #include <QtCore/qsettings.h> #include <QtWidgets/qmessagebox.h> +#if defined (Q_OS_ANDROID) + #include <Android/tandroid.h> +#endif #include <QtCore/qdebug.h> @@ -202,6 +205,9 @@ void Texam::skipLast(bool skip) { Texam::EerrorType Texam::loadFromFile(const QString& fileName) { +#if defined (Q_OS_ANDROID) + Tandroid::askForWriteAcces(); +#endif m_okTime = 0; m_tmpMist = 0; m_tmpHalf = 0; diff --git a/src/libs/core/tglobals.cpp b/src/libs/core/tglobals.cpp index 5188aceed..d43a72583 100755 --- a/src/libs/core/tglobals.cpp +++ b/src/libs/core/tglobals.cpp @@ -517,9 +517,12 @@ void Tglobals::loadSettings(QSettings* cfg) { S->scientificOctaves = cfg->value(QStringLiteral("scientificOctaves"), false).toBool(); Tnote::scientificOctaves = S->scientificOctaves; #if defined (Q_OS_ANDROID) - S->lastXmlDir = cfg->value(QStringLiteral("lastXmlDir"), Tandroid::getExternalPath()).toString(); - if (!QFileInfo::exists(S->lastXmlDir)) // reset if doesn't exist - S->lastXmlDir = Tandroid::getExternalPath(); + bool hasWriteAccess = Tandroid::hasWriteAccess(); + if (hasWriteAccess) { + S->lastXmlDir = cfg->value(QStringLiteral("lastXmlDir"), Tandroid::getExternalPath()).toString(); + if (!QFileInfo::exists(S->lastXmlDir) || !QFileInfo(S->lastXmlDir).isWritable()) // reset if doesn't exist + S->lastXmlDir = Tandroid::getExternalPath(); + } #endif cfg->endGroup(); @@ -614,12 +617,14 @@ void Tglobals::loadSettings(QSettings* cfg) { if (E->studentName.isEmpty()) E->studentName = systemUserName(); #if defined (Q_OS_ANDROID) - E->examsDir = cfg->value(QStringLiteral("examsDir"), Tandroid::getExternalPath()).toString(); - if (!QFileInfo::exists(E->examsDir)) // reset if doesn't exist - E->examsDir = Tandroid::getExternalPath(); - E->levelsDir = cfg->value(QStringLiteral("levelsDir"), Tandroid::getExternalPath()).toString(); - if (!QFileInfo::exists(E->levelsDir)) - E->levelsDir = Tandroid::getExternalPath(); + if (hasWriteAccess) { + E->examsDir = cfg->value(QStringLiteral("examsDir"), Tandroid::getExternalPath()).toString(); + if (!QFileInfo::exists(E->examsDir) || !QFileInfo(E->examsDir).isWritable()) // reset if doesn't exist + E->examsDir = Tandroid::getExternalPath(); + E->levelsDir = cfg->value(QStringLiteral("levelsDir"), Tandroid::getExternalPath()).toString(); + if (!QFileInfo::exists(E->levelsDir) || !QFileInfo(E->levelsDir).isWritable()) + E->levelsDir = Tandroid::getExternalPath(); + } #else E->examsDir = cfg->value(QStringLiteral("examsDir"), QDir::homePath()).toString(); if (!QFileInfo::exists(E->examsDir)) // reset if doesn't exist diff --git a/src/libs/core/tnootkaqml.cpp b/src/libs/core/tnootkaqml.cpp index 5645c7b3b..dc1d1dd1a 100755 --- a/src/libs/core/tnootkaqml.cpp +++ b/src/libs/core/tnootkaqml.cpp @@ -37,6 +37,10 @@ #include "music/ttuneobject.h" #include "tmtr.h" #include "tcolor.h" +#if defined (Q_OS_ANDROID) + #include <Android/tandroid.h> +#endif + #include <QtQml/qqmlengine.h> #include <QtCore/qtimer.h> @@ -290,6 +294,8 @@ Tinstrument TnootkaQML::instr(int type) { QString TnootkaQML::getXmlToOpen() { QString openFile; #if defined (Q_OS_ANDROID) + if (GLOB->lastXmlDir().isEmpty()) + GLOB->setLastXmlDir(Tandroid::getExternalPath()); openFile = TfileDialog::getOpenFileName(GLOB->lastXmlDir(), QStringLiteral("xml|musicxml")); #else openFile = TfileDialog::getOpenFileName(qApp->translate("TmainScoreObject", "Open melody file"), GLOB->lastXmlDir(), @@ -305,6 +311,8 @@ QString TnootkaQML::getXmlToSave(const QString& fileName) { QString saveFile; QString filter; #if defined (Q_OS_ANDROID) + if (GLOB->lastXmlDir().isEmpty()) + GLOB->setLastXmlDir(Tandroid::getExternalPath()); saveFile = TfileDialog::getSaveFileName(GLOB->lastXmlDir() + QLatin1String("/") + fileName, QStringLiteral("musicxml|xml")); #else diff --git a/src/main.cpp b/src/main.cpp index 050523ee9..c95004e93 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -90,11 +90,14 @@ int main(int argc, char *argv[]) qputenv("QT_ANDROID_VOLUME_KEYS", "1"); // Handle volume keys by Qt, lock native Android behavior // log to any writable storage - logFile = Tandroid::getExternalPath() + QStringLiteral("/nootka-log.txt"); - if (QFile::exists(logFile)) - QFile::remove(logFile); - qInstallMessageHandler(myMessageOutput); - qDebug() << "==== NOOTKA LOG =======\n" << QDateTime::currentDateTime().toString(); + if (Tandroid::hasWriteAccess()) { + logFile = Tandroid::getExternalPath() + QStringLiteral("/nootka-log.txt"); + Tandroid::askForWriteAcces(); + if (QFile::exists(logFile)) + QFile::remove(logFile); + qInstallMessageHandler(myMessageOutput); + qDebug() << "==== NOOTKA LOG =======\n" << QDateTime::currentDateTime().toString(); + } #else qputenv("QT_QUICK_CONTROLS_STYLE", ""); // reset style environment var - other styles can cause crashes #endif diff --git a/src/main/texamexecutor.cpp b/src/main/texamexecutor.cpp index 3e29655f2..f5526144d 100644 --- a/src/main/texamexecutor.cpp +++ b/src/main/texamexecutor.cpp @@ -44,6 +44,9 @@ #include "tnameitem.h" #include "tmainscoreobject.h" #include <Android/tfiledialog.h> +#if defined (Q_OS_ANDROID) + #include <Android/tandroid.h> +#endif #include <QtCore/qdatetime.h> #include <QtCore/qtimer.h> @@ -79,6 +82,10 @@ void debugStyle(TQAunit &qa) { * but when such a file exists in current exam directory some time mark is added. */ QString getExamFileName(Texam* e) { +#if defined (Q_OS_ANDROID) + if (GLOB->E->examsDir.isEmpty()) + GLOB->E->examsDir = Tandroid::getExternalPath(); +#endif auto fName = QDir::toNativeSeparators(GLOB->E->examsDir + QLatin1String("/") + e->userName() + QLatin1String("-") + e->level()->name); fName = fName.replace(QLatin1String("."), QLatin1String("")); //HACK: file dialogues don't like dots in the names if (QFileInfo::exists(fName + QLatin1String(".noo"))) diff --git a/src/main/tstartexamitem.cpp b/src/main/tstartexamitem.cpp index 52d27266e..2d6ab1c41 100644 --- a/src/main/tstartexamitem.cpp +++ b/src/main/tstartexamitem.cpp @@ -124,6 +124,8 @@ void TstartExamItem::continuePrevExam() { void TstartExamItem::examFromFileDialog() { #if defined (Q_OS_ANDROID) + if (GLOB->E->examsDir.isEmpty()) + GLOB->E->examsDir = Tandroid::getExternalPath(); QString fileName = TfileDialog::getOpenFileName(GLOB->E->examsDir, QStringLiteral("noo")); #else QString fileName = TfileDialog::getOpenFileName(TexTrans::loadExamFileTxt(), GLOB->E->examsDir, TexTrans::examFilterTxt()); -- GitLab