Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
QtActivityBase.java
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4package org.qtproject.qt.android;
5
6import android.annotation.SuppressLint;
7import android.app.Activity;
8import android.app.AlertDialog;
9import android.app.Dialog;
10import android.content.Intent;
11import android.content.pm.ActivityInfo;
12import android.content.res.Configuration;
13import android.content.res.Resources;
14import android.net.Uri;
15import android.os.Build;
16import android.os.Bundle;
17import android.provider.Browser;
18import android.view.ContextMenu;
19import android.view.ContextMenu.ContextMenuInfo;
20import android.view.KeyEvent;
21import android.view.Menu;
22import android.view.MenuItem;
23import android.view.MotionEvent;
24import android.view.View;
25import android.view.Window;
26import java.lang.IllegalArgumentException;
27
28public class QtActivityBase extends Activity
29{
30 public static final String EXTRA_SOURCE_INFO = "org.qtproject.qt.android.sourceInfo";
31
32 private String m_applicationParams = "";
33 private boolean m_isCustomThemeSet = false;
34 private boolean m_retainNonConfigurationInstance = false;
35 private Configuration m_prevConfig;
36 private final QtActivityDelegate m_delegate;
37
38 private void addReferrer(Intent intent)
39 {
40 Bundle extras = intent.getExtras();
41 if (extras != null && extras.getString(EXTRA_SOURCE_INFO) != null)
42 return;
43
44 if (extras == null) {
45 Uri referrer = getReferrer();
46 if (referrer != null) {
47 String cleanReferrer = referrer.toString().replaceFirst("android-app://", "");
48 intent.putExtra(EXTRA_SOURCE_INFO, cleanReferrer);
49 }
50 } else {
51 String applicationId = extras.getString(Browser.EXTRA_APPLICATION_ID);
52 if (applicationId != null)
53 intent.putExtra(EXTRA_SOURCE_INFO, applicationId);
54 }
55 }
56
57 // Append any parameters to your application.
58 // Either a whitespace or a tab is accepted as a separator between parameters.
61 {
62 if (params == null || params.isEmpty())
63 return;
64
65 if (!m_applicationParams.isEmpty())
66 m_applicationParams += " ";
67 m_applicationParams += params;
68 }
69
70 @Override
71 public void setTheme(int resId) {
72 super.setTheme(resId);
73 m_isCustomThemeSet = true;
74 }
75
76 private void restartApplication() {
77 Intent intent = Intent.makeRestartActivityTask(getComponentName());
78 startActivity(intent);
79 QtNative.quitApp();
80 Runtime.getRuntime().exit(0);
81 }
82
84 {
85 m_delegate = new QtActivityDelegate(this);
86 }
87
88 @Override
89 protected void onCreate(Bundle savedInstanceState)
90 {
91 super.onCreate(savedInstanceState);
92 requestWindowFeature(Window.FEATURE_ACTION_BAR);
93
94 if (!m_isCustomThemeSet) {
95 setTheme(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ?
96 android.R.style.Theme_DeviceDefault_DayNight :
97 android.R.style.Theme_Holo_Light);
98 }
99
100 if (QtNative.getStateDetails().isStarted) {
101 // We don't yet have a reliable way to keep the app
102 // running properly in case of an Activity only restart,
103 // so for now restart the whole app.
104 restartApplication();
105 }
106
107 QtNative.registerAppStateListener(m_delegate);
108 addReferrer(getIntent());
109
110 try {
111 QtActivityLoader loader = QtActivityLoader.getActivityLoader(this);
112 loader.appendApplicationParameters(m_applicationParams);
113
114 QtLoader.LoadingResult result = loader.loadQtLibraries();
115
116 if (result == QtLoader.LoadingResult.Succeeded) {
117 m_delegate.startNativeApplication(loader.getApplicationParameters(),
118 loader.getMainLibraryPath());
119 } else if (result == QtLoader.LoadingResult.Failed) {
120 showErrorDialog();
121 }
122 } catch (IllegalArgumentException e) {
123 e.printStackTrace();
124 showErrorDialog();
125 }
126
127 m_prevConfig = new Configuration(getResources().getConfiguration());
128 }
129
130 @Override
131 protected void onPause()
132 {
133 super.onPause();
134 if (Build.VERSION.SDK_INT < 24 || !isInMultiWindowMode())
135 QtNative.setApplicationState(QtNative.ApplicationState.ApplicationInactive);
136 m_delegate.displayManager().unregisterDisplayListener();
137 }
138
139 @Override
140 protected void onResume()
141 {
142 super.onResume();
143 QtNative.setApplicationState(QtNative.ApplicationState.ApplicationActive);
144 if (QtNative.getStateDetails().isStarted) {
145 m_delegate.displayManager().registerDisplayListener();
146 QtNative.updateWindow();
147 // Suspending the app clears the immersive mode, so we need to set it again.
148 m_delegate.displayManager().updateFullScreen();
149 }
150 }
151
152 @Override
153 protected void onStop()
154 {
155 super.onStop();
156 QtNative.setApplicationState(QtNative.ApplicationState.ApplicationSuspended);
157 }
158
159 @Override
160 protected void onDestroy()
161 {
162 super.onDestroy();
163 if (!m_retainNonConfigurationInstance) {
164 QtNative.unregisterAppStateListener(m_delegate);
165 QtNative.terminateQt();
166 QtNative.setActivity(null);
167 QtNative.getQtThread().exit();
168 System.exit(0);
169 }
170 }
171
172 @Override
173 public void onConfigurationChanged(Configuration newConfig)
174 {
175 super.onConfigurationChanged(newConfig);
176 m_delegate.handleUiModeChange(newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK);
177
178 int diff = newConfig.diff(m_prevConfig);
179 if ((diff & ActivityInfo.CONFIG_LOCALE) != 0)
180 QtNative.updateLocale();
181
182 m_prevConfig = new Configuration(newConfig);
183 }
184
185 @Override
186 public boolean onContextItemSelected(MenuItem item)
187 {
188 m_delegate.setContextMenuVisible(false);
189 return QtNative.onContextItemSelected(item.getItemId(), item.isChecked());
190 }
191
192 @Override
193 public void onContextMenuClosed(Menu menu)
194 {
195 if (!m_delegate.isContextMenuVisible())
196 return;
197 m_delegate.setContextMenuVisible(false);
198 QtNative.onContextMenuClosed(menu);
199 }
200
201 @Override
202 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
203 {
204 menu.clearHeader();
205 QtNative.onCreateContextMenu(menu);
206 m_delegate.setContextMenuVisible(true);
207 }
208
209 @Override
210 public boolean dispatchKeyEvent(KeyEvent event)
211 {
212 boolean handleResult = m_delegate.getInputDelegate().handleDispatchKeyEvent(event);
213 if (QtNative.getStateDetails().isStarted && handleResult)
214 return true;
215
216 return super.dispatchKeyEvent(event);
217 }
218
219 @Override
220 public boolean dispatchGenericMotionEvent(MotionEvent event)
221 {
222 boolean handled = m_delegate.getInputDelegate().handleDispatchGenericMotionEvent(event);
223 if (QtNative.getStateDetails().isStarted && handled)
224 return true;
225
226 return super.dispatchGenericMotionEvent(event);
227 }
228
229 @Override
230 public boolean onKeyDown(int keyCode, KeyEvent event)
231 {
232 QtNative.ApplicationStateDetails stateDetails = QtNative.getStateDetails();
233 if (!stateDetails.isStarted || !stateDetails.nativePluginIntegrationReady)
234 return false;
235
236 return m_delegate.getInputDelegate().onKeyDown(keyCode, event);
237 }
238
239 @Override
240 public boolean onKeyUp(int keyCode, KeyEvent event)
241 {
242 QtNative.ApplicationStateDetails stateDetails = QtNative.getStateDetails();
243 if (!stateDetails.isStarted || !stateDetails.nativePluginIntegrationReady)
244 return false;
245
246 return m_delegate.getInputDelegate().onKeyUp(keyCode, event);
247 }
248
249 @Override
250 public boolean onCreateOptionsMenu(Menu menu)
251 {
252 menu.clear();
253 return true;
254 }
255
256 @Override
257 public boolean onPrepareOptionsMenu(Menu menu)
258 {
259 boolean res = QtNative.onPrepareOptionsMenu(menu);
260 m_delegate.setActionBarVisibility(res && menu.size() > 0);
261 return res;
262 }
263
264 @Override
265 public boolean onOptionsItemSelected(MenuItem item)
266 {
267 return QtNative.onOptionsItemSelected(item.getItemId(), item.isChecked());
268 }
269
270 @Override
271 public void onOptionsMenuClosed(Menu menu)
272 {
273 QtNative.onOptionsMenuClosed(menu);
274 }
275
276 @Override
277 protected void onRestoreInstanceState(Bundle savedInstanceState)
278 {
279 super.onRestoreInstanceState(savedInstanceState);
280 QtNative.setStarted(savedInstanceState.getBoolean("Started"));
281 int savedSystemUiVisibility = savedInstanceState.getInt("SystemUiVisibility");
282 m_delegate.displayManager().setSystemUiVisibility(savedSystemUiVisibility);
283 // FIXME restore all surfaces
284 }
285
286 @Override
288 {
289 super.onRetainNonConfigurationInstance();
290 m_retainNonConfigurationInstance = true;
291 return true;
292 }
293
294 @Override
295 protected void onSaveInstanceState(Bundle outState)
296 {
297 super.onSaveInstanceState(outState);
298 outState.putInt("SystemUiVisibility", m_delegate.displayManager().systemUiVisibility());
299 outState.putBoolean("Started", QtNative.getStateDetails().isStarted);
300 }
301
302 @Override
303 public void onWindowFocusChanged(boolean hasFocus)
304 {
305 super.onWindowFocusChanged(hasFocus);
306 if (hasFocus)
307 m_delegate.displayManager().updateFullScreen();
308 }
309
310 @Override
311 protected void onNewIntent(Intent intent)
312 {
313 addReferrer(intent);
314 QtNative.onNewIntent(intent);
315 }
316
317 @Override
318 protected void onActivityResult(int requestCode, int resultCode, Intent data)
319 {
320 super.onActivityResult(requestCode, resultCode, data);
321 QtNative.onActivityResult(requestCode, resultCode, data);
322 }
323
324 @Override
325 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
326 {
327 QtNative.sendRequestPermissionsResult(requestCode, grantResults);
328 }
329
331 public void hideSplashScreen(final int duration)
332 {
333 m_delegate.hideSplashScreen(duration);
334 }
335
336 private void showErrorDialog() {
337 Resources resources = getResources();
338 String packageName = getPackageName();
339 AlertDialog errorDialog = new AlertDialog.Builder(this).create();
340 @SuppressLint("DiscouragedApi") int id = resources.getIdentifier(
341 "fatal_error_msg", "string", packageName);
342 errorDialog.setMessage(resources.getString(id));
343 errorDialog.setButton(Dialog.BUTTON_POSITIVE, resources.getString(android.R.string.ok),
344 (dialog, which) -> finish());
345 errorDialog.show();
346 }
347}
DarwinBluetooth::DeviceInquiryDelegate * m_delegate
Definition main.cpp:8
void clear()
Removes all the menu's actions.
Definition qmenu.cpp:2225
QSize size
the size of the widget excluding any window frame
Definition qwidget.h:113
void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
boolean dispatchGenericMotionEvent(MotionEvent event)
boolean onKeyDown(int keyCode, KeyEvent event)
void onCreate(Bundle savedInstanceState)
void onActivityResult(int requestCode, int resultCode, Intent data)
void onConfigurationChanged(Configuration newConfig)
boolean onKeyUp(int keyCode, KeyEvent event)
void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
void onRestoreInstanceState(Bundle savedInstanceState)
static native void onNewIntent(Intent data)
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
[0]
GLsizei const GLfloat * v
[13]
void ** params
GLuint res
GLuint64EXT * result
[6]
struct _cl_event * event
[0]
static QStringList getResources(const QString &resourceFile, QMakeVfs *vfs)
Definition main.cpp:122
static QString getString(IMFActivate *device, const IID &id)
view show()
[18] //! [19]
QFileDialog dialog(this)
[1]
QGraphicsItem * item
QMenu menu
[5]