summaryrefslogtreecommitdiffstats
path: root/src/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/android')
-rw-r--r--src/android/jar/bundledjar.pro3
-rw-r--r--src/android/jar/distributedjar.pro2
-rw-r--r--src/android/jar/jar.pri18
-rw-r--r--src/android/jar/jar.pro21
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java6
-rw-r--r--src/android/java/AndroidManifest.xml6
-rw-r--r--src/android/java/READ-THIS-BEFORE-MANUALLY-ADDING-FILES-TO-PACKAGE.txt6
-rw-r--r--src/android/java/res/values/libs.xml2
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java116
9 files changed, 153 insertions, 27 deletions
diff --git a/src/android/jar/bundledjar.pro b/src/android/jar/bundledjar.pro
new file mode 100644
index 0000000000..e82c01c51b
--- /dev/null
+++ b/src/android/jar/bundledjar.pro
@@ -0,0 +1,3 @@
+TARGET = QtAndroid-bundled
+CONFIG += bundled_jar_file
+include(jar.pri)
diff --git a/src/android/jar/distributedjar.pro b/src/android/jar/distributedjar.pro
new file mode 100644
index 0000000000..15f362f629
--- /dev/null
+++ b/src/android/jar/distributedjar.pro
@@ -0,0 +1,2 @@
+TARGET = QtAndroid
+include(jar.pri)
diff --git a/src/android/jar/jar.pri b/src/android/jar/jar.pri
new file mode 100644
index 0000000000..19501d7b29
--- /dev/null
+++ b/src/android/jar/jar.pri
@@ -0,0 +1,18 @@
+CONFIG += java
+DESTDIR = $$[QT_INSTALL_PREFIX/get]/jar
+
+PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/
+
+JAVACLASSPATH += $$PWD/src/
+JAVASOURCES += \
+ $$PATHPREFIX/QtActivityDelegate.java \
+ $$PATHPREFIX/QtEditText.java \
+ $$PATHPREFIX/QtInputConnection.java \
+ $$PATHPREFIX/QtLayout.java \
+ $$PATHPREFIX/QtNative.java \
+ $$PATHPREFIX/QtNativeLibrariesDir.java \
+ $$PATHPREFIX/QtSurface.java
+
+# install
+target.path = $$[QT_INSTALL_PREFIX]/jar
+INSTALLS += target
diff --git a/src/android/jar/jar.pro b/src/android/jar/jar.pro
index 1955f16142..8d19c1b7d6 100644
--- a/src/android/jar/jar.pro
+++ b/src/android/jar/jar.pro
@@ -1,19 +1,2 @@
-CONFIG += java
-TARGET = QtAndroid
-DESTDIR = $$[QT_INSTALL_PREFIX/get]/jar
-
-PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/
-
-JAVACLASSPATH += $$PWD/src/
-JAVASOURCES += \
- $$PATHPREFIX/QtActivityDelegate.java \
- $$PATHPREFIX/QtEditText.java \
- $$PATHPREFIX/QtInputConnection.java \
- $$PATHPREFIX/QtLayout.java \
- $$PATHPREFIX/QtNative.java \
- $$PATHPREFIX/QtNativeLibrariesDir.java \
- $$PATHPREFIX/QtSurface.java
-
-# install
-target.path = $$[QT_INSTALL_PREFIX]/jar
-INSTALLS += target
+TEMPLATE = subdirs
+SUBDIRS += bundledjar.pro distributedjar.pro
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index be618934df..06ece9d04c 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -704,10 +704,8 @@ public class QtActivityDelegate
}
}
- if (keyCode == KeyEvent.KEYCODE_BACK && m_keyboardIsVisible)
- {
- if (!m_keyboardIsHiding)
- hideSoftwareKeyboard();
+ if (keyCode == KeyEvent.KEYCODE_BACK && m_keyboardIsVisible && !m_keyboardIsHiding) {
+ hideSoftwareKeyboard();
return true;
}
diff --git a/src/android/java/AndroidManifest.xml b/src/android/java/AndroidManifest.xml
index 6a407dcb6e..48fb23ab28 100644
--- a/src/android/java/AndroidManifest.xml
+++ b/src/android/java/AndroidManifest.xml
@@ -11,8 +11,12 @@
<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"/>
<meta-data android:name="android.app.lib_name" android:value=""/>
+ <!-- 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="0"/>
+ <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=""/>
<meta-data android:name="android.app.load_local_jars" android:value=""/>
diff --git a/src/android/java/READ-THIS-BEFORE-MANUALLY-ADDING-FILES-TO-PACKAGE.txt b/src/android/java/READ-THIS-BEFORE-MANUALLY-ADDING-FILES-TO-PACKAGE.txt
new file mode 100644
index 0000000000..978417721f
--- /dev/null
+++ b/src/android/java/READ-THIS-BEFORE-MANUALLY-ADDING-FILES-TO-PACKAGE.txt
@@ -0,0 +1,6 @@
+If this package is accessed by Qt Creator, certain changes can be
+overwritten without warning. In particular, Qt Creator may overwrite
+settings which are maintained using its own UI, and files and
+directories containing the string "--Managed_by_Qt_Creator--", as well
+as native libraries whose file names begin with "libQt5" may be
+deleted without warning if they are contained inside this package.
diff --git a/src/android/java/res/values/libs.xml b/src/android/java/res/values/libs.xml
index f47174e3d3..09fa409458 100644
--- a/src/android/java/res/values/libs.xml
+++ b/src/android/java/res/values/libs.xml
@@ -8,4 +8,6 @@
<item>Qt5Core</item>
</array>
<array name="bundled_libs"/>
+ <array name="bundled_in_lib" />
+ <array name="bundled_in_assets" />
</resources>
diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
index dfb638fbb0..22b34fdbef 100644
--- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
+++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
@@ -27,6 +27,11 @@
package org.qtproject.qt5.android.bindings;
import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.FileOutputStream;
+import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
@@ -47,6 +52,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources.Theme;
+import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.net.Uri;
@@ -89,6 +95,8 @@ public class QtActivity extends Activity
private static final String ENVIRONMENT_VARIABLES_KEY = "environment.variables";
private static final String APPLICATION_PARAMETERS_KEY = "application.parameters";
private static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries";
+ private static final String BUNDLED_IN_LIB_RESOURCE_ID_KEY = "android.app.bundled_in_lib_resource_id";
+ private static final String BUNDLED_IN_ASSETS_RESOURCE_ID_KEY = "android.app.bundled_in_assets_resource_id";
private static final String MAIN_LIBRARY_KEY = "main.library";
private static final String STATIC_INIT_CLASSES_KEY = "static.init.classes";
private static final String NECESSITAS_API_LEVEL_KEY = "necessitas.api.level";
@@ -120,6 +128,8 @@ public class QtActivity extends Activity
// note that the android style plugin in Qt 5.1 is not fully functional.
private static final int INCOMPATIBLE_MINISTRO_VERSION = 1; // Incompatible Ministro version. Ministro needs to be upgraded.
+ private static final int BUFFER_SIZE = 1024;
+
private ActivityInfo m_activityInfo = null; // activity info object, used to access the libs and the strings
private DexClassLoader m_classLoader = null; // loader object
private String[] m_sources = {"https://files.kde.org/necessitas/ministro/android/necessitas/qt5/latest"}; // Make sure you are using ONLY secure locations
@@ -308,6 +318,92 @@ public class QtActivity extends Activity
errorDialog.show();
}
+ static private void copyFile(InputStream inputStream, OutputStream outputStream)
+ throws IOException
+ {
+ byte[] buffer = new byte[BUFFER_SIZE];
+
+ int count;
+ while ((count = inputStream.read(buffer)) > 0)
+ outputStream.write(buffer, 0, count);
+ }
+
+
+ private void copyAsset(String source, String destination)
+ throws IOException
+ {
+ // Already exists, we don't have to do anything
+ File destinationFile = new File(destination);
+ if (destinationFile.exists())
+ return;
+
+ File parentDirectory = destinationFile.getParentFile();
+ if (!parentDirectory.exists())
+ parentDirectory.mkdirs();
+
+ destinationFile.createNewFile();
+
+ AssetManager assetsManager = getAssets();
+ InputStream inputStream = assetsManager.open(source);
+ OutputStream outputStream = new FileOutputStream(destinationFile);
+ copyFile(inputStream, outputStream);
+ }
+
+ private static void createBundledBinary(String source, String destination)
+ throws IOException
+ {
+ // Already exists, we don't have to do anything
+ File destinationFile = new File(destination);
+ if (destinationFile.exists())
+ return;
+
+ File parentDirectory = destinationFile.getParentFile();
+ if (!parentDirectory.exists())
+ parentDirectory.mkdirs();
+
+ destinationFile.createNewFile();
+
+ InputStream inputStream = new FileInputStream(source);
+ OutputStream outputStream = new FileOutputStream(destinationFile);
+ copyFile(inputStream, outputStream);
+ }
+
+ private void extractBundledPluginsAndImports(String localPrefix)
+ throws IOException
+ {
+ ArrayList<String> libs = new ArrayList<String>();
+
+ {
+ String key = BUNDLED_IN_LIB_RESOURCE_ID_KEY;
+ java.util.Set<String> keys = m_activityInfo.metaData.keySet();
+ if (m_activityInfo.metaData.containsKey(key)) {
+ String[] list = getResources().getStringArray(m_activityInfo.metaData.getInt(key));
+
+ for (String bundledImportBinary : list) {
+ String[] split = bundledImportBinary.split(":");
+ String sourceFileName = localPrefix + "lib/" + split[0];
+ String destinationFileName = localPrefix + split[1];
+ createBundledBinary(sourceFileName, destinationFileName);
+ }
+ }
+ }
+
+ {
+ String key = BUNDLED_IN_ASSETS_RESOURCE_ID_KEY;
+ if (m_activityInfo.metaData.containsKey(key)) {
+ String[] list = getResources().getStringArray(m_activityInfo.metaData.getInt(key));
+
+ for (String fileName : list) {
+ String[] split = fileName.split(":");
+ String sourceFileName = split[0];
+ String destinationFileName = localPrefix + split[1];
+ copyAsset(sourceFileName, destinationFileName);
+ }
+ }
+
+ }
+ }
+
private void startApp(final boolean firstStart)
{
try {
@@ -328,13 +424,26 @@ public class QtActivity extends Activity
&& m_activityInfo.metaData.getInt("android.app.use_local_qt_libs") == 1) {
ArrayList<String> libraryList = new ArrayList<String>();
+
String localPrefix = "/data/local/tmp/qt/";
if (m_activityInfo.metaData.containsKey("android.app.libs_prefix"))
localPrefix = m_activityInfo.metaData.getString("android.app.libs_prefix");
+ boolean bundlingQtLibs = false;
+ if (m_activityInfo.metaData.containsKey("android.app.bundle_local_qt_libs")
+ && m_activityInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) {
+ localPrefix = getApplicationInfo().dataDir + "/";
+ extractBundledPluginsAndImports(localPrefix);
+ bundlingQtLibs = true;
+ }
+
if (m_qtLibs != null) {
- for (int i=0;i<m_qtLibs.length;i++)
- libraryList.add(localPrefix+"lib/lib"+m_qtLibs[i]+".so");
+ for (int i=0;i<m_qtLibs.length;i++) {
+ libraryList.add(localPrefix
+ + "lib/lib"
+ + m_qtLibs[i]
+ + ".so");
+ }
}
if (m_activityInfo.metaData.containsKey("android.app.load_local_libs")) {
@@ -345,9 +454,10 @@ public class QtActivity extends Activity
}
}
+
String dexPaths = new String();
String pathSeparator = System.getProperty("path.separator", ":");
- if (m_activityInfo.metaData.containsKey("android.app.load_local_jars")) {
+ if (!bundlingQtLibs && m_activityInfo.metaData.containsKey("android.app.load_local_jars")) {
String[] jarFiles = m_activityInfo.metaData.getString("android.app.load_local_jars").split(":");
for (String jar:jarFiles) {
if (jar.length() > 0) {