android: read the activity's own arguments, since Qt does not deliver them

`am start -n <pkg>/org.qtproject.qt.android.bindings.QtActivity --esa
applicationArguments "--workspace,/sdcard/x"` left the window on its default
workspace on the NX789J (the plain-string extra too), so the extra is read
from the intent directly. That is what makes `cst-agent-app --uitest
--workspace DIR` reachable on a device with no keyboard -- and adb cannot
inject touch into this window either (tap, touchscreen tap, mouse tap and
motionevent all do nothing; key events do work), so it is the only way in.

Everything degrades to "no arguments": an invalid object, a missing method or
a context that is not an activity all come back empty.
This commit is contained in:
WHC
2026-10-11 20:22:50 +08:00
parent 7b2e7a3dbd
commit da04913071
3 changed files with 56 additions and 1 deletions
+6
View File
@@ -97,6 +97,12 @@ bool hasAllFilesAccess();
* dialog for it). A desktop, a phone that already has it or one too old to
* know about it returns "" and nothing opens. */
QString requestAllFilesAccess();
/* The arguments the Android activity was started with (the
* "applicationArguments" intent extra): the way
* `cst-agent-app --uitest --workspace DIR` is reachable on a device, since
* Qt's own plumbing for that extra does not reach this build. Empty
* everywhere else, and empty on a device that was not started with any. */
QStringList activityArguments();
} // namespace app
+10 -1
View File
@@ -199,7 +199,16 @@ int main(int argc, char **argv) {
parser.addOption(planOpt);
parser.addOption(uitestOpt);
parser.addOption(sizeOpt);
parser.process(app);
/* What the process was started with, plus -- on a phone -- what the
* activity was started with: Qt's own applicationArguments plumbing does
* not deliver the extra on the NX789J (see activityArguments()), and
* without it there is no way to hand this window a workspace or a --uitest
* run on a device that has no keyboard. */
QStringList args = QCoreApplication::arguments();
#if defined(Q_OS_ANDROID)
args += app::activityArguments();
#endif
parser.process(args);
QString ws = parser.value(wsOpt);
if (ws.isEmpty()) {
+40
View File
@@ -101,6 +101,41 @@ QJniObject appContext() {
return QNativeInterface::QAndroidApplication::context();
}
/* The strings the activity was started with. Qt is meant to hand the
* "applicationArguments" extra to QCoreApplication::arguments() by itself; on
* the NX789J it does not -- `am start ... --esa applicationArguments
* "--workspace,/sdcard/x"` left the window on its default workspace, and so
* did the same extra as a plain string. So the intent is asked directly, which
* is what makes `cst-agent-app --uitest --workspace DIR` (or any other
* argument) reachable on a device with no keyboard attached.
*
* Everything here degrades to "no arguments": an invalid object, a missing
* method, or a context that is not an activity all come back empty. */
QStringList intentArguments() {
QStringList out;
QJniObject activity = appContext();
if (!activity.isValid())
return out;
QJniObject intent =
activity.callObjectMethod("getIntent", "()Landroid/content/Intent;");
if (!intent.isValid())
return out;
QJniObject list = intent.callObjectMethod(
"getStringArrayListExtra", "(Ljava/lang/String;)Ljava/util/ArrayList;",
QJniObject::fromString(QStringLiteral("applicationArguments"))
.object<jstring>());
if (!list.isValid())
return out;
const jint n = list.callMethod<jint>("size", "()I");
for (jint i = 0; i < n; i++) {
QJniObject item =
list.callObjectMethod("get", "(I)Ljava/lang/Object;", i);
if (item.isValid())
out << item.toString();
}
return out;
}
/* --- notification_send --------------------------------------------------- */
/* Android 13 (API 33) put notifications behind a runtime permission; before
@@ -516,6 +551,11 @@ cst_tool_def_t g_share;
} // namespace
/* What main() asks for (ToolProvider.h): the reading itself is the JNI helper
* above, next to the Android context it needs. It sits outside the anonymous
* namespace so main.cpp can link to it. */
QStringList activityArguments() { return intentArguments(); }
/* A file card's "open": whatever app the phone has for the type, with the read
* permission granted to the app that picks it up. */
QString openLocalFile(const QString &path, const QString &title,