summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/jar/CMakeLists.txt5
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java349
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java334
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtActivityLoader.java18
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtApplicationBase.java17
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtLoader.java182
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtServiceBase.java58
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtServiceDelegate.java23
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtServiceLoader.java18
-rw-r--r--src/android/java/src/org/qtproject/qt/android/bindings/QtActivity.java388
-rw-r--r--src/android/java/src/org/qtproject/qt/android/bindings/QtApplication.java22
-rw-r--r--src/android/java/src/org/qtproject/qt/android/bindings/QtService.java76
12 files changed, 539 insertions, 951 deletions
diff --git a/src/android/jar/CMakeLists.txt b/src/android/jar/CMakeLists.txt
index 31e09458d0..dd6a1dacba 100644
--- a/src/android/jar/CMakeLists.txt
+++ b/src/android/jar/CMakeLists.txt
@@ -8,7 +8,11 @@ set(java_sources
src/org/qtproject/qt/android/EditContextView.java
src/org/qtproject/qt/android/EditPopupMenu.java
src/org/qtproject/qt/android/ExtractStyle.java
+ src/org/qtproject/qt/android/QtApplicationBase.java
+ src/org/qtproject/qt/android/QtActivityBase.java
+ src/org/qtproject/qt/android/QtServiceBase.java
src/org/qtproject/qt/android/QtActivityDelegate.java
+ src/org/qtproject/qt/android/QtServiceDelegate.java
src/org/qtproject/qt/android/QtLoader.java
src/org/qtproject/qt/android/QtActivityLoader.java
src/org/qtproject/qt/android/QtServiceLoader.java
@@ -20,7 +24,6 @@ set(java_sources
src/org/qtproject/qt/android/QtNativeLibrariesDir.java
src/org/qtproject/qt/android/QtSurface.java
src/org/qtproject/qt/android/QtThread.java
- src/org/qtproject/qt/android/QtServiceDelegate.java
src/org/qtproject/qt/android/extras//QtAndroidBinder.java
src/org/qtproject/qt/android/extras/QtAndroidServiceConnection.java
src/org/qtproject/qt/android/extras/QtNative.java
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java
new file mode 100644
index 0000000000..fe2eaf0b9d
--- /dev/null
+++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java
@@ -0,0 +1,349 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+package org.qtproject.qt.android;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.provider.Browser;
+import android.text.method.MetaKeyKeyListener;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class QtActivityBase extends Activity
+{
+ private long m_metaState;
+ public boolean m_backKeyPressedSent = false;
+
+ private boolean m_optionsMenuIsVisible = false;
+
+ // use this variable to pass any parameters to your application,
+ // the parameters must not contain any white spaces
+ // and must be separated with "\t"
+ // e.g "-param1\t-param2=value2\t-param3\tvalue3"
+ public String APPLICATION_PARAMETERS = null;
+
+ // use this variable to add any environment variables to your application.
+ // the env vars must be separated with "\t"
+ // e.g. "ENV_VAR1=1\tENV_VAR2=2\t"
+ // Currently the following vars are used by the android plugin:
+ // * QT_USE_ANDROID_NATIVE_DIALOGS - 1 to use the android native dialogs.
+ public String ENVIRONMENT_VARIABLES = "QT_USE_ANDROID_NATIVE_DIALOGS=1";
+
+ // A list with all themes that your application want to use.
+ // The name of the theme must be the same with any theme from
+ // http://developer.android.com/reference/android/R.style.html
+ // The most used themes are:
+ // * "Theme_Light" - (default for API <=10) check http://developer.android.com/reference/android/R.style.html#Theme_Light
+ // * "Theme_Holo" - check http://developer.android.com/reference/android/R.style.html#Theme_Holo
+ // * "Theme_Holo_Light" - (default for API 11-13) check http://developer.android.com/reference/android/R.style.html#Theme_Holo_Light
+ public String[] QT_ANDROID_THEMES = null;
+
+ public String QT_ANDROID_DEFAULT_THEME = null; // sets the default theme.
+
+ private final QtActivityLoader m_loader = new QtActivityLoader(this);
+
+ private final QtActivityDelegate m_delegate = new QtActivityDelegate();
+
+ protected void onCreateHook(Bundle savedInstanceState) {
+ m_loader.APPLICATION_PARAMETERS = APPLICATION_PARAMETERS;
+ m_loader.ENVIRONMENT_VARIABLES = ENVIRONMENT_VARIABLES;
+ m_loader.QT_ANDROID_THEMES = QT_ANDROID_THEMES;
+ m_loader.QT_ANDROID_DEFAULT_THEME = QT_ANDROID_DEFAULT_THEME;
+ m_loader.onCreate(savedInstanceState);
+ }
+
+ public static final String EXTRA_SOURCE_INFO = "org.qtproject.qt.android.sourceInfo";
+
+ private void addReferrer(Intent intent)
+ {
+ if (intent.getExtras() != null && intent.getExtras().getString(EXTRA_SOURCE_INFO) != null)
+ return;
+
+ String browserApplicationId = "";
+ if (intent.getExtras() != null)
+ browserApplicationId = intent.getExtras().getString(Browser.EXTRA_APPLICATION_ID);
+
+ String sourceInformation = "";
+ if (browserApplicationId != null && !browserApplicationId.isEmpty()) {
+ sourceInformation = browserApplicationId;
+ } else {
+ Uri referrer = getReferrer();
+ if (referrer != null)
+ sourceInformation = referrer.toString().replaceFirst("android-app://", "");
+ }
+
+ intent.putExtra(EXTRA_SOURCE_INFO, sourceInformation);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ onCreateHook(savedInstanceState);
+ addReferrer(getIntent());
+ }
+
+ @Override
+ protected void onStart()
+ {
+ super.onStart();
+ }
+
+ @Override
+ protected void onRestart()
+ {
+ super.onRestart();
+ }
+
+ @Override
+ protected void onPause()
+ {
+ super.onPause();
+ if (Build.VERSION.SDK_INT < 24 || !isInMultiWindowMode())
+ QtNative.setApplicationState(QtConstants.ApplicationState.ApplicationInactive);
+ }
+
+ @Override
+ protected void onResume()
+ {
+ super.onResume();
+ QtNative.setApplicationState(QtConstants.ApplicationState.ApplicationActive);
+ if (m_delegate.isStarted()) {
+ QtNative.updateWindow();
+ m_delegate.updateFullScreen(); // Suspending the app clears the immersive mode, so we need to set it again.
+ }
+ }
+
+ @Override
+ protected void onStop()
+ {
+ super.onStop();
+ QtNative.setApplicationState(QtConstants.ApplicationState.ApplicationSuspended);
+ }
+
+ @Override
+ protected void onDestroy()
+ {
+ super.onDestroy();
+ if (m_delegate.isQuitApp()) {
+ QtNative.terminateQt();
+ QtNative.setActivity(null, null);
+ QtNative.m_qtThread.exit();
+ System.exit(0);
+ }
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event)
+ {
+ if (m_delegate.isStarted()
+ && event.getAction() == KeyEvent.ACTION_MULTIPLE
+ && event.getCharacters() != null
+ && event.getCharacters().length() == 1
+ && event.getKeyCode() == 0) {
+ QtNative.keyDown(0, event.getCharacters().charAt(0), event.getMetaState(), event.getRepeatCount() > 0);
+ QtNative.keyUp(0, event.getCharacters().charAt(0), event.getMetaState(), event.getRepeatCount() > 0);
+ }
+
+ if (QtNative.dispatchKeyEvent(event))
+ return true;
+
+ return super.dispatchKeyEvent(event);
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig)
+ {
+ super.onConfigurationChanged(newConfig);
+ m_delegate.handleUiModeChange(newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK);
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item)
+ {
+ m_delegate.setContextMenuVisible(false);
+ return QtNative.onContextItemSelected(item.getItemId(), item.isChecked());
+ }
+
+ @Override
+ public void onContextMenuClosed(Menu menu)
+ {
+ if (!m_delegate.isContextMenuVisible())
+ return;
+ m_delegate.setContextMenuVisible(false);
+ QtNative.onContextMenuClosed(menu);
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
+ {
+ menu.clearHeader();
+ QtNative.onCreateContextMenu(menu);
+ m_delegate.setContextMenuVisible(true);
+ }
+
+ private int m_lastChar = 0;
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event)
+ {
+ if (!m_delegate.isStarted() || !m_delegate.isPluginRunning())
+ return false;
+
+ m_metaState = MetaKeyKeyListener.handleKeyDown(m_metaState, keyCode, event);
+ int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(m_metaState) | event.getMetaState());
+ int lc = c;
+ m_metaState = MetaKeyKeyListener.adjustMetaAfterKeypress(m_metaState);
+
+ if ((c & KeyCharacterMap.COMBINING_ACCENT) != 0) {
+ c = c & KeyCharacterMap.COMBINING_ACCENT_MASK;
+ c = KeyEvent.getDeadChar(m_lastChar, c);
+ }
+
+ if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP
+ || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
+ || keyCode == KeyEvent.KEYCODE_MUTE)
+ && System.getenv("QT_ANDROID_VOLUME_KEYS") == null) {
+ return false;
+ }
+
+ m_lastChar = lc;
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ m_backKeyPressedSent = !m_delegate.isKeyboardVisible();
+ if (!m_backKeyPressedSent)
+ return true;
+ }
+ QtNative.keyDown(keyCode, c, event.getMetaState(), event.getRepeatCount() > 0);
+
+ return true;
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event)
+ {
+ if (!m_delegate.isStarted() || !m_delegate.isPluginRunning())
+ return false;
+
+ if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP
+ || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
+ || keyCode == KeyEvent.KEYCODE_MUTE)
+ && System.getenv("QT_ANDROID_VOLUME_KEYS") == null) {
+ return false;
+ }
+
+ if (keyCode == KeyEvent.KEYCODE_BACK && !m_backKeyPressedSent) {
+ m_delegate.hideSoftwareKeyboard();
+ m_delegate.setKeyboardVisibility(false, System.nanoTime());
+ return true;
+ }
+
+ m_metaState = MetaKeyKeyListener.handleKeyUp(m_metaState, keyCode, event);
+ QtNative.keyUp(keyCode, event.getUnicodeChar(), event.getMetaState(), event.getRepeatCount() > 0);
+ return true;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ menu.clear();
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu)
+ {
+ m_optionsMenuIsVisible = true;
+ boolean res = QtNative.onPrepareOptionsMenu(menu);
+ m_delegate.setActionBarVisibility(res && menu.size() > 0);
+ return res;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ return QtNative.onOptionsItemSelected(item.getItemId(), item.isChecked());
+ }
+
+ @Override
+ public void onOptionsMenuClosed(Menu menu)
+ {
+ m_optionsMenuIsVisible = false;
+ QtNative.onOptionsMenuClosed(menu);
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState)
+ {
+ super.onRestoreInstanceState(savedInstanceState);
+ m_delegate.setStarted(savedInstanceState.getBoolean("Started"));
+ // FIXME restore all surfaces
+ }
+
+ @Override
+ public Object onRetainNonConfigurationInstance()
+ {
+ super.onRetainNonConfigurationInstance();
+ m_delegate.setQuitApp(false);
+ return true;
+
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState)
+ {
+ super.onSaveInstanceState(outState);
+ outState.putInt("SystemUiVisibility", m_delegate.systemUiVisibility());
+ outState.putBoolean("Started", m_delegate.isStarted());
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus)
+ {
+ super.onWindowFocusChanged(hasFocus);
+ if (hasFocus)
+ m_delegate.updateFullScreen();
+ }
+
+ @Override
+ public boolean dispatchGenericMotionEvent(MotionEvent ev)
+ {
+ if (m_delegate.isStarted() && QtNative.dispatchGenericMotionEvent(ev))
+ return true;
+
+ return super.dispatchGenericMotionEvent(ev);
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent)
+ {
+ QtNative.onNewIntent(intent);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data)
+ {
+ super.onActivityResult(requestCode, resultCode, data);
+ QtNative.onActivityResult(requestCode, resultCode, data);
+ }
+
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
+ {
+ QtNative.sendRequestPermissionsResult(requestCode, permissions, grantResults);
+ }
+
+ QtActivityDelegate getActivityDelegate()
+ {
+ return m_delegate;
+ }
+}
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java
index cc6aed569f..b180685af5 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java
@@ -1,5 +1,5 @@
// Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
-// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
@@ -71,16 +71,6 @@ import static org.qtproject.qt.android.QtConstants.*;
public class QtActivityDelegate
{
private Activity m_activity = null;
- private Method m_super_dispatchKeyEvent = null;
- private Method m_super_onRestoreInstanceState = null;
- private Method m_super_onRetainNonConfigurationInstance = null;
- private Method m_super_onSaveInstanceState = null;
- private Method m_super_onKeyDown = null;
- private Method m_super_onKeyUp = null;
- private Method m_super_onConfigurationChanged = null;
- private Method m_super_onActivityResult = null;
- private Method m_super_dispatchGenericMotionEvent = null;
- private Method m_super_onWindowFocusChanged = null;
// Keep in sync with QtAndroid::SystemUiVisibility in androidjnimain.h
public static final int SYSTEM_UI_VISIBILITY_NORMAL = 0;
@@ -93,8 +83,6 @@ public class QtActivityDelegate
private int m_nativeOrientation = Configuration.ORIENTATION_UNDEFINED;
private String m_mainLib;
- private long m_metaState;
- private int m_lastChar = 0;
private int m_softInputMode = 0;
private int m_systemUiVisibility = SYSTEM_UI_VISIBILITY_NORMAL;
private boolean m_started = false;
@@ -108,7 +96,6 @@ public class QtActivityDelegate
private boolean m_quitApp = true;
private View m_dummyView = null;
private boolean m_keyboardIsVisible = false;
- public boolean m_backKeyPressedSent = false;
private long m_showHideTimeStamp = System.nanoTime();
private int m_portraitKeyboardHeight = 0;
private int m_landscapeKeyboardHeight = 0;
@@ -122,6 +109,9 @@ public class QtActivityDelegate
private QtAccessibilityDelegate m_accessibilityDelegate = null;
+ QtActivityDelegate() { }
+
+
public void setSystemUiVisibility(int systemUiVisibility)
{
if (m_systemUiVisibility == systemUiVisibility)
@@ -442,6 +432,46 @@ public class QtActivityDelegate
});
}
+ void setStarted(boolean started)
+ {
+ m_started = started;
+ }
+
+ boolean isStarted()
+ {
+ return m_started;
+ }
+
+ void setQuitApp(boolean quitApp)
+ {
+ m_quitApp = quitApp;
+ }
+
+ boolean isQuitApp()
+ {
+ return m_quitApp;
+ }
+
+ boolean isPluginRunning()
+ {
+ return m_isPluginRunning;
+ }
+
+ int systemUiVisibility()
+ {
+ return m_systemUiVisibility;
+ }
+
+ void setContextMenuVisible(boolean contextMenuVisible)
+ {
+ m_contextMenuVisible = contextMenuVisible;
+ }
+
+ boolean isContextMenuVisible()
+ {
+ return m_contextMenuVisible;
+ }
+
int getAppIconSize(Activity a)
{
int size = a.getResources().getDimensionPixelSize(android.R.dimen.app_icon_size);
@@ -625,28 +655,6 @@ public class QtActivityDelegate
QtNative.setActivity(m_activity, this);
setActionBarVisibility(false);
- Class<?> activityClass = m_activity.getClass();
- m_super_dispatchKeyEvent =
- activityClass.getMethod("super_dispatchKeyEvent", KeyEvent.class);
- m_super_onRestoreInstanceState =
- activityClass.getMethod("super_onRestoreInstanceState", Bundle.class);
- m_super_onRetainNonConfigurationInstance =
- activityClass.getMethod("super_onRetainNonConfigurationInstance");
- m_super_onSaveInstanceState =
- activityClass.getMethod("super_onSaveInstanceState", Bundle.class);
- m_super_onKeyDown =
- activityClass.getMethod("super_onKeyDown", Integer.TYPE, KeyEvent.class);
- m_super_onKeyUp =
- activityClass.getMethod("super_onKeyUp", Integer.TYPE, KeyEvent.class);
- m_super_onConfigurationChanged =
- activityClass.getMethod("super_onConfigurationChanged", Configuration.class);
- m_super_onActivityResult =
- activityClass.getMethod("super_onActivityResult", Integer.TYPE, Integer.TYPE, Intent.class);
- m_super_onWindowFocusChanged =
- activityClass.getMethod("super_onWindowFocusChanged", Boolean.TYPE);
- m_super_dispatchGenericMotionEvent =
- activityClass.getMethod("super_dispatchGenericMotionEvent", MotionEvent.class);
-
m_softInputMode = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), 0).softInputMode;
DisplayManager displayManager = (DisplayManager)m_activity.getSystemService(Context.DISPLAY_SERVICE);
@@ -948,7 +956,6 @@ public class QtActivityDelegate
m_accessibilityDelegate.notifyScrolledEvent(viewId);
}
-
public void notifyQtAndroidPluginRunning(boolean running)
{
m_isPluginRunning = running;
@@ -959,22 +966,12 @@ public class QtActivityDelegate
m_accessibilityDelegate = new QtAccessibilityDelegate(m_activity, m_layout, this);
}
- public void onWindowFocusChanged(boolean hasFocus) {
- try {
- m_super_onWindowFocusChanged.invoke(m_activity, hasFocus);
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (hasFocus)
- updateFullScreen();
- }
-
boolean isUiModeDark(Configuration config)
{
return (config.uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
}
- private void handleUiModeChange(int uiMode)
+ void handleUiModeChange(int uiMode)
{
// QTBUG-108365
if (Build.VERSION.SDK_INT >= 30) {
@@ -1001,215 +998,12 @@ public class QtActivityDelegate
}
}
- public void onConfigurationChanged(Configuration configuration)
- {
- try {
- m_super_onConfigurationChanged.invoke(m_activity, configuration);
- } catch (Exception e) {
- e.printStackTrace();
- }
- handleUiModeChange(configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK);
- }
-
- public void onDestroy()
- {
- if (m_quitApp) {
- QtNative.terminateQt();
- QtNative.setActivity(null, null);
- QtNative.m_qtThread.exit();
- System.exit(0);
- }
- }
-
- public void onPause()
- {
- if (Build.VERSION.SDK_INT < 24 || !m_activity.isInMultiWindowMode())
- QtNative.setApplicationState(ApplicationState.ApplicationInactive);
- }
-
- public void onResume()
- {
- QtNative.setApplicationState(ApplicationState.ApplicationActive);
- if (m_started) {
- QtNative.updateWindow();
- updateFullScreen(); // Suspending the app clears the immersive mode, so we need to set it again.
- }
- }
-
- public void onNewIntent(Intent data)
- {
- QtNative.onNewIntent(data);
- }
-
- public void onActivityResult(int requestCode, int resultCode, Intent data)
- {
- try {
- m_super_onActivityResult.invoke(m_activity, requestCode, resultCode, data);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- QtNative.onActivityResult(requestCode, resultCode, data);
- }
-
-
- public void onStop()
- {
- QtNative.setApplicationState(ApplicationState.ApplicationSuspended);
- }
-
- public Object onRetainNonConfigurationInstance()
- {
- try {
- m_super_onRetainNonConfigurationInstance.invoke(m_activity);
- } catch (Exception e) {
- e.printStackTrace();
- }
- m_quitApp = false;
- return true;
- }
-
- public void onSaveInstanceState(Bundle outState) {
- try {
- m_super_onSaveInstanceState.invoke(m_activity, outState);
- } catch (Exception e) {
- e.printStackTrace();
- }
- outState.putInt("SystemUiVisibility", m_systemUiVisibility);
- outState.putBoolean("Started", m_started);
- // It should never
- }
-
- public void onRestoreInstanceState(Bundle savedInstanceState)
- {
- try {
- m_super_onRestoreInstanceState.invoke(m_activity, savedInstanceState);
- } catch (Exception e) {
- e.printStackTrace();
- }
- m_started = savedInstanceState.getBoolean("Started");
- // FIXME restore all surfaces
-
- }
-
- public boolean onKeyDown(int keyCode, KeyEvent event)
- {
- if (!m_started || !m_isPluginRunning)
- return false;
-
- m_metaState = MetaKeyKeyListener.handleKeyDown(m_metaState, keyCode, event);
- int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(m_metaState) | event.getMetaState());
- int lc = c;
- m_metaState = MetaKeyKeyListener.adjustMetaAfterKeypress(m_metaState);
-
- if ((c & KeyCharacterMap.COMBINING_ACCENT) != 0) {
- c = c & KeyCharacterMap.COMBINING_ACCENT_MASK;
- int composed = KeyEvent.getDeadChar(m_lastChar, c);
- c = composed;
- }
-
- if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP
- || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
- || keyCode == KeyEvent.KEYCODE_MUTE)
- && System.getenv("QT_ANDROID_VOLUME_KEYS") == null) {
- return false;
- }
-
- m_lastChar = lc;
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- m_backKeyPressedSent = !m_keyboardIsVisible;
- if (!m_backKeyPressedSent)
- return true;
- }
- QtNative.keyDown(keyCode, c, event.getMetaState(), event.getRepeatCount() > 0);
-
- return true;
- }
-
- public boolean onKeyUp(int keyCode, KeyEvent event)
- {
- if (!m_started || !m_isPluginRunning)
- return false;
-
- if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP
- || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
- || keyCode == KeyEvent.KEYCODE_MUTE)
- && System.getenv("QT_ANDROID_VOLUME_KEYS") == null) {
- return false;
- }
-
- if (keyCode == KeyEvent.KEYCODE_BACK && !m_backKeyPressedSent) {
- hideSoftwareKeyboard();
- setKeyboardVisibility(false, System.nanoTime());
- return true;
- }
-
- m_metaState = MetaKeyKeyListener.handleKeyUp(m_metaState, keyCode, event);
- QtNative.keyUp(keyCode, event.getUnicodeChar(), event.getMetaState(), event.getRepeatCount() > 0);
- return true;
- }
-
- public boolean dispatchKeyEvent(KeyEvent event)
- {
- if (m_started
- && event.getAction() == KeyEvent.ACTION_MULTIPLE
- && event.getCharacters() != null
- && event.getCharacters().length() == 1
- && event.getKeyCode() == 0) {
- QtNative.keyDown(0, event.getCharacters().charAt(0), event.getMetaState(), event.getRepeatCount() > 0);
- QtNative.keyUp(0, event.getCharacters().charAt(0), event.getMetaState(), event.getRepeatCount() > 0);
- }
-
- if (QtNative.dispatchKeyEvent(event))
- return true;
-
- try {
- return (Boolean) m_super_dispatchKeyEvent.invoke(m_activity, event);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return false;
- }
-
- private boolean m_optionsMenuIsVisible = false;
- public boolean onCreateOptionsMenu(Menu menu)
- {
- menu.clear();
- return true;
- }
- public boolean onPrepareOptionsMenu(Menu menu)
- {
- m_optionsMenuIsVisible = true;
- boolean res = QtNative.onPrepareOptionsMenu(menu);
- setActionBarVisibility(res && menu.size() > 0);
- return res;
- }
-
- public boolean onOptionsItemSelected(MenuItem item)
- {
- return QtNative.onOptionsItemSelected(item.getItemId(), item.isChecked());
- }
-
- public void onOptionsMenuClosed(Menu menu)
- {
- m_optionsMenuIsVisible = false;
- QtNative.onOptionsMenuClosed(menu);
- }
-
public void resetOptionsMenu()
{
m_activity.invalidateOptionsMenu();
}
private boolean m_contextMenuVisible = false;
- public void onCreateContextMenu(ContextMenu menu,
- View v,
- ContextMenuInfo menuInfo)
- {
- menu.clearHeader();
- QtNative.onCreateContextMenu(menu);
- m_contextMenuVisible = true;
- }
public void onCreatePopupMenu(Menu menu)
{
@@ -1217,20 +1011,6 @@ public class QtActivityDelegate
m_contextMenuVisible = true;
}
- public void onContextMenuClosed(Menu menu)
- {
- if (!m_contextMenuVisible)
- return;
- m_contextMenuVisible = false;
- QtNative.onContextMenuClosed(menu);
- }
-
- public boolean onContextItemSelected(MenuItem item)
- {
- m_contextMenuVisible = false;
- return QtNative.onContextItemSelected(item.getItemId(), item.isChecked());
- }
-
public void openContextMenu(final int x, final int y, final int w, final int h)
{
m_layout.postDelayed(new Runnable() {
@@ -1242,13 +1022,13 @@ public class QtActivityDelegate
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
- return QtActivityDelegate.this.onContextItemSelected(menuItem);
+ return m_activity.onContextItemSelected(menuItem);
}
});
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
@Override
public void onDismiss(PopupMenu popupMenu) {
- QtActivityDelegate.this.onContextMenuClosed(popupMenu.getMenu());
+ m_activity.onContextMenuClosed(popupMenu.getMenu());
}
});
popup.show();
@@ -1261,7 +1041,7 @@ public class QtActivityDelegate
m_activity.closeContextMenu();
}
- private void setActionBarVisibility(boolean visible)
+ void setActionBarVisibility(boolean visible)
{
if (m_activity.getActionBar() == null)
return;
@@ -1398,22 +1178,4 @@ public class QtActivityDelegate
m_layout.moveChild(view, index);
}
}
-
- public boolean dispatchGenericMotionEvent (MotionEvent ev)
- {
- if (m_started && QtNative.dispatchGenericMotionEvent(ev))
- return true;
-
- try {
- return (Boolean) m_super_dispatchGenericMotionEvent.invoke(m_activity, ev);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return false;
- }
-
- public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
- {
- QtNative.sendRequestPermissionsResult(requestCode, permissions, grantResults);
- }
}
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityLoader.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityLoader.java
index 1c8cc99950..d9cfa2f79d 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtActivityLoader.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityLoader.java
@@ -16,23 +16,13 @@ import java.lang.reflect.Field;
public class QtActivityLoader extends QtLoader {
Activity m_activity;
- public QtActivityLoader(Activity activity, Class<?> clazz)
+ public QtActivityLoader(Activity activity)
{
- super(activity, clazz);
+ super(activity);
m_activity = activity;
}
@Override
- protected String loaderClassName() {
- return "org.qtproject.qt.android.QtActivityDelegate";
- }
-
- @Override
- protected Class<?> contextClassName() {
- return android.app.Activity.class;
- }
-
- @Override
protected void finish() {
m_activity.finish();
}
@@ -88,9 +78,7 @@ public class QtActivityLoader extends QtLoader {
Runtime.getRuntime().exit(0);
}
- // there can only be a valid delegate object if the QtNative was started.
- if (m_delegateObject != null && onCreate != null)
- invokeDelegateMethod(onCreate, savedInstanceState);
+ ((QtActivityBase)m_activity).getActivityDelegate().onCreate(savedInstanceState);
return;
}
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtApplicationBase.java b/src/android/jar/src/org/qtproject/qt/android/QtApplicationBase.java
new file mode 100644
index 0000000000..5ecb1597fe
--- /dev/null
+++ b/src/android/jar/src/org/qtproject/qt/android/QtApplicationBase.java
@@ -0,0 +1,17 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+package org.qtproject.qt.android;
+
+import android.app.Application;
+
+public class QtApplicationBase extends Application {
+ public final static String QtTAG = "Qt";
+
+ @Override
+ public void onTerminate() {
+ QtNative.terminateQt();
+ QtNative.m_qtThread.exit();
+ super.onTerminate();
+ }
+}
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtLoader.java b/src/android/jar/src/org/qtproject/qt/android/QtLoader.java
index 168ce15ea3..74cc2e29c8 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtLoader.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtLoader.java
@@ -36,71 +36,18 @@ public abstract class QtLoader {
// These parameters matter in case of deploying application as system (embedded into firmware)
public static final String SYSTEM_LIB_PATH = "/system/lib/";
- public String APPLICATION_PARAMETERS = null; // use this variable to pass any parameters to your application,
- // the parameters must not contain any white spaces
- // and must be separated with "\t"
- // e.g "-param1\t-param2=value2\t-param3\tvalue3"
-
+ public String APPLICATION_PARAMETERS = null;
public String ENVIRONMENT_VARIABLES = "QT_USE_ANDROID_NATIVE_DIALOGS=1";
- // use this variable to add any environment variables to your application.
- // the env vars must be separated with "\t"
- // e.g. "ENV_VAR1=1\tENV_VAR2=2\t"
- // Currently the following vars are used by the android plugin:
- // * QT_USE_ANDROID_NATIVE_DIALOGS -1 to use the android native dialogs.
-
- public String[] QT_ANDROID_THEMES = null; // A list with all themes that your application want to use.
- // The name of the theme must be the same with any theme from
- // http://developer.android.com/reference/android/R.style.html
- // The most used themes are:
- // * "Theme" - (fallback) check http://developer.android.com/reference/android/R.style.html#Theme
- // * "Theme_Black" - check http://developer.android.com/reference/android/R.style.html#Theme_Black
- // * "Theme_Light" - (default for API <=10) check http://developer.android.com/reference/android/R.style.html#Theme_Light
- // * "Theme_Holo" - check http://developer.android.com/reference/android/R.style.html#Theme_Holo
- // * "Theme_Holo_Light" - (default for API 11-13) check http://developer.android.com/reference/android/R.style.html#Theme_Holo_Light
- // * "Theme_DeviceDefault" - check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault
- // * "Theme_DeviceDefault_Light" - (default for API 14+) check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault_Light
-
+ public String[] QT_ANDROID_THEMES = null;
public String QT_ANDROID_DEFAULT_THEME = null; // sets the default theme.
public ArrayList<String> m_qtLibs = null; // required qt libs
public int m_displayDensity = -1;
private ContextWrapper m_context;
protected ComponentInfo m_contextInfo;
- private Class<?> m_delegateClass;
-
- private static ArrayList<FileOutputStream> m_fileOutputStreams = new ArrayList<FileOutputStream>();
- // List of open file streams associated with files copied during installation.
-
- public static Object m_delegateObject = null;
- public static HashMap<String, ArrayList<Method>> m_delegateMethods= new HashMap<String, ArrayList<Method>>();
- public static Method dispatchKeyEvent = null;
- public static Method dispatchPopulateAccessibilityEvent = null;
- public static Method dispatchTouchEvent = null;
- public static Method dispatchTrackballEvent = null;
- public static Method onKeyDown = null;
- public static Method onKeyMultiple = null;
- public static Method onKeyUp = null;
- public static Method onTouchEvent = null;
- public static Method onTrackballEvent = null;
- public static Method onActivityResult = null;
- public static Method onCreate = null;
- public static Method onKeyLongPress = null;
- public static Method dispatchKeyShortcutEvent = null;
- public static Method onKeyShortcut = null;
- public static Method dispatchGenericMotionEvent = null;
- public static Method onGenericMotionEvent = null;
- public static Method onRequestPermissionsResult = null;
- private static String activityClassName;
- private static Class qtApplicationClass = null;
-
- public QtLoader(ContextWrapper context, Class<?> clazz) {
- m_context = context;
- m_delegateClass = clazz;
- }
- public static void setQtApplicationClass(Class qtAppClass)
- {
- qtApplicationClass = qtAppClass;
+ public QtLoader(ContextWrapper context) {
+ m_context = context;
}
public static void setQtTAG(String tag)
@@ -108,93 +55,6 @@ public abstract class QtLoader {
QtTAG = tag;
}
- public static void setQtContextDelegate(Class<?> clazz, Object listener)
- {
- m_delegateObject = listener;
- activityClassName = clazz.getCanonicalName();
-
- ArrayList<Method> delegateMethods = new ArrayList<Method>();
- for (Method m : listener.getClass().getMethods()) {
- if (m.getDeclaringClass().getName().startsWith("org.qtproject.qt.android"))
- delegateMethods.add(m);
- }
-
- ArrayList<Field> applicationFields = new ArrayList<Field>();
- for (Field f : qtApplicationClass.getFields()) {
- if (f.getDeclaringClass().getName().equals(qtApplicationClass.getName()))
- applicationFields.add(f);
- }
-
- for (Method delegateMethod : delegateMethods) {
- try {
- clazz.getDeclaredMethod(delegateMethod.getName(), delegateMethod.getParameterTypes());
- if (m_delegateMethods.containsKey(delegateMethod.getName())) {
- m_delegateMethods.get(delegateMethod.getName()).add(delegateMethod);
- } else {
- ArrayList<Method> delegateSet = new ArrayList<Method>();
- delegateSet.add(delegateMethod);
- m_delegateMethods.put(delegateMethod.getName(), delegateSet);
- }
- for (Field applicationField:applicationFields) {
- if (applicationField.getName().equals(delegateMethod.getName())) {
- try {
- applicationField.set(null, delegateMethod);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- } catch (Exception e) { }
- }
- }
-
- public static class InvokeResult
- {
- public boolean invoked = false;
- public Object methodReturns = null;
- }
-
- private static int stackDeep=-1;
- public static InvokeResult invokeDelegate(Object... args)
- {
- InvokeResult result = new InvokeResult();
- if (m_delegateObject == null)
- return result;
- StackTraceElement[] elements = Thread.currentThread().getStackTrace();
- if (-1 == stackDeep) {
- for (int it=0;it<elements.length;it++)
- if (elements[it].getClassName().equals(activityClassName)) {
- stackDeep = it;
- break;
- }
- }
- if (-1 == stackDeep)
- return result;
-
- final String methodName=elements[stackDeep].getMethodName();
- if (!m_delegateMethods.containsKey(methodName))
- return result;
-
- for (Method m : m_delegateMethods.get(methodName)) {
- if (m.getParameterTypes().length == args.length) {
- result.methodReturns = invokeDelegateMethod(m, args);
- result.invoked = true;
- return result;
- }
- }
- return result;
- }
-
- public static Object invokeDelegateMethod(Method m, Object... args)
- {
- try {
- return m.invoke(m_delegateObject, args);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
-
// Implement in subclass
protected void finish() {}
@@ -206,9 +66,6 @@ public abstract class QtLoader {
run.run();
}
- protected abstract String loaderClassName();
- protected abstract Class<?> contextClassName();
-
Intent getIntent()
{
return null;
@@ -288,21 +145,21 @@ public abstract class QtLoader {
loaderParams.containsKey(LIB_PATH_KEY) ? loaderParams.getString(LIB_PATH_KEY) : null, // libs folder (if exists)
m_context.getClassLoader()); // parent loader
- Class<?> loaderClass = classLoader.loadClass(loaderParams.getString(LOADER_CLASS_NAME_KEY)); // load QtLoader class
- Object qtLoader = loaderClass.newInstance(); // create an instance
- Method prepareAppMethod = qtLoader.getClass().getMethod("loadApplication",
- contextClassName(),
- ClassLoader.class,
- Bundle.class);
- if (!(Boolean)prepareAppMethod.invoke(qtLoader, m_context, classLoader, loaderParams))
- throw new Exception("");
-
- setQtContextDelegate(m_delegateClass, qtLoader);
-
- Method startAppMethod=qtLoader.getClass().getMethod("startApplication");
- if (!(Boolean)startAppMethod.invoke(qtLoader))
- throw new Exception("");
-
+ if (m_context instanceof QtActivityBase) {
+ QtActivityBase activityBase = (QtActivityBase)m_context;
+ QtActivityDelegate activityDelegate = activityBase.getActivityDelegate();
+ if (!activityDelegate.loadApplication(activityBase, classLoader, loaderParams))
+ throw new Exception("");
+ if (!activityDelegate.startApplication())
+ throw new Exception("");
+ } else if (m_context instanceof QtServiceBase) {
+ QtServiceBase serviceBase = (QtServiceBase)m_context;
+ QtServiceDelegate serviceDelegate = serviceBase.getServiceDelegate();
+ if (!serviceDelegate.loadApplication(serviceBase, classLoader, loaderParams))
+ throw new Exception("");
+ if (!serviceDelegate.startApplication())
+ throw new Exception("");
+ }
} catch (Exception e) {
e.printStackTrace();
AlertDialog errorDialog = new AlertDialog.Builder(m_context).create();
@@ -412,7 +269,6 @@ public abstract class QtLoader {
Bundle loaderParams = new Bundle();
loaderParams.putInt(ERROR_CODE_KEY, 0);
loaderParams.putString(DEX_PATH_KEY, new String());
- loaderParams.putString(LOADER_CLASS_NAME_KEY, loaderClassName());
id = resources.getIdentifier("static_init_classes", "string", packageName);
loaderParams.putStringArray(STATIC_INIT_CLASSES_KEY, resources.getString(id)
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtServiceBase.java b/src/android/jar/src/org/qtproject/qt/android/QtServiceBase.java
new file mode 100644
index 0000000000..f35db6436a
--- /dev/null
+++ b/src/android/jar/src/org/qtproject/qt/android/QtServiceBase.java
@@ -0,0 +1,58 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+package org.qtproject.qt.android;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.util.Log;
+
+public class QtServiceBase extends Service {
+
+ private final QtServiceDelegate m_delegate = new QtServiceDelegate(this);
+ QtServiceLoader m_loader = new QtServiceLoader(this);
+ protected void onCreateHook() {
+ // the application has already started
+ // do not reload everything again
+ if (QtNative.isStarted()) {
+ m_loader = null;
+ Log.w(QtNative.QtTAG,
+ "A QtService tried to start in the same process as an initiated " +
+ "QtActivity. That is not supported. This results in the service " +
+ "functioning as an Android Service detached from Qt.");
+ } else {
+ m_loader.onCreate();
+ }
+ }
+
+ @Override
+ public void onCreate()
+ {
+ super.onCreate();
+ onCreateHook();
+ }
+
+ @Override
+ public void onDestroy()
+ {
+ super.onDestroy();
+ QtNative.quitQtCoreApplication();
+ QtNative.terminateQt();
+ QtNative.setService(null, null);
+ QtNative.m_qtThread.exit();
+ System.exit(0);
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ synchronized (this) {
+ return QtNative.onBind(intent);
+ }
+ }
+
+ QtServiceDelegate getServiceDelegate()
+ {
+ return m_delegate;
+ }
+}
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtServiceDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtServiceDelegate.java
index 0670f66756..1b6a8c9a8c 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtServiceDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtServiceDelegate.java
@@ -1,5 +1,5 @@
// Copyright (C) 2016 BogDan Vatra <bogdan@kde.org>
-// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
package org.qtproject.qt.android;
@@ -58,6 +58,11 @@ public class QtServiceDelegate
private Service m_service = null;
private static String m_applicationParameters = null;
+ QtServiceDelegate(Service service)
+ {
+ m_service = service;
+ }
+
public boolean loadApplication(Service service, ClassLoader classLoader, Bundle loaderParams)
{
/// check parameters integrity
@@ -136,20 +141,4 @@ public class QtServiceDelegate
return false;
}
}
-
- public void onDestroy()
- {
- QtNative.quitQtCoreApplication();
- QtNative.terminateQt();
- QtNative.setService(null, null);
- QtNative.m_qtThread.exit();
- System.exit(0);
- }
-
- public IBinder onBind(Intent intent)
- {
- synchronized (this) {
- return QtNative.onBind(intent);
- }
- }
}
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtServiceLoader.java b/src/android/jar/src/org/qtproject/qt/android/QtServiceLoader.java
index d5f7167b7a..f6add928e1 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtServiceLoader.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtServiceLoader.java
@@ -14,8 +14,8 @@ import java.security.Provider;
public class QtServiceLoader extends QtLoader {
Service m_service;
- public QtServiceLoader(Service service, Class<?> clazz) {
- super(service, clazz);
+ public QtServiceLoader(Service service) {
+ super(service);
m_service = service;
}
@@ -29,10 +29,6 @@ public class QtServiceLoader extends QtLoader {
return;
}
- if (m_delegateObject != null && onCreate != null) {
- Bundle bundle = null;
- invokeDelegateMethod(onCreate, bundle);
- }
startApp(true);
}
@@ -40,14 +36,4 @@ public class QtServiceLoader extends QtLoader {
protected void finish() {
m_service.stopSelf();
}
-
- @Override
- protected String loaderClassName() {
- return "org.qtproject.qt.android.QtServiceDelegate";
- }
-
- @Override
- protected Class<?> contextClassName() {
- return android.app.Service.class;
- }
}
diff --git a/src/android/java/src/org/qtproject/qt/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt/android/bindings/QtActivity.java
index 438fd403a6..9fa8d3ffae 100644
--- a/src/android/java/src/org/qtproject/qt/android/bindings/QtActivity.java
+++ b/src/android/java/src/org/qtproject/qt/android/bindings/QtActivity.java
@@ -4,11 +4,6 @@
package org.qtproject.qt.android.bindings;
-import android.app.Activity;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
import android.provider.Browser;
import android.view.ContextMenu;
@@ -18,373 +13,48 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
+import android.os.Build;
-import org.qtproject.qt.android.QtActivityLoader;
-import org.qtproject.qt.android.QtLoader;
+import org.qtproject.qt.android.QtActivityBase;
-public class QtActivity extends Activity
+public class QtActivity extends QtActivityBase
{
- public static final String EXTRA_SOURCE_INFO = "org.qtproject.qt.android.sourceInfo";
-
- public String APPLICATION_PARAMETERS = null; // use this variable to pass any parameters to your application,
- // the parameters must not contain any white spaces
- // and must be separated with "\t"
- // e.g "-param1\t-param2=value2\t-param3\tvalue3"
-
- public String ENVIRONMENT_VARIABLES = "QT_USE_ANDROID_NATIVE_DIALOGS=1";
- // use this variable to add any environment variables to your application.
- // the env vars must be separated with "\t"
- // e.g. "ENV_VAR1=1\tENV_VAR2=2\t"
- // Currently the following vars are used by the android plugin:
- // * QT_USE_ANDROID_NATIVE_DIALOGS - 1 to use the android native dialogs.
-
- public String[] QT_ANDROID_THEMES = null; // A list with all themes that your application want to use.
- // The name of the theme must be the same with any theme from
- // http://developer.android.com/reference/android/R.style.html
- // The most used themes are:
- // * "Theme" - (fallback) check http://developer.android.com/reference/android/R.style.html#Theme
- // * "Theme_Black" - check http://developer.android.com/reference/android/R.style.html#Theme_Black
- // * "Theme_Light" - (default for API <=10) check http://developer.android.com/reference/android/R.style.html#Theme_Light
- // * "Theme_Holo" - check http://developer.android.com/reference/android/R.style.html#Theme_Holo
- // * "Theme_Holo_Light" - (default for API 11-13) check http://developer.android.com/reference/android/R.style.html#Theme_Holo_Light
- // * "Theme_DeviceDefault" - check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault
- // * "Theme_DeviceDefault_Light" - (default for API 14+) check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault_Light
-
- public String QT_ANDROID_DEFAULT_THEME = null; // sets the default theme.
-
- private QtActivityLoader m_loader;
- public QtActivity()
- {
- m_loader = new QtActivityLoader(this, QtActivity.class);
-
- if (Build.VERSION.SDK_INT < 29) {
- QT_ANDROID_THEMES = new String[] {"Theme_Holo_Light"};
- QT_ANDROID_DEFAULT_THEME = "Theme_Holo_Light";
- } else {
- QT_ANDROID_THEMES = new String[] {"Theme_DeviceDefault_DayNight"};
- QT_ANDROID_DEFAULT_THEME = "Theme_DeviceDefault_DayNight";
- }
- }
-
-
- /////////////////////////// forward all notifications ////////////////////////////
- /////////////////////////// Super class calls ////////////////////////////////////
- /////////////// PLEASE DO NOT CHANGE THE FOLLOWING CODE //////////////////////////
- //////////////////////////////////////////////////////////////////////////////////
-
- protected void onCreateHook(Bundle savedInstanceState) {
- m_loader.APPLICATION_PARAMETERS = APPLICATION_PARAMETERS;
- m_loader.ENVIRONMENT_VARIABLES = ENVIRONMENT_VARIABLES;
- m_loader.QT_ANDROID_THEMES = QT_ANDROID_THEMES;
- m_loader.QT_ANDROID_DEFAULT_THEME = QT_ANDROID_DEFAULT_THEME;
- m_loader.onCreate(savedInstanceState);
- }
-
- private void addReferrer(Intent intent)
- {
- if (intent.getExtras() != null && intent.getExtras().getString(EXTRA_SOURCE_INFO) != null)
- return;
-
- String browserApplicationId = "";
- if (intent.getExtras() != null)
- browserApplicationId = intent.getExtras().getString(Browser.EXTRA_APPLICATION_ID);
-
- String sourceInformation = "";
- if (browserApplicationId != null && !browserApplicationId.isEmpty()) {
- sourceInformation = browserApplicationId;
- } else {
- Uri referrer = getReferrer();
- if (referrer != null)
- sourceInformation = referrer.toString().replaceFirst("android-app://", "");
- }
-
- intent.putExtra(EXTRA_SOURCE_INFO, sourceInformation);
- }
-
@Override
public void onCreate(Bundle savedInstanceState)
{
+ setAppDetails();
super.onCreate(savedInstanceState);
- QtLoader.setQtApplicationClass(QtApplication.class);
- onCreateHook(savedInstanceState);
- addReferrer(getIntent());
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event)
- {
- if (QtLoader.m_delegateObject != null && QtLoader.dispatchKeyEvent != null)
- return (Boolean) QtLoader.invokeDelegateMethod(QtLoader.dispatchKeyEvent, event);
- else
- return super.dispatchKeyEvent(event);
- }
- public boolean super_dispatchKeyEvent(KeyEvent event)
- {
- return super.dispatchKeyEvent(event);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data)
- {
-
- if (QtLoader.m_delegateObject != null && QtLoader.onActivityResult != null) {
- QtLoader.invokeDelegateMethod(QtLoader.onActivityResult, requestCode, resultCode, data);
- return;
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
- public void super_onActivityResult(int requestCode, int resultCode, Intent data)
- {
- super.onActivityResult(requestCode, resultCode, data);
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig)
- {
- if (!QtLoader.invokeDelegate(newConfig).invoked)
- super.onConfigurationChanged(newConfig);
- }
- public void super_onConfigurationChanged(Configuration newConfig)
- {
- super.onConfigurationChanged(newConfig);
- }
-
- @Override
- public boolean onContextItemSelected(MenuItem item)
- {
- QtLoader.InvokeResult res = QtLoader.invokeDelegate(item);
- if (res.invoked)
- return (Boolean)res.methodReturns;
- else
- return super.onContextItemSelected(item);
- }
- public boolean super_onContextItemSelected(MenuItem item)
- {
- return super.onContextItemSelected(item);
- }
-
- @Override
- public void onContextMenuClosed(Menu menu)
- {
- if (!QtLoader.invokeDelegate(menu).invoked)
- super.onContextMenuClosed(menu);
- }
- public void super_onContextMenuClosed(Menu menu)
- {
- super.onContextMenuClosed(menu);
- }
-
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
- {
- if (!QtLoader.invokeDelegate(menu, v, menuInfo).invoked)
- super.onCreateContextMenu(menu, v, menuInfo);
- }
- public void super_onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
- {
- super.onCreateContextMenu(menu, v, menuInfo);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu)
- {
- QtLoader.InvokeResult res = QtLoader.invokeDelegate(menu);
- if (res.invoked)
- return (Boolean)res.methodReturns;
- else
- return super.onCreateOptionsMenu(menu);
- }
- public boolean super_onCreateOptionsMenu(Menu menu)
- {
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- protected void onDestroy()
- {
- super.onDestroy();
- QtLoader.invokeDelegate();
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event)
- {
- if (QtLoader.m_delegateObject != null && QtLoader.onKeyDown != null)
- return (Boolean) QtLoader.invokeDelegateMethod(QtLoader.onKeyDown, keyCode, event);
- else
- return super.onKeyDown(keyCode, event);
- }
- public boolean super_onKeyDown(int keyCode, KeyEvent event)
- {
- return super.onKeyDown(keyCode, event);
}
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event)
- {
- if (QtLoader.m_delegateObject != null && QtLoader.onKeyUp != null)
- return (Boolean) QtLoader.invokeDelegateMethod(QtLoader.onKeyUp, keyCode, event);
- else
- return super.onKeyUp(keyCode, event);
- }
- public boolean super_onKeyUp(int keyCode, KeyEvent event)
- {
- return super.onKeyUp(keyCode, event);
- }
-
- @Override
- protected void onNewIntent(Intent intent)
- {
- addReferrer(intent);
- if (!QtLoader.invokeDelegate(intent).invoked)
- super.onNewIntent(intent);
- }
- public void super_onNewIntent(Intent intent)
- {
- super.onNewIntent(intent);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item)
- {
- QtLoader.InvokeResult res = QtLoader.invokeDelegate(item);
- if (res.invoked)
- return (Boolean)res.methodReturns;
- else
- return super.onOptionsItemSelected(item);
- }
- public boolean super_onOptionsItemSelected(MenuItem item)
- {
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public void onOptionsMenuClosed(Menu menu)
- {
- if (!QtLoader.invokeDelegate(menu).invoked)
- super.onOptionsMenuClosed(menu);
- }
- public void super_onOptionsMenuClosed(Menu menu)
- {
- super.onOptionsMenuClosed(menu);
- }
-
- @Override
- protected void onPause()
- {
- super.onPause();
- QtLoader.invokeDelegate();
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu)
- {
- QtLoader.InvokeResult res = QtLoader.invokeDelegate(menu);
- if (res.invoked)
- return (Boolean)res.methodReturns;
- else
- return super.onPrepareOptionsMenu(menu);
- }
- public boolean super_onPrepareOptionsMenu(Menu menu)
- {
- return super.onPrepareOptionsMenu(menu);
- }
-
- @Override
- protected void onRestart()
- {
- super.onRestart();
- QtLoader.invokeDelegate();
- }
-
- @Override
- protected void onRestoreInstanceState(Bundle savedInstanceState)
- {
- if (!QtLoader.invokeDelegate(savedInstanceState).invoked)
- super.onRestoreInstanceState(savedInstanceState);
- }
- public void super_onRestoreInstanceState(Bundle savedInstanceState)
- {
- super.onRestoreInstanceState(savedInstanceState);
- }
-
- @Override
- protected void onResume()
- {
- super.onResume();
- QtLoader.invokeDelegate();
- }
-
- @Override
- public Object onRetainNonConfigurationInstance()
- {
- QtLoader.InvokeResult res = QtLoader.invokeDelegate();
- if (res.invoked)
- return res.methodReturns;
- else
- return super.onRetainNonConfigurationInstance();
- }
- public Object super_onRetainNonConfigurationInstance()
- {
- return super.onRetainNonConfigurationInstance();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState)
- {
- if (!QtLoader.invokeDelegate(outState).invoked)
- super.onSaveInstanceState(outState);
- }
- public void super_onSaveInstanceState(Bundle outState)
- {
- super.onSaveInstanceState(outState);
-
- }
-
- @Override
- protected void onStart()
- {
- super.onStart();
- QtLoader.invokeDelegate();
- }
-
- @Override
- protected void onStop()
+ private void setAppDetails()
{
- super.onStop();
- QtLoader.invokeDelegate();
- }
+ // use this variable to pass any parameters to your application,
+ // the parameters must not contain any white spaces
+ // and must be separated with "\t"
+ // e.g "-param1\t-param2=value2\t-param3\tvalue3"
+ APPLICATION_PARAMETERS = "";
- @Override
- public void onWindowFocusChanged(boolean hasFocus)
- {
- if (!QtLoader.invokeDelegate(hasFocus).invoked)
- super.onWindowFocusChanged(hasFocus);
- }
- public void super_onWindowFocusChanged(boolean hasFocus)
- {
- super.onWindowFocusChanged(hasFocus);
- }
+ // Use this variable to add any environment variables to your application.
+ // the env vars must be separated with "\t"
+ // e.g. "ENV_VAR1=1\tENV_VAR2=2\t"
+ // Currently the following vars are used by the android plugin:
+ // * QT_USE_ANDROID_NATIVE_DIALOGS - 1 to use the android native dialogs.
+ ENVIRONMENT_VARIABLES = "QT_USE_ANDROID_NATIVE_DIALOGS=1";
- @Override
- public boolean dispatchGenericMotionEvent(MotionEvent ev)
- {
- if (QtLoader.m_delegateObject != null && QtLoader.dispatchGenericMotionEvent != null)
- return (Boolean) QtLoader.invokeDelegateMethod(QtLoader.dispatchGenericMotionEvent, ev);
- else
- return super.dispatchGenericMotionEvent(ev);
- }
- public boolean super_dispatchGenericMotionEvent(MotionEvent event)
- {
- return super.dispatchGenericMotionEvent(event);
- }
+ // A list with all themes that your application want to use.
+ // The name of the theme must be the same with any theme from
+ // http://developer.android.com/reference/android/R.style.html
+ // The most used themes are:
+ // * "Theme_Light"
+ // * "Theme_Holo"
+ // * "Theme_Holo_Light"
- public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
- {
- if (QtLoader.m_delegateObject != null && QtLoader.onRequestPermissionsResult != null) {
- QtLoader.invokeDelegateMethod(QtLoader.onRequestPermissionsResult, requestCode ,
- permissions, grantResults);
+ if (Build.VERSION.SDK_INT < 29) {
+ QT_ANDROID_THEMES = new String[] {"Theme_Holo_Light"};
+ QT_ANDROID_DEFAULT_THEME = "Theme_Holo_Light";
+ } else {
+ QT_ANDROID_THEMES = new String[] {"Theme_DeviceDefault_DayNight"};
+ QT_ANDROID_DEFAULT_THEME = "Theme_DeviceDefault_DayNight";
}
}
- //---------------------------------------------------------------------------
}
diff --git a/src/android/java/src/org/qtproject/qt/android/bindings/QtApplication.java b/src/android/java/src/org/qtproject/qt/android/bindings/QtApplication.java
index b89946b9a5..d1330565c1 100644
--- a/src/android/java/src/org/qtproject/qt/android/bindings/QtApplication.java
+++ b/src/android/java/src/org/qtproject/qt/android/bindings/QtApplication.java
@@ -4,30 +4,12 @@
package org.qtproject.qt.android.bindings;
-import android.app.Application;
-import org.qtproject.qt.android.QtLoader;
+import org.qtproject.qt.android.QtApplicationBase;
-public class QtApplication extends Application
+public class QtApplication extends QtApplicationBase
{
- public final static String QtTAG = "Qt";
-
@Override
public void onTerminate() {
- if (QtLoader.m_delegateObject != null && QtLoader.m_delegateMethods.containsKey("onTerminate"))
- QtLoader.invokeDelegateMethod(QtLoader.m_delegateMethods.get("onTerminate").get(0));
super.onTerminate();
}
-
- // TODO: only keep around for avoid build errors, will be removed.
- public static class InvokeResult
- {
- public boolean invoked = false;
- public Object methodReturns = null;
- }
-
- public static InvokeResult invokeDelegate(Object... args)
- {
- InvokeResult result = new InvokeResult();
- return result;
- }
}
diff --git a/src/android/java/src/org/qtproject/qt/android/bindings/QtService.java b/src/android/java/src/org/qtproject/qt/android/bindings/QtService.java
index 8322af2ae7..6569446901 100644
--- a/src/android/java/src/org/qtproject/qt/android/bindings/QtService.java
+++ b/src/android/java/src/org/qtproject/qt/android/bindings/QtService.java
@@ -4,85 +4,13 @@
package org.qtproject.qt.android.bindings;
-import android.app.Service;
-import android.util.Log;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.os.IBinder;
+import org.qtproject.qt.android.QtServiceBase;
-import org.qtproject.qt.android.QtNative;
-import org.qtproject.qt.android.QtServiceLoader;
-import org.qtproject.qt.android.QtLoader;
-
-public class QtService extends Service
+public class QtService extends QtServiceBase
{
- QtServiceLoader m_loader = new QtServiceLoader(this, QtService.class);
-
- /////////////////////////// forward all notifications ////////////////////////////
- /////////////////////////// Super class calls ////////////////////////////////////
- /////////////// PLEASE DO NOT CHANGE THE FOLLOWING CODE //////////////////////////
- //////////////////////////////////////////////////////////////////////////////////
-
- protected void onCreateHook() {
- // the application has already started
- // do not reload everything again
- if (QtNative.isStarted()) {
- m_loader = null;
- Log.w(QtNative.QtTAG,
- "A QtService tried to start in the same process as an initiated " +
- "QtActivity. That is not supported. This results in the service " +
- "functioning as an Android Service detached from Qt.");
- } else {
- m_loader.onCreate();
- }
- }
@Override
public void onCreate()
{
super.onCreate();
- onCreateHook();
- }
-
- @Override
- public void onDestroy()
- {
- super.onDestroy();
- QtLoader.invokeDelegate();
- }
-
- @Override
- public IBinder onBind(Intent intent)
- {
- QtLoader.InvokeResult res = QtLoader.invokeDelegate(intent);
- if (res.invoked)
- return (IBinder)res.methodReturns;
- else
- return null;
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig)
- {
- if (!QtLoader.invokeDelegate(newConfig).invoked)
- super.onConfigurationChanged(newConfig);
- }
- public void super_onConfigurationChanged(Configuration newConfig)
- {
- super.onConfigurationChanged(newConfig);
- }
-
- @Override
- public boolean onUnbind(Intent intent)
- {
- QtLoader.InvokeResult res = QtLoader.invokeDelegate(intent);
- if (res.invoked)
- return (Boolean) res.methodReturns;
- else
- return super.onUnbind(intent);
- }
- public boolean super_onUnbind(Intent intent)
- {
- return super.onUnbind(intent);
}
- //---------------------------------------------------------------------------
}