From 9d7ad9433e67001afb120b1f7a4797b2def8b4e1 Mon Sep 17 00:00:00 2001 From: WHC Date: Sun, 11 Oct 2026 20:35:41 +0800 Subject: [PATCH] android: the arguments arrive as a String[], not an ArrayList The hook added in da04913 asked for getStringArrayListExtra, but `am start --esa applicationArguments "--uitest,--workspace,/sdcard/x"` stores a String[] -- that call answers null for an array, so the window still started with no arguments at all. Ask for the array first, then the list (Qt's own loader, putStringArrayListExtra), then the single comma-separated string. With this the uitest runs from adb on the NX789J: the fixtures and selftest.pdf land in --workspace, which is how a device round trip is possible without touch injection (adb cannot tap this window). --- app/src/platform/android/AndroidTools.cpp | 60 +++++++++++++++++++---- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/app/src/platform/android/AndroidTools.cpp b/app/src/platform/android/AndroidTools.cpp index 47c6b86..ea5631a 100644 --- a/app/src/platform/android/AndroidTools.cpp +++ b/app/src/platform/android/AndroidTools.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -120,18 +121,57 @@ QStringList intentArguments() { activity.callObjectMethod("getIntent", "()Landroid/content/Intent;"); if (!intent.isValid()) return out; + const QJniObject key = + QJniObject::fromString(QStringLiteral("applicationArguments")); + /* Three shapes for the same extra, and which one arrives depends on who + * sent it: `am start --esa applicationArguments "--uitest,--workspace,/x"` + * stores a String[] (an empty launch, arguments and all, is what that cost + * us -- getStringArrayListExtra answers null for an array), a launcher or + * Qt's own loader uses putStringArrayListExtra, and `--es` puts one + * comma-separated string there. Try each, in that order. */ + const QJniObject array = intent.callObjectMethod( + "getStringArrayExtra", "(Ljava/lang/String;)[Ljava/lang/String;", + key.object()); + if (array.isValid()) { + QJniEnvironment env; + const jobjectArray a = reinterpret_cast(array.object()); + const jsize n = env->GetArrayLength(a); + for (jsize i = 0; i < n; i++) { + const jstring item = + reinterpret_cast(env->GetObjectArrayElement(a, i)); + if (!item) + continue; + const char *c = env->GetStringUTFChars(item, nullptr); + if (c) { + out << QString::fromUtf8(c); + env->ReleaseStringUTFChars(item, c); + } + env->DeleteLocalRef(item); + } + if (!out.isEmpty()) + return out; + } QJniObject list = intent.callObjectMethod( "getStringArrayListExtra", "(Ljava/lang/String;)Ljava/util/ArrayList;", - QJniObject::fromString(QStringLiteral("applicationArguments")) - .object()); - if (!list.isValid()) - return out; - const jint n = list.callMethod("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(); + key.object()); + if (list.isValid()) { + const jint n = list.callMethod("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(); + } + if (!out.isEmpty()) + return out; + } + const QJniObject one = intent.callObjectMethod( + "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;", + key.object()); + if (one.isValid()) { + const QStringList parts = + one.toString().split(QLatin1Char(','), Qt::SkipEmptyParts); + out << parts; } return out; }