File: AndroidUtils.cpp

package info (click to toggle)
pentobi 18.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 3,912 kB
  • sloc: cpp: 26,729; javascript: 907; xml: 49; sh: 35; makefile: 21; java: 11
file content (152 lines) | stat: -rw-r--r-- 5,523 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//-----------------------------------------------------------------------------
/** @file pentobi/AndroidUtils.cpp
    @author Markus Enzenberger
    @copyright GNU General Public License version 3 or later */
//-----------------------------------------------------------------------------

#include "AndroidUtils.h"

#include <QCoreApplication>
#include <QStandardPaths>

#ifdef Q_OS_ANDROID
#include <QAndroidJniObject>
#include <QDir>
#include <QDirIterator>
#include <QHash>
#include <QtAndroid>
#endif

//-----------------------------------------------------------------------------

bool AndroidUtils::checkPermission([[maybe_unused]] const QString& permission)
{
#ifdef Q_OS_ANDROID
    using QtAndroid::PermissionResult;
    if (QtAndroid::checkPermission(permission) == PermissionResult::Denied)
    {
        QStringList permissions;
        permissions << permission;
        auto result = QtAndroid::requestPermissionsSync(permissions);
        if (result[permission] == PermissionResult::Denied)
            return false;
    }
#endif
    return true;
}

QUrl AndroidUtils::extractHelp([[maybe_unused]] const QString& language)
{
#ifdef Q_OS_ANDROID
    if (language != QStringLiteral("C"))
        // Other languages use pictures from C
        extractHelp(QStringLiteral("C"));
    auto activity = QtAndroid::androidActivity();
    auto filesDir =
            activity.callObjectMethod("getFilesDir", "()Ljava/io/File;");
    if (! filesDir.isValid())
        return {};
    auto filesDirString = filesDir.callObjectMethod("toString",
                                                    "()Ljava/lang/String;");
    if (! filesDirString.isValid())
        return {};
    QDir dir(filesDirString.toString() + "/help/"
             + QCoreApplication::applicationVersion() + "/" + language
             + "/pentobi");
    auto dirPath = dir.path();
    if (QFileInfo::exists(dirPath + "/index.html"))
        return QUrl::fromLocalFile(dirPath + "/index.html");
    if (! QFileInfo::exists(filesDirString.toString() + "/help/"
                            + QCoreApplication::applicationVersion()
                            + "/C/pentobi/index.html"))
        // No need to keep files from older versions around
        QDir(filesDirString.toString() + "/help").removeRecursively();
    QDirIterator it(":qml/help/" + language + "/pentobi");
    while (it.hasNext())
    {
        it.next();
        if (! it.fileInfo().isFile())
            continue;
        QFile dest(dirPath + "/" + it.fileName());
        QFileInfo(dest).dir().mkpath(QStringLiteral("."));
        dest.remove();
        QFile::copy(it.filePath(), dest.fileName());
    }
    auto file = QFileInfo(dirPath + "/index.html").absoluteFilePath();
    return QUrl::fromLocalFile(file);
#else
    return {};
#endif
}

QUrl AndroidUtils::getDefaultFolder()
{
#ifdef Q_OS_ANDROID
    QUrl fallback(QStringLiteral("file:///sdcard"));
    auto file = QAndroidJniObject::callStaticObjectMethod(
                "android/os/Environment", "getExternalStorageDirectory",
                "()Ljava/io/File;");
    if (! file.isValid())
        return fallback;
    auto fileString = file.callObjectMethod("toString",
                                            "()Ljava/lang/String;");
    if (! fileString.isValid())
        return fallback;
    return QUrl::fromLocalFile(fileString.toString());
#else
    return QUrl::fromLocalFile(
                QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
#endif
}

#ifdef Q_OS_ANDROID
float AndroidUtils::getDensity()
{
    auto resources = QtAndroid::androidActivity().callObjectMethod(
                "getResources", "()Landroid/content/res/Resources;");
    if (! resources.isValid())
        return 0;
    auto metrics = resources.callObjectMethod(
                "getDisplayMetrics", "()Landroid/util/DisplayMetrics;");
    if (! metrics.isValid())
        return 0;
    return metrics.getField<jfloat>("density");
}
#endif

void AndroidUtils::scanFile([[maybe_unused]] const QString& pathname)
{
#ifdef Q_OS_ANDROID
    // Corresponding Java code:
    //   sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
    //                         Uri.fromFile(File(pathname).getAbsoluteFile())))
    auto action = QAndroidJniObject::getStaticObjectField<jstring>(
                "android/content/Intent", "ACTION_MEDIA_SCANNER_SCAN_FILE");
    if (! action.isValid())
        return;
    auto pathnameString = QAndroidJniObject::fromString(pathname);
    QAndroidJniObject file("java/io/File", "(Ljava/lang/String;)V",
                           pathnameString.object<jstring>());
    if (! file.isValid())
        return;
    auto absoluteFile = file.callObjectMethod(
                "getAbsoluteFile", "()Ljava/io/File;");
    if (! absoluteFile.isValid())
        return;
    auto uri = QAndroidJniObject::callStaticObjectMethod(
                "android/net/Uri", "fromFile",
                "(Ljava/io/File;)Landroid/net/Uri;", absoluteFile.object());
    if (! uri.isValid())
        return;
    QAndroidJniObject intent("android/content/Intent",
                             "(Ljava/lang/String;Landroid/net/Uri;)V",
                             action.object<jstring>(), uri.object());
    if (! intent.isValid())
        return;
    QtAndroid::androidActivity().callMethod<void>(
                "sendBroadcast", "(Landroid/content/Intent;)V",
                intent.object());
#endif
}

//-----------------------------------------------------------------------------