Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
QtActivityLoader.java
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// Copyright (c) 2016, BogDan Vatra <bogdan@kde.org>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5package org.qtproject.qt.android;
6
7import android.annotation.SuppressLint;
8import android.app.Activity;
9import android.app.AlertDialog;
10import android.app.Dialog;
11import android.content.ContextWrapper;
12import android.content.Intent;
13import android.content.pm.ApplicationInfo;
14import android.content.pm.PackageManager;
15import android.content.res.Resources;
16import android.os.Bundle;
17import android.system.Os;
18import android.util.Base64;
19import android.util.DisplayMetrics;
20import android.util.Log;
21
22import java.lang.reflect.InvocationTargetException;
23import java.lang.reflect.Method;
24import java.nio.charset.StandardCharsets;
25
26class QtActivityLoader extends QtLoader {
27 private final Activity m_activity;
28
29 public QtActivityLoader(Activity activity)
30 {
31 super(new ContextWrapper(activity));
32 m_activity = activity;
33
34 extractContextMetaData();
35 }
36
37 private void showErrorDialog() {
38 if (m_activity == null) {
39 Log.w(QtTAG, "cannot show the error dialog from a null activity object");
40 return;
41 }
42 Resources resources = m_activity.getResources();
43 String packageName = m_activity.getPackageName();
44 AlertDialog errorDialog = new AlertDialog.Builder(m_activity).create();
45 @SuppressLint("DiscouragedApi") int id = resources.getIdentifier(
46 "fatal_error_msg", "string", packageName);
47 errorDialog.setMessage(resources.getString(id));
48 errorDialog.setButton(Dialog.BUTTON_POSITIVE, resources.getString(android.R.string.ok),
49 (dialog, which) -> finish());
50 errorDialog.show();
51 }
52
53 @Override
54 protected void finish() {
55 if (m_activity == null) {
56 Log.w(QtTAG, "finish() called when activity object is null");
57 return;
58 }
59 showErrorDialog();
60 m_activity.finish();
61 }
62
63 private String getDecodedUtfString(String str)
64 {
65 byte[] decodedExtraEnvVars = Base64.decode(str, Base64.DEFAULT);
66 return new String(decodedExtraEnvVars, StandardCharsets.UTF_8);
67 }
68
69 int getAppIconSize()
70 {
71 int size = m_activity.getResources().getDimensionPixelSize(android.R.dimen.app_icon_size);
72 if (size < 36 || size > 512) { // check size sanity
73 DisplayMetrics metrics = new DisplayMetrics();
74 m_activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
75 size = metrics.densityDpi / 10 * 3;
76 if (size < 36)
77 size = 36;
78
79 if (size > 512)
80 size = 512;
81 }
82
83 return size;
84 }
85
86 private void setupStyleExtraction()
87 {
88 int displayDensity = m_activity.getResources().getDisplayMetrics().densityDpi;
89 setEnvironmentVariable("QT_ANDROID_THEME_DISPLAY_DPI", String.valueOf(displayDensity));
90
91 String extractOption = getMetaData("android.app.extract_android_style");
92 if (extractOption.equals("full"))
93 setEnvironmentVariable("QT_USE_ANDROID_NATIVE_STYLE", String.valueOf(1));
94
95 String stylePath = ExtractStyle.setup(m_activity, extractOption, displayDensity);
96 setEnvironmentVariable("ANDROID_STYLE_PATH", stylePath);
97 }
98
99 @Override
100 protected void extractContextMetaData()
101 {
102 super.extractContextMetaData();
103
104 setEnvironmentVariable("QT_USE_ANDROID_NATIVE_DIALOGS", String.valueOf(1));
105 setEnvironmentVariable("QT_ANDROID_APP_ICON_SIZE", String.valueOf(getAppIconSize()));
106
107 setupStyleExtraction();
108
109 Intent intent = m_activity.getIntent();
110 if (intent == null) {
111 Log.w(QtTAG, "Null Intent from the current Activity.");
112 return;
113 }
114
115 String intentArgs = intent.getStringExtra("applicationArguments");
116 if (intentArgs != null)
117 appendApplicationParameters(intentArgs);
118
119 Bundle extras = intent.getExtras();
120 if (extras == null) {
121 Log.w(QtTAG, "Null extras from the Activity's intent.");
122 return;
123 }
124
125 int flags = m_activity.getApplicationInfo().flags;
126 boolean isDebuggable = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
127
128 if (isDebuggable) {
129 if (extras.containsKey("extraenvvars")) {
130 String extraEnvVars = extras.getString("extraenvvars");
131 setEnvironmentVariables(getDecodedUtfString(extraEnvVars));
132 }
133
134 if (extras.containsKey("extraappparams")) {
135 String extraAppParams = extras.getString("extraappparams");
136 appendApplicationParameters(getDecodedUtfString(extraAppParams));
137 }
138
139 m_debuggerSleepMs = 3000;
140 if (Os.getenv("QT_ANDROID_DEBUGGER_MAIN_THREAD_SLEEP_MS") != null) {
141 try {
142 m_debuggerSleepMs = Integer.parseInt(Os.getenv("QT_ANDROID_DEBUGGER_MAIN_THREAD_SLEEP_MS"));
143 } catch (NumberFormatException ignored) {
144 }
145 }
146 } else {
147 Log.d(QtNative.QtTAG, "Not in debug mode! It is not allowed to use extra arguments " +
148 "in non-debug mode.");
149 }
150 }
151}
QString str
[2]
Q_CORE_EXPORT QtJniTypes::Activity activity()
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
GLbitfield flags
static QString getString(IMFActivate *device, const IID &id)
view show()
[18] //! [19]
QFileDialog dialog(this)
[1]