mirror of
https://invent.kde.org/graphics/okular
synced 2024-08-27 03:30:20 +00:00
Android: Make it possible to open documents from Android
Include ad-hoc code to open files on Android.
This commit is contained in:
parent
9ca00505a5
commit
885e1f2269
|
@ -1,43 +1,16 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<manifest package="org.kde.okularkirigami" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.3.0" android:versionCode="9" android:installLocation="auto">
|
||||
<application android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Okular" android:icon="@drawable/icon">
|
||||
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation"
|
||||
android:name="org.qtproject.qt5.android.bindings.QtActivity"
|
||||
android:label="Okular"
|
||||
android:hardwareAccelerated="true"
|
||||
android:screenOrientation="unspecified">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
|
||||
<meta-data android:name="android.app.lib_name" android:value="okularkirigami"/>
|
||||
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
|
||||
<meta-data android:name="android.app.repository" android:value="default"/>
|
||||
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
|
||||
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
|
||||
<!-- Deploy Qt libs as part of package -->
|
||||
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="1"/>
|
||||
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
|
||||
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
|
||||
<!-- Run with local libs -->
|
||||
<meta-data android:name="android.app.use_local_qt_libs" android:value="1"/>
|
||||
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
|
||||
<meta-data android:name="android.app.load_local_libs" android:value="plugins/platforms/android/libqtforandroid.so:plugins/bearer/libqandroidbearer.so"/>
|
||||
<meta-data android:name="android.app.load_local_jars" android:value="jar/QtAndroid.jar:jar/QtAndroidAccessibility.jar:jar/QtAndroid-bundled.jar:jar/QtAndroidAccessibility-bundled.jar:jar/QtAndroidBearer.jar:jar/QtAndroidBearer-bundled.jar"/>
|
||||
<meta-data android:name="android.app.static_init_classes" android:value=""/>
|
||||
<!-- Messages maps -->
|
||||
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
|
||||
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
|
||||
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
|
||||
<!-- Messages maps -->
|
||||
</activity>
|
||||
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation"
|
||||
android:name="org.kde.something.OpenFileActivity"
|
||||
android:label="Okular"
|
||||
android:hardwareAccelerated="true"
|
||||
android:screenOrientation="unspecified">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
<intent-filter android:label="Okular">
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.util.Log;
|
|||
import android.os.Bundle;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.net.Uri;
|
||||
import android.app.Activity;
|
||||
|
||||
import org.qtproject.qt5.android.bindings.QtActivity;
|
||||
|
||||
|
@ -14,16 +15,13 @@ class FileClass
|
|||
public static native void openUri(String uri);
|
||||
}
|
||||
|
||||
public class OpenFileActivity extends QtActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
final Intent bundleIntent = getIntent();
|
||||
if (bundleIntent == null)
|
||||
public class OpenFileActivity extends QtActivity
|
||||
{
|
||||
private void displayUri(Uri uri)
|
||||
{
|
||||
if (uri == null)
|
||||
return;
|
||||
|
||||
final String action = bundleIntent.getAction();
|
||||
Uri uri = bundleIntent.getData();
|
||||
if (!uri.getScheme().equals("file")) {
|
||||
try {
|
||||
ContentResolver resolver = getBaseContext().getContentResolver();
|
||||
|
@ -33,11 +31,49 @@ public class OpenFileActivity extends QtActivity {
|
|||
e.printStackTrace();
|
||||
|
||||
//TODO: emit warning that couldn't be opened
|
||||
Log.v("Okular", "failed to open");
|
||||
Log.e("Okular", "failed to open");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Log.e("Okular", "opening url: " + uri.toString());
|
||||
FileClass.openUri(uri.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
final Intent bundleIntent = getIntent();
|
||||
if (bundleIntent == null)
|
||||
return;
|
||||
|
||||
final String action = bundleIntent.getAction();
|
||||
Log.v("Okular", "Starting action: " + action);
|
||||
if (action == "android.intent.action.VIEW") {
|
||||
displayUri(bundleIntent.getData());
|
||||
}
|
||||
}
|
||||
|
||||
private static int OpenDocumentRequest = 42;
|
||||
|
||||
public static void openFile(Activity context, String title, String mimes)
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("application/pdf");
|
||||
Log.v("Okular", "opening: " + mimes);
|
||||
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimes.split(";"));
|
||||
|
||||
context.startActivityForResult(intent, OpenDocumentRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
Log.v("Okular", "Activity Result: " + String.valueOf(requestCode) + " with code: " + String.valueOf(resultCode));
|
||||
if (requestCode == OpenDocumentRequest) {
|
||||
Uri uri = intent.getData();
|
||||
Log.v("Okular", "Opening document: " + uri.toString());
|
||||
displayUri(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@ set(CMAKE_AUTORCC ON)
|
|||
add_executable(okularkirigami main.cpp app.qrc)
|
||||
target_link_libraries(okularkirigami Qt5::Widgets Qt5::Qml KF5::I18n)
|
||||
if (ANDROID)
|
||||
find_package(Qt5 COMPONENTS AndroidExtras)
|
||||
target_sources(okularkirigami PRIVATE android.cpp)
|
||||
target_link_libraries(okularkirigami Qt5::AndroidExtras)
|
||||
endif()
|
||||
|
||||
install(TARGETS okularkirigami ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
|
||||
|
|
|
@ -17,6 +17,32 @@
|
|||
*************************************************************************************/
|
||||
|
||||
#include "android.h"
|
||||
#include <QAndroidJniObject>
|
||||
#include <QAndroidJniEnvironment>
|
||||
#include <QStringList>
|
||||
#include <QDebug>
|
||||
|
||||
static AndroidInstance* s_instance = nullptr;
|
||||
|
||||
void AndroidInstance::openFile(const QString &title, const QStringList &mimes)
|
||||
{
|
||||
s_instance = this;
|
||||
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); //activity is valid
|
||||
Q_ASSERT ( activity.isValid() );
|
||||
|
||||
QAndroidJniEnvironment _env;
|
||||
QAndroidJniObject::callStaticMethod<void>("org/kde/something/OpenFileActivity",
|
||||
"openFile",
|
||||
"(Landroid/app/Activity;Ljava/lang/String;Ljava/lang/String;)V",
|
||||
activity.object<jobject>(),
|
||||
QAndroidJniObject::fromString(title).object<jstring>(),
|
||||
QAndroidJniObject::fromString(mimes.join(';')).object<jstring>()
|
||||
);
|
||||
if (_env->ExceptionCheck()) {
|
||||
_env->ExceptionClear();
|
||||
qWarning() << "couldn't launch intent";
|
||||
}
|
||||
}
|
||||
|
||||
void Java_org_kde_something_FileClass_openUri(JNIEnv *env,
|
||||
jobject /*obj*/,
|
||||
|
@ -24,7 +50,11 @@ void Java_org_kde_something_FileClass_openUri(JNIEnv *env,
|
|||
{
|
||||
jboolean isCopy = false;
|
||||
const char* utf = env->GetStringUTFChars(uri, &isCopy);
|
||||
handler.openUri(QString::fromUtf8(utf));
|
||||
const QString uriString = QString::fromUtf8(utf);
|
||||
if (s_instance)
|
||||
s_instance->openUri(QUrl(uriString));
|
||||
else
|
||||
handler.openUri(uriString);
|
||||
env->ReleaseStringUTFChars(uri, utf);
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
#ifndef ANDROID_H
|
||||
#define ANDROID_H
|
||||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
#include <jni.h>
|
||||
|
||||
class URIHandler {
|
||||
|
@ -33,6 +34,16 @@ public:
|
|||
|
||||
static URIHandler handler;
|
||||
|
||||
class AndroidInstance : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Q_SCRIPTABLE void openFile(const QString &title, const QStringList &mimes);
|
||||
|
||||
Q_SIGNALS:
|
||||
void openUri(const QUrl &uri);
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
|
|
|
@ -49,8 +49,10 @@ int main(int argc, char *argv[])
|
|||
QQmlApplicationEngine engine;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
qmlRegisterSingletonType<QObject>("org.kde.okular.app", 2, 0, "AndroidInstance", [](QQmlEngine*, QJSEngine*) -> QObject* { return new AndroidInstance; });
|
||||
const QString uri = handler.m_lastUrl;
|
||||
#else
|
||||
qmlRegisterSingletonType<QObject>("org.kde.okular.app", 2, 0, "AndroidInstance", [](QQmlEngine*, QJSEngine*) -> QObject* { return new QObject; });
|
||||
const QString uri = parser.positionalArguments().count() == 1
|
||||
? QUrl::fromUserInput(parser.positionalArguments().constFirst(), {}, QUrl::AssumeLocalFile).toString()
|
||||
: QString();
|
||||
|
|
|
@ -21,6 +21,7 @@ import QtQuick 2.1
|
|||
import QtQuick.Dialogs 1.3 as QQD
|
||||
import org.kde.okular 2.0 as Okular
|
||||
import org.kde.kirigami 2.0 as Kirigami
|
||||
import org.kde.okular.app 2.0
|
||||
|
||||
Kirigami.AbstractApplicationWindow {
|
||||
id: fileBrowserRoot
|
||||
|
@ -47,6 +48,22 @@ Kirigami.AbstractApplicationWindow {
|
|||
onTriggered: {
|
||||
fileDialog.open()
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Open Android...")
|
||||
icon.name: "document-open"
|
||||
readonly property var p0: Connections {
|
||||
target: AndroidInstance
|
||||
enabled: AndroidInstance.hasOwnProperty("openFile")
|
||||
onOpenUri: {
|
||||
console.log("open uri!", uri)
|
||||
documentItem.url = uri
|
||||
}
|
||||
}
|
||||
onTriggered: {
|
||||
// var mimetypes = Okular.Okular.mimeTypes.join(",")
|
||||
AndroidInstance.openFile(i18n("Document to open..."), "*/*")
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue