Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
mobile Datovka
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
12
Issues
12
List
Boards
Labels
Service Desk
Milestones
Merge Requests
4
Merge Requests
4
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Datovka projects
mobile Datovka
Commits
f643cc46
Commit
f643cc46
authored
Dec 14, 2018
by
Martin Straka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Android file provider prototyp
parent
0946d392
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
328 additions
and
8 deletions
+328
-8
android/AndroidManifest.tmp
android/AndroidManifest.tmp
+8
-1
android/res/xml/filepaths.xml
android/res/xml/filepaths.xml
+1
-2
android/src/android_io.cpp
android/src/android_io.cpp
+62
-0
android/src/android_io.h
android/src/android_io.h
+59
-0
android/src/cz/nic/mobiledatovka/java/QFileProvider.java
android/src/cz/nic/mobiledatovka/java/QFileProvider.java
+158
-0
mobile-datovka.pro
mobile-datovka.pro
+4
-0
src/files.cpp
src/files.cpp
+36
-5
No files found.
android/AndroidManifest.tmp
View file @
f643cc46
...
...
@@ -13,6 +13,13 @@
<data
android:host=
"*"
/>
<data
android:pathPattern=
".*\\.zfo"
/>
</intent-filter>
<intent-filter>
<action
android:name=
"android.intent.action.VIEW"
/>
<category
android:name=
"android.intent.category.DEFAULT"
/>
<data
android:scheme=
"content"
/>
<data
android:scheme=
"file"
/>
<data
android:mimeType=
"*/*"
/>
</intent-filter>
<intent-filter>
<action
android:name=
"android.intent.action.VIEW"
/>
<category
android:name=
"android.intent.category.BROWSABLE"
/>
...
...
@@ -77,7 +84,7 @@
<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
<provider
android:name=
"android.support.v4.content.FileProvider"
android:authorities=
"
${applicationId}
.fileprovider"
android:authorities=
"
cz.nic.mobiledatovka
.fileprovider"
android:grantUriPermissions=
"true"
android:exported=
"false"
>
<meta-data
android:name=
"android.support.FILE_PROVIDER_PATHS"
...
...
android/res/xml/filepaths.xml
View file @
f643cc46
<?xml version="1.0" encoding="utf-8"?>
<paths
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<file
-path
name=
"external_files"
path=
"."
/>
<file
s-path
name=
"my_shared_files"
path=
"share_example_x_files/"
/>
</paths>
\ No newline at end of file
android/src/android_io.cpp
0 → 100644
View file @
f643cc46
/*
* Copyright (C) 2014-2018 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#include <QAndroidJniObject>
#include <QtAndroidExtras>
#include <QDesktopServices>
#include <QUrl>
#include "android/src/android_io.h"
AndroidIO
::
AndroidIO
(
void
)
{
}
bool
AndroidIO
::
openFile
(
const
QString
&
filePath
)
{
/* TOTO: ADD test: if (SDK >= 24) { use FileProvide } else { use QDesktopServices } */
#if 0
return openWithQDesktopServices(filePath);
#else
return
openWithFileProvider
(
filePath
);
#endif
}
bool
AndroidIO
::
openWithQDesktopServices
(
const
QString
&
filePath
)
{
return
QDesktopServices
::
openUrl
(
QUrl
::
fromLocalFile
(
filePath
));
}
bool
AndroidIO
::
openWithFileProvider
(
const
QString
&
filePath
)
{
QAndroidJniObject
jsPath
=
QAndroidJniObject
::
fromString
(
filePath
);
jboolean
ok
=
QAndroidJniObject
::
callStaticMethod
<
jboolean
>
(
"cz/nic/mobiledatovka/java/QFileProvider"
,
"viewFile"
,
"(Ljava/lang/String;I)Z"
,
jsPath
.
object
<
jstring
>
(),
0
);
return
(
ok
);
}
android/src/android_io.h
0 → 100644
View file @
f643cc46
/*
* Copyright (C) 2014-2018 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#pragma once
#include <QtAndroid>
#include <QAndroidActivityResultReceiver>
#include <QObject>
/*!
* @brief Wraps Android intent retrieval.
*
*/
class
AndroidIO
:
public
QAndroidActivityResultReceiver
{
public:
/*!
* @brief Constructor.
*
* @param[in] parent Parent object.
*/
explicit
AndroidIO
(
void
);
/*!
* @brief Obtain intent arguments.
*
* @return List of files to be opened.
*/
static
bool
openFile
(
const
QString
&
filePath
);
private:
static
bool
openWithQDesktopServices
(
const
QString
&
filePath
);
static
bool
openWithFileProvider
(
const
QString
&
filePath
);
};
android/src/cz/nic/mobiledatovka/java/QFileProvider.java
0 → 100644
View file @
f643cc46
/*
* Copyright (C) 2014-2018 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
package
cz.nic.mobiledatovka.java
;
import
org.qtproject.qt5.android.QtNative
;
import
java.lang.String
;
import
android.content.Intent
;
import
java.io.File
;
import
android.net.Uri
;
import
android.util.Log
;
import
android.content.ContentResolver
;
import
android.database.Cursor
;
import
android.provider.MediaStore
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.FileOutputStream
;
import
java.util.List
;
import
android.content.pm.ResolveInfo
;
import
java.util.ArrayList
;
import
android.content.pm.PackageManager
;
import
java.util.Comparator
;
import
java.util.Collections
;
import
android.content.Context
;
import
android.os.Parcelable
;
import
android.os.Build
;
import
android.support.v4.content.FileProvider
;
import
android.support.v4.app.ShareCompat
;
public
class
QFileProvider
{
// Authority defined in AndroidManifest.xml
private
static
String
AUTHORITY
=
"cz.nic.mobiledatovka.fileprovider"
;
protected
QFileProvider
()
{}
public
static
boolean
startActivity
(
Intent
theIntent
,
Uri
uri
)
{
final
Context
context
=
QtNative
.
activity
();
final
PackageManager
packageManager
=
context
.
getPackageManager
();
final
boolean
isLowerOrEqualsKitKat
=
Build
.
VERSION
.
SDK_INT
<=
Build
.
VERSION_CODES
.
KITKAT
;
ResolveInfo
defaultAppInfo
=
packageManager
.
resolveActivity
(
theIntent
,
PackageManager
.
MATCH_DEFAULT_ONLY
);
if
(
defaultAppInfo
==
null
)
{
return
false
;
}
List
<
ResolveInfo
>
appInfoList
=
packageManager
.
queryIntentActivities
(
theIntent
,
PackageManager
.
MATCH_DEFAULT_ONLY
);
if
(
appInfoList
.
isEmpty
())
{
return
false
;
}
Collections
.
sort
(
appInfoList
,
new
Comparator
<
ResolveInfo
>()
{
@Override
public
int
compare
(
ResolveInfo
first
,
ResolveInfo
second
)
{
String
firstName
=
first
.
loadLabel
(
packageManager
).
toString
();
String
secondName
=
second
.
loadLabel
(
packageManager
).
toString
();
return
firstName
.
compareToIgnoreCase
(
secondName
);
}
});
List
<
Intent
>
targetedIntents
=
new
ArrayList
<
Intent
>();
for
(
ResolveInfo
appInfo
:
appInfoList
)
{
String
targetPackageName
=
appInfo
.
activityInfo
.
packageName
;
if
(
targetPackageName
.
equals
(
context
.
getPackageName
()))
{
continue
;
}
Intent
targetedIntent
=
new
Intent
(
theIntent
);
targetedIntent
.
setPackage
(
targetPackageName
);
targetedIntents
.
add
(
targetedIntent
);
if
(
isLowerOrEqualsKitKat
)
{
context
.
grantUriPermission
(
targetPackageName
,
uri
,
Intent
.
FLAG_GRANT_READ_URI_PERMISSION
|
Intent
.
FLAG_GRANT_WRITE_URI_PERMISSION
);
}
}
if
(
targetedIntents
.
isEmpty
())
{
return
false
;
}
Intent
chooserIntent
=
Intent
.
createChooser
(
targetedIntents
.
remove
(
targetedIntents
.
size
()
-
1
),
"View File"
);
if
(
targetedIntents
.
isEmpty
())
{
}
else
{
chooserIntent
.
putExtra
(
Intent
.
EXTRA_INITIAL_INTENTS
,
targetedIntents
.
toArray
(
new
Parcelable
[]
{}));
}
if
(
chooserIntent
.
resolveActivity
(
QtNative
.
activity
().
getPackageManager
())
!=
null
)
{
QtNative
.
activity
().
startActivity
(
chooserIntent
);
return
true
;
}
return
false
;
}
public
static
boolean
viewFile
(
String
filePath
,
int
id
)
{
if
(
QtNative
.
activity
()
==
null
)
{
return
false
;
}
// Intent viewIntent = new Intent();
Intent
viewIntent
=
ShareCompat
.
IntentBuilder
.
from
(
QtNative
.
activity
()).
getIntent
();
viewIntent
.
setAction
(
Intent
.
ACTION_VIEW
);
File
imageFileToShare
=
new
File
(
filePath
);
Uri
uri
;
try
{
uri
=
FileProvider
.
getUriForFile
(
QtNative
.
activity
(),
AUTHORITY
,
imageFileToShare
);
}
catch
(
IllegalArgumentException
e
)
{
Log
.
d
(
"Error viewFile - cannot be shared: "
,
filePath
);
return
false
;
}
Log
.
d
(
"File path: "
,
filePath
);
Log
.
d
(
"File content URI: "
,
uri
.
toString
());
String
mimeType
=
QtNative
.
activity
().
getContentResolver
().
getType
(
uri
);
viewIntent
.
setDataAndType
(
uri
,
mimeType
);
viewIntent
.
addFlags
(
Intent
.
FLAG_GRANT_READ_URI_PERMISSION
);
viewIntent
.
addFlags
(
Intent
.
FLAG_GRANT_WRITE_URI_PERMISSION
);
return
startActivity
(
viewIntent
,
uri
);
}
}
mobile-datovka.pro
View file @
f643cc46
...
...
@@ -88,6 +88,7 @@ TRANSLATIONS_FILES += \
res/locale/datovka_en.qm
SOURCES += \
android/src/android_io.cpp \
src/accounts.cpp \
src/auxiliaries/email_helper.cpp \
src/datovka_shared/gov_services/helper.cpp \
...
...
@@ -209,6 +210,7 @@ SOURCES += \
src/zfo.cpp
HEADERS += \
android/src/android_io.h \
src/accounts.h \
src/auxiliaries/email_helper.h \
src/common.h \
...
...
@@ -372,6 +374,8 @@ android {
}
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
include(android/android.pri)
OTHER_FILES += android/src/cz/nic/mobiledatovka/java/QFileProvider.java
}
# winphone|winrt target.
...
...
src/files.cpp
View file @
f643cc46
...
...
@@ -22,10 +22,14 @@
*/
#include <QDesktopServices>
#include <QDir>
#include <QFileInfo>
#include <QQmlEngine>
#include <QStringBuilder>
#if defined (Q_OS_ANDROID)
#include "android/src/android_io.h"
#endif
#include "ios/src/url_opener.h"
#include "src/auxiliaries/email_helper.h"
#include "src/common.h"
...
...
@@ -204,7 +208,28 @@ void Files::openAttachment(const QString &fileName,
return
;
}
QString
filePath
(
writeFile
(
appTmpDirPath
(),
fileName
,
binaryData
));
QString
docLocationRoot
=
appTmpDirPath
();
#if defined (Q_OS_ANDROID)
docLocationRoot
=
QStandardPaths
::
standardLocations
(
QStandardPaths
::
AppDataLocation
).
value
(
0
);
QString
documentsWorkPath
=
docLocationRoot
.
append
(
"/share_example_x_files"
);
if
(
!
QDir
(
documentsWorkPath
).
exists
())
{
if
(
!
QDir
(
""
).
mkpath
(
documentsWorkPath
))
{
logErrorNL
(
"Failed to create share directory: '%s'."
,
documentsWorkPath
.
toUtf8
().
constData
());
Dialogues
::
errorMessage
(
Dialogues
::
CRITICAL
,
tr
(
"Open attachment error"
),
tr
(
"Cannot save selected file to disk for opening."
),
QString
());
return
;
}
}
#endif
QString
filePath
(
writeFile
(
docLocationRoot
,
fileName
,
binaryData
));
if
(
!
filePath
.
isEmpty
())
{
logInfoNL
(
"Creating temporary file '%s'."
,
...
...
@@ -240,12 +265,18 @@ void Files::openAttachmentFromPath(const QString &filePath)
UrlOpener
urlOpener
;
urlOpener
.
openFile
(
filePath
);
#el
se
#el
if defined (Q_OS_ANDROID)
QUrl
contentUri
=
QUrl
::
fromLocalFile
(
filePath
);
contentUri
.
setScheme
(
"content"
);
if
(
!
AndroidIO
::
openFile
(
filePath
))
{
Dialogues
::
errorMessage
(
Dialogues
::
CRITICAL
,
tr
(
"Open attachment error"
),
tr
(
"There is no application to open this file format."
),
tr
(
"File: '%1'"
).
arg
(
filePath
));
}
#else
if
(
!
QDesktopServices
::
openUrl
(
contentUri
))
{
if
(
!
QDesktopServices
::
openUrl
(
QUrl
::
fromLocalFile
(
filePath
)
))
{
Dialogues
::
errorMessage
(
Dialogues
::
CRITICAL
,
tr
(
"Open attachment error"
),
tr
(
"There is no application to open this file format."
),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment