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
28import android.widget.Toast;
29
30public class QtActivityBase extends Activity
31{
32 public static final String EXTRA_SOURCE_INFO = "org.qtproject.qt.android.sourceInfo";
33
34 private String m_applicationParams = "";
35 private boolean m_isCustomThemeSet = false;
36 private boolean m_retainNonConfigurationInstance = false;
37 private Configuration m_prevConfig;
38 private final QtActivityDelegate m_delegate;
39 private boolean m_onCreateSucceeded = false;
40
41 private void addReferrer(Intent intent)
42 {
43 Bundle extras = intent.getExtras();
44 if (extras != null && extras.getString(EXTRA_SOURCE_INFO) != null)
45 return;
46
47 if (extras == null) {
48 Uri referrer = getReferrer();
49 if (referrer != null) {
50 String cleanReferrer = referrer.toString().replaceFirst("android-app://", "");
51 intent.putExtra(EXTRA_SOURCE_INFO, cleanReferrer);
52 }
53 } else {
54 String applicationId = extras.getString(Browser.EXTRA_APPLICATION_ID);
55 if (applicationId != null)
56 intent.putExtra(EXTRA_SOURCE_INFO, applicationId);
57 }
58 }
59
67 @SuppressWarnings("unused")
69 {
70 if (params == null || params.isEmpty())
71 return;
72
73 if (!m_applicationParams.isEmpty())
74 m_applicationParams += " ";
75 m_applicationParams += params;
76 }
77
78 @Override
79 public void setTheme(int resId) {
80 super.setTheme(resId);
81 m_isCustomThemeSet = true;
82 }
83
84 private void restartApplication() {
85 Intent intent = Intent.makeRestartActivityTask(getComponentName());
86 startActivity(intent);
87 QtNative.setStarted(false);
88 // FIXME: calling exit() right after this gives no time to get onDestroy().
89 finish();
90 Runtime.getRuntime().exit(0);
91 }
92
94 {
95 m_delegate = new QtActivityDelegate(this);
96 }
97
98 @Override
99 protected void onCreate(Bundle savedInstanceState)
100 {
101 super.onCreate(savedInstanceState);
102 requestWindowFeature(Window.FEATURE_ACTION_BAR);
103
104 if (!m_isCustomThemeSet) {
105 @SuppressWarnings("deprecation")
106 int themeId = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
107 ? android.R.style.Theme_DeviceDefault_DayNight
108 : android.R.style.Theme_Holo_Light;
109 setTheme(themeId);
110 }
111
112 if (QtNative.getStateDetails().isStarted) {
113 // We don't yet have a reliable way to keep the app
114 // running properly in case of an Activity only restart,
115 // so for now restart the whole app.
116 restartApplication();
117 }
118
119 QtNative.registerAppStateListener(m_delegate);
120 addReferrer(getIntent());
121
122 try {
123 QtActivityLoader loader = QtActivityLoader.getActivityLoader(this);
124 loader.appendApplicationParameters(m_applicationParams);
125
126 QtLoader.LoadingResult result = loader.loadQtLibraries();
127 if (result == QtLoader.LoadingResult.Succeeded) {
128 m_delegate.startNativeApplication(loader.getApplicationParameters(),
129 loader.getMainLibraryPath());
130 } else if (result == QtLoader.LoadingResult.Failed) {
131 showFatalFinishingToast();
132 return;
133 }
134 } catch (IllegalArgumentException e) {
135 e.printStackTrace();
136 showFatalFinishingToast();
137 return;
138 }
139
140 m_prevConfig = new Configuration(getResources().getConfiguration());
141 m_onCreateSucceeded = true;
142 }
143
144 private void showFatalFinishingToast() {
145 Resources resources = getResources();
146 String packageName = getPackageName();
147 @SuppressLint("DiscouragedApi") int id = resources.getIdentifier(
148 "fatal_error_msg", "string", packageName);
149 String message = resources.getString(id);
150 Toast.makeText(this, message, Toast.LENGTH_LONG).show();
151
152 finish();
153 }
154
155 @Override
156 protected void onPause()
157 {
158 super.onPause();
159 if (Build.VERSION.SDK_INT < 24 || !isInMultiWindowMode())
160 QtNative.setApplicationState(QtNative.ApplicationState.ApplicationInactive);
161 m_delegate.displayManager().unregisterDisplayListener();
162 }
163
164 @Override
165 protected void onResume()
166 {
167 super.onResume();
168 QtNative.setApplicationState(QtNative.ApplicationState.ApplicationActive);
169 if (QtNative.getStateDetails().isStarted) {
170 m_delegate.displayManager().registerDisplayListener();
171 QtWindow.updateWindows();
172 // Suspending the app clears the immersive mode, so we need to set it again.
173 QtWindowInsetsController.restoreFullScreenVisibility(this);
174 }
175 }
176
177 @Override
178 protected void onStop()
179 {
180 super.onStop();
181 QtNative.setApplicationState(QtNative.ApplicationState.ApplicationSuspended);
182 }
183
184 @Override
185 protected void onDestroy()
186 {
187 super.onDestroy();
188
189 if (!m_onCreateSucceeded)
190 System.exit(-1);
191
192 if (!m_retainNonConfigurationInstance) {
193 QtNative.unregisterAppStateListener(m_delegate);
194 QtNative.terminateQtNativeApplication();
195 QtNative.setActivity(null);
196 System.exit(0);
197 }
198 }
199
200 @Override
201 public void onConfigurationChanged(Configuration newConfig)
202 {
203 super.onConfigurationChanged(newConfig);
204
205 int diff = newConfig.diff(m_prevConfig);
206 if ((diff & ActivityInfo.CONFIG_UI_MODE) != 0)
207 m_delegate.handleUiModeChange();
208
209 if ((diff & ActivityInfo.CONFIG_LOCALE) != 0)
210 QtNative.updateLocale();
211
212 m_prevConfig = new Configuration(newConfig);
213 }
214
215 @Override
216 public boolean onContextItemSelected(MenuItem item)
217 {
218 m_delegate.setContextMenuVisible(false);
219 return QtNative.onContextItemSelected(item.getItemId(), item.isChecked());
220 }
221
222 @Override
223 public void onContextMenuClosed(Menu menu)
224 {
225 if (!m_delegate.isContextMenuVisible())
226 return;
227 m_delegate.setContextMenuVisible(false);
228 QtNative.onContextMenuClosed(menu);
229 }
230
231 @Override
232 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
233 {
234 menu.clearHeader();
235 QtNative.onCreateContextMenu(menu);
236 m_delegate.setContextMenuVisible(true);
237 }
238
239 @Override
241 {
242 boolean handleResult = m_delegate.getInputDelegate().handleDispatchKeyEvent(event);
243 if (QtNative.getStateDetails().isStarted && handleResult)
244 return true;
245
246 return super.dispatchKeyEvent(event);
247 }
248
249 @Override
250 public boolean dispatchGenericMotionEvent(MotionEvent event)
251 {
252 boolean handled = m_delegate.getInputDelegate().handleDispatchGenericMotionEvent(event);
253 if (QtNative.getStateDetails().isStarted && handled)
254 return true;
255
256 return super.dispatchGenericMotionEvent(event);
257 }
258
259 @Override
260 public boolean onKeyDown(int keyCode, KeyEvent event)
261 {
262 QtNative.ApplicationStateDetails stateDetails = QtNative.getStateDetails();
263 if (!stateDetails.isStarted || !stateDetails.nativePluginIntegrationReady)
264 return false;
265
266 return m_delegate.getInputDelegate().onKeyDown(keyCode, event);
267 }
268
269 @Override
270 public boolean onKeyUp(int keyCode, KeyEvent event)
271 {
272 QtNative.ApplicationStateDetails stateDetails = QtNative.getStateDetails();
273 if (!stateDetails.isStarted || !stateDetails.nativePluginIntegrationReady)
274 return false;
275
276 return m_delegate.getInputDelegate().onKeyUp(keyCode, event);
277 }
278
279 @Override
280 public boolean onCreateOptionsMenu(Menu menu)
281 {
282 menu.clear();
283 return true;
284 }
285
286 @Override
287 public boolean onPrepareOptionsMenu(Menu menu)
288 {
289 boolean res = QtNative.onPrepareOptionsMenu(menu);
290 m_delegate.setActionBarVisibility(res && menu.size() > 0);
291 return res;
292 }
293
294 @Override
295 public boolean onOptionsItemSelected(MenuItem item)
296 {
297 return QtNative.onOptionsItemSelected(item.getItemId(), item.isChecked());
298 }
299
300 @Override
301 public void onOptionsMenuClosed(Menu menu)
302 {
303 QtNative.onOptionsMenuClosed(menu);
304 }
305
306 @Override
307 protected void onRestoreInstanceState(Bundle savedInstanceState)
308 {
309 super.onRestoreInstanceState(savedInstanceState);
310
311 // only restore when this Activity is being recreated for a config change
312 if (getLastNonConfigurationInstance() == null)
313 return;
314
315 QtNative.setStarted(savedInstanceState.getBoolean("Started"));
316 QtWindowInsetsController.restoreFullScreenVisibility(this);
317 // FIXME restore all surfaces
318 }
319
320 @Override
322 {
323 super.onRetainNonConfigurationInstance();
324 m_retainNonConfigurationInstance = true;
325 return true;
326 }
327
328 @Override
329 protected void onSaveInstanceState(Bundle outState)
330 {
331 super.onSaveInstanceState(outState);
332 outState.putBoolean("Started", QtNative.getStateDetails().isStarted);
333 }
334
335 @Override
336 public void onWindowFocusChanged(boolean hasFocus)
337 {
338 super.onWindowFocusChanged(hasFocus);
339 if (hasFocus)
340 QtWindowInsetsController.restoreFullScreenVisibility(this);
341 }
342
343 @Override
344 protected void onNewIntent(Intent intent)
345 {
346 addReferrer(intent);
347 QtNative.onNewIntent(intent);
348 }
349
350 @Override
351 protected void onActivityResult(int requestCode, int resultCode, Intent data)
352 {
353 super.onActivityResult(requestCode, resultCode, data);
354 QtNative.onActivityResult(requestCode, resultCode, data);
355 }
356
357 @Override
358 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
359 {
360 QtNative.sendRequestPermissionsResult(requestCode, grantResults);
361 }
362
364 public void hideSplashScreen(final int duration)
365 {
366 m_delegate.hideSplashScreen(duration);
367 }
368}
[Window class with invokable method]
Definition window.h:11
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)
#define this
Definition dialogs.cpp:8
QMap< Name, StatePointer > Bundle
Definition lalr.h:46
[vector_of_multirole_objects_0]
Definition main.cpp:188
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
[0]
GLuint GLsizei const GLchar * message
GLsizei const GLfloat * v
void ** params
struct _cl_event * event
GLuint res
GLuint64EXT * result
[6]
static QStringList getResources(const QString &resourceFile, QMakeVfs *vfs)
Definition main.cpp:99
static QString getString(IMFActivate *device, const IID &id)
view show()
[18] //! [19]
void handleResult(const QFuture< T > &future)
QGraphicsItem * item
QMenu menu
[5]
if(foo.startsWith("("+type+") 0x")) ... QString hello("hello")
[0]