summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/java/src/org/qtproject/qt/android/bindings/QtLoader.java82
-rw-r--r--src/android/templates/AndroidManifest.xml101
-rw-r--r--src/android/templates/res/values/libs.xml6
-rw-r--r--src/tools/androiddeployqt/main.cpp23
4 files changed, 113 insertions, 99 deletions
diff --git a/src/android/java/src/org/qtproject/qt/android/bindings/QtLoader.java b/src/android/java/src/org/qtproject/qt/android/bindings/QtLoader.java
index 7a122f658a..ef53e91bab 100644
--- a/src/android/java/src/org/qtproject/qt/android/bindings/QtLoader.java
+++ b/src/android/java/src/org/qtproject/qt/android/bindings/QtLoader.java
@@ -1,4 +1,5 @@
/*
+ Copyright (C) 2021 The Qt Company Ltd.
Copyright (c) 2019, BogDan Vatra <bogdan@kde.org>
Contact: http://www.qt.io/licensing/
@@ -42,6 +43,7 @@ import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ComponentInfo;
+import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
@@ -170,28 +172,29 @@ public abstract class QtLoader {
// this function is used to load and start the loader
private void loadApplication(Bundle loaderParams)
{
+ final Resources resources = m_context.getResources();
+ final String packageName = m_context.getPackageName();
try {
final int errorCode = loaderParams.getInt(ERROR_CODE_KEY);
if (errorCode != 0) {
// fatal error, show the error and quit
AlertDialog errorDialog = new AlertDialog.Builder(m_context).create();
errorDialog.setMessage(loaderParams.getString(ERROR_MESSAGE_KEY));
- errorDialog.setButton(m_context.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- finish();
- }
- });
+ errorDialog.setButton(resources.getString(android.R.string.ok),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ finish();
+ }
+ });
errorDialog.show();
return;
}
// add all bundled Qt libs to loader params
- ArrayList<String> libs = new ArrayList<String>();
- if (m_contextInfo.metaData.containsKey("android.app.bundled_libs_resource_id")) {
- int resourceId = m_contextInfo.metaData.getInt("android.app.bundled_libs_resource_id");
- libs.addAll(prefferedAbiLibs(m_context.getResources().getStringArray(resourceId)));
- }
+ int id = resources.getIdentifier("bundled_libs", "array", packageName);
+ final String[] bundledLibs = resources.getStringArray(id);
+ ArrayList<String> libs = new ArrayList<>(prefferedAbiLibs(bundledLibs));
String libName = null;
if (m_contextInfo.metaData.containsKey("android.app.lib_name")) {
@@ -225,17 +228,16 @@ public abstract class QtLoader {
} catch (Exception e) {
e.printStackTrace();
AlertDialog errorDialog = new AlertDialog.Builder(m_context).create();
- if (m_contextInfo.metaData.containsKey("android.app.fatal_error_msg"))
- errorDialog.setMessage(m_contextInfo.metaData.getString("android.app.fatal_error_msg"));
- else
- errorDialog.setMessage("Fatal error, your application can't be started.");
-
- errorDialog.setButton(m_context.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- finish();
- }
- });
+ int id = resources.getIdentifier("fatal_error_msg", "string",
+ packageName);
+ errorDialog.setMessage(resources.getString(id));
+ errorDialog.setButton(resources.getString(android.R.string.ok),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ finish();
+ }
+ });
errorDialog.show();
}
}
@@ -243,14 +245,16 @@ public abstract class QtLoader {
public void startApp(final boolean firstStart)
{
try {
- if (m_contextInfo.metaData.containsKey("android.app.qt_libs_resource_id")) {
- int resourceId = m_contextInfo.metaData.getInt("android.app.qt_libs_resource_id");
- m_qtLibs = prefferedAbiLibs(m_context.getResources().getStringArray(resourceId));
- }
+ final Resources resources = m_context.getResources();
+ final String packageName = m_context.getPackageName();
+ int id = resources.getIdentifier("qt_libs", "array", packageName);
+ m_qtLibs = prefferedAbiLibs(resources.getStringArray(id));
- if (m_contextInfo.metaData.containsKey("android.app.use_local_qt_libs")
- && m_contextInfo.metaData.getInt("android.app.use_local_qt_libs") == 1) {
- ArrayList<String> libraryList = new ArrayList<String>();
+ id = resources.getIdentifier("use_local_qt_libs", "string", packageName);
+ final int useLocalLibs = Integer.parseInt(resources.getString(id));
+
+ if (useLocalLibs == 1) {
+ ArrayList<String> libraryList = new ArrayList<>();
boolean apkDeployFromSystem = false;
String apkPath = m_context.getApplicationInfo().publicSourceDir;
@@ -293,10 +297,13 @@ public abstract class QtLoader {
libraryList.add(libPrefix + lib + ".so");
}
- if (m_contextInfo.metaData.containsKey("android.app.bundle_local_qt_libs")
- && m_contextInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) {
- int resourceId = m_contextInfo.metaData.getInt("android.app.load_local_libs_resource_id");
- for (String libs : prefferedAbiLibs(m_context.getResources().getStringArray(resourceId))) {
+ id = resources.getIdentifier("bundle_local_qt_libs", "string", packageName);
+ final int bundleLocalLibs = Integer.parseInt(resources.getString(id));
+
+ if (bundleLocalLibs == 1) {
+ id = resources.getIdentifier("load_local_libs", "array", packageName);
+ ArrayList<String> localLibs = prefferedAbiLibs(resources.getStringArray(id));
+ for (String libs : localLibs) {
for (String lib : libs.split(":")) {
if (!lib.isEmpty())
libraryList.add(libsDir + lib);
@@ -310,10 +317,11 @@ public abstract class QtLoader {
loaderParams.putInt(ERROR_CODE_KEY, 0);
loaderParams.putString(DEX_PATH_KEY, new String());
loaderParams.putString(LOADER_CLASS_NAME_KEY, loaderClassName());
- if (m_contextInfo.metaData.containsKey("android.app.static_init_classes")) {
- loaderParams.putStringArray(STATIC_INIT_CLASSES_KEY,
- m_contextInfo.metaData.getString("android.app.static_init_classes").split(":"));
- }
+
+ id = resources.getIdentifier("static_init_classes", "string", packageName);
+ loaderParams.putStringArray(STATIC_INIT_CLASSES_KEY, resources.getString(id)
+ .split(":"));
+
loaderParams.putStringArrayList(NATIVE_LIBRARIES_KEY, libraryList);
diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml
index fa520d0345..d352209339 100644
--- a/src/android/templates/AndroidManifest.xml
+++ b/src/android/templates/AndroidManifest.xml
@@ -1,75 +1,82 @@
<?xml version="1.0"?>
-<manifest package="org.qtproject.example" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="-- %%INSERT_VERSION_NAME%% --" android:versionCode="-- %%INSERT_VERSION_CODE%% --" android:installLocation="auto">
- <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
- Remove the comment if you do not require these default permissions. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.qtproject.example"
+ android:installLocation="auto"
+ android:versionCode="-- %%INSERT_VERSION_CODE%% --"
+ android:versionName="-- %%INSERT_VERSION_NAME%% --">
+ <!-- The comment below will be replaced with dependencies permissions upon deployment.
+ Remove the comment if you do not require these default permissions. -->
<!-- %%INSERT_PERMISSIONS -->
- <!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
- Remove the comment if you do not require these default features. -->
+ <!-- The comment below will be replaced with dependencies permissions upon deployment.
+ Remove the comment if you do not require these default features. -->
<!-- %%INSERT_FEATURES -->
- <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
- <application android:hardwareAccelerated="true" android:name="org.qtproject.qt.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --" android:extractNativeLibs="true" android:requestLegacyExternalStorage="true">
- <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name="org.qtproject.qt.android.bindings.QtActivity" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleTop">
+ <supports-screens
+ android:anyDensity="true"
+ android:largeScreens="true"
+ android:normalScreens="true"
+ android:smallScreens="true" />
+ <application
+ android:name="org.qtproject.qt.android.bindings.QtApplication"
+ android:extractNativeLibs="true"
+ android:hardwareAccelerated="true"
+ android:label="-- %%INSERT_APP_NAME%% --"
+ android:requestLegacyExternalStorage="true">
+ <activity
+ android:name="org.qtproject.qt.android.bindings.QtActivity"
+ android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
+ android:label="-- %%INSERT_APP_NAME%% --"
+ android:launchMode="singleTop"
+ android:screenOrientation="unspecified">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
-
- <!-- Application arguments -->
- <meta-data android:name="android.app.arguments" android:value="-- %%INSERT_APP_ARGUMENTS%% --"/>
<!-- Application arguments -->
- <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
- <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="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
+ <meta-data
+ android:name="android.app.arguments"
+ android:value="-- %%INSERT_APP_ARGUMENTS%% --" />
+ <!-- Application arguments -->
+ <meta-data
+ android:name="android.app.lib_name"
+ android:value="-- %%INSERT_APP_LIB_NAME%% --" />
- <!-- Run with local libs -->
- <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
- <meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
- <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
- <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Used to specify custom system library path to run with local system libs -->
- <!-- <meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/> -->
- <!-- Messages maps -->
- <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
- <meta-data android:value="@string/unsupported_android_version" android:name="android.app.unsupported_android_version"/>
- <!-- Messages maps -->
-
+<!-- <meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/>-->
<!-- Splash screen -->
- <!-- Orientation-specific (portrait/landscape) data is checked first. If not available for current orientation,
- then android.app.splash_screen_drawable. For best results, use together with splash_screen_sticky and
- use hideSplashScreen() with a fade-out animation from Qt Android Extras to hide the splash screen when you
- are done populating your window with content. -->
- <!-- meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/logo_portrait" / -->
- <!-- meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/logo_landscape" / -->
- <!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ -->
- <!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
+ <!-- Orientation-specific (portrait/landscape) data is checked first. If not available
+ for current orientation, then android.app.splash_screen_drawable. For best
+ results, use together with splash_screen_sticky and use hideSplashScreen() with
+ a fade-out animation to hide the splash screen when you are done populating
+ your window with content. -->
+<!-- <meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/logo_portrait" />-->
+<!-- <meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/logo_landscape" />-->
+<!-- <meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/>-->
+<!-- <meta-data android:name="android.app.splash_screen_sticky" android:value="true"/>-->
<!-- Splash screen -->
<!-- Background running -->
<!-- Warning: changing this value to true may cause unexpected crashes if the
application still try to draw after
- "applicationStateChanged(Qt::ApplicationSuspended)"
- signal is sent! -->
- <meta-data android:name="android.app.background_running" android:value="false"/>
+ "applicationStateChanged(Qt::ApplicationSuspended)" signal is sent! -->
+ <meta-data
+ android:name="android.app.background_running"
+ android:value="false" />
<!-- Background running -->
<!-- extract android style -->
<!-- available android:values :
- * default - In most cases this will be the same as "full", but it can also be something else if needed, e.g., for compatibility reasons
+ * default - In most cases this will be the same as "full", but it can also be
+ * something else if needed, e.g., for compatibility reasons
* full - useful QWidget & Quick Controls 1 apps
* minimal - useful for Quick Controls 2 apps, it is much faster than "full"
- * none - useful for apps that don't use any of the above Qt modules
- -->
- <meta-data android:name="android.app.extract_android_style" android:value="default"/>
+ * none - useful for apps that don't use any of the above Qt modules -->
+ <meta-data
+ android:name="android.app.extract_android_style"
+ android:value="default" />
<!-- extract android style -->
- </activity>
-
- <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
-
+ </activity>
</application>
-
</manifest>
diff --git a/src/android/templates/res/values/libs.xml b/src/android/templates/res/values/libs.xml
index 280c03c686..beb15ca1d8 100644
--- a/src/android/templates/res/values/libs.xml
+++ b/src/android/templates/res/values/libs.xml
@@ -1,7 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
- <!-- The following is handled automatically by the deployment tool. It should
- not be edited manually. -->
+ <!-- DO NOT EDIT THIS: This file is populated automatically by the deployment tool. -->
<array name="bundled_libs">
<!-- %%INSERT_EXTRA_LIBS%% -->
@@ -15,4 +14,7 @@
<!-- %%INSERT_LOCAL_LIBS%% -->
</array>
+ <string name="static_init_classes"><!-- %%INSERT_INIT_CLASSES%% --></string>
+ <string name="use_local_qt_libs"><!-- %%USE_LOCAL_QT_LIBS%% --></string>
+ <string name="bundle_local_qt_libs"><!-- %%BUNDLE_LOCAL_QT_LIBS%% --></string>
</resources>
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 406acaf54d..7993a0cfb8 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -235,7 +235,6 @@ struct Options
bool usesOpenGL = false;
// Per package collected information
- QStringList localJars;
QStringList initClasses;
QStringList permissions;
QStringList features;
@@ -1411,10 +1410,20 @@ bool updateLibsXml(Options *options)
allLocalLibs += QLatin1String(" <item>%1;%2</item>\n").arg(it.key(), localLibs.join(QLatin1Char(':')));
}
+ options->initClasses.removeDuplicates();
+
QHash<QString, QString> replacements;
replacements[QStringLiteral("<!-- %%INSERT_QT_LIBS%% -->")] += qtLibs.trimmed();
replacements[QStringLiteral("<!-- %%INSERT_LOCAL_LIBS%% -->")] = allLocalLibs.trimmed();
replacements[QStringLiteral("<!-- %%INSERT_EXTRA_LIBS%% -->")] = extraLibs.trimmed();
+ const QString initClasses = options->initClasses.join(QLatin1Char(':'));
+ replacements[QStringLiteral("<!-- %%INSERT_INIT_CLASSES%% -->")] = initClasses;
+
+ // Bundle and use libs from the apk because currently we don't have a way avoid
+ // duplicating them.
+ replacements[QStringLiteral("<!-- %%BUNDLE_LOCAL_QT_LIBS%% -->")] = QLatin1String("1");
+ replacements[QStringLiteral("<!-- %%USE_LOCAL_QT_LIBS%% -->")] = QLatin1String("1");
+
if (!updateFile(fileName, replacements))
return false;
@@ -1456,22 +1465,13 @@ bool updateAndroidManifest(Options &options)
if (options.verbose)
fprintf(stdout, " -- AndroidManifest.xml \n");
- options.localJars.removeDuplicates();
- options.initClasses.removeDuplicates();
-
QHash<QString, QString> replacements;
replacements[QStringLiteral("-- %%INSERT_APP_NAME%% --")] = options.applicationBinary;
replacements[QStringLiteral("-- %%INSERT_APP_ARGUMENTS%% --")] = options.applicationArguments;
replacements[QStringLiteral("-- %%INSERT_APP_LIB_NAME%% --")] = options.applicationBinary;
- replacements[QStringLiteral("-- %%INSERT_LOCAL_JARS%% --")] = options.localJars.join(QLatin1Char(':'));
- replacements[QStringLiteral("-- %%INSERT_INIT_CLASSES%% --")] = options.initClasses.join(QLatin1Char(':'));
replacements[QStringLiteral("-- %%INSERT_VERSION_NAME%% --")] = options.versionName;
replacements[QStringLiteral("-- %%INSERT_VERSION_CODE%% --")] = options.versionCode;
replacements[QStringLiteral("package=\"org.qtproject.example\"")] = QLatin1String("package=\"%1\"").arg(options.packageName);
- replacements[QStringLiteral("-- %%BUNDLE_LOCAL_QT_LIBS%% --")]
- = (options.deploymentMechanism == Options::Bundled) ? QLatin1String("1") : QLatin1String("0");
- // use libs from the apk
- replacements[QStringLiteral("-- %%USE_LOCAL_QT_LIBS%% --")] = QLatin1String("1");
QString permissions;
for (const QString &permission : qAsConst(options.permissions))
@@ -1664,9 +1664,6 @@ bool readAndroidDependencyXml(Options *options,
}
}
- if (!fileName.isEmpty())
- options->localJars.append(fileName);
-
if (reader.attributes().hasAttribute(QLatin1String("initClass"))) {
options->initClasses.append(reader.attributes().value(QLatin1String("initClass")).toString());
}