如何通过QAndroidJniObject获取Android Intent的所有Extras?
获取Android Intent的所有Extras并转换为QMap<QString, QVariant>(C++/Qt)
要在Qt C++侧实现这个需求,得通过JNI调用Android原生API遍历Intent的Extras Bundle,再把每个键值对转换成Qt的类型。以下是完整实现方案:
核心步骤
- 从Intent对象中获取Extras对应的Bundle实例
- 遍历Bundle的所有键集合
- 根据每个键对应值的Java类型,转换为QVariant
- 将键值对存入QMap
完整代码实现
#include <QAndroidJniObject> #include <QMap> #include <QVariant> #include <QDebug> // 递归处理嵌套Bundle(可选,根据需求启用) QVariant convertJniValueToQVariant(const QAndroidJniObject &jniValue); QMap<QString, QVariant> getIntentExtras(const QAndroidJniObject &intent) { QMap<QString, QVariant> extrasMap; // 获取Intent的Extras Bundle QAndroidJniObject bundle = intent.callObjectMethod("getExtras", "()Landroid/os/Bundle;"); if (bundle.isNull()) { return extrasMap; } // 获取Bundle中所有键的Set集合 QAndroidJniObject keySet = bundle.callObjectMethod("keySet", "()Ljava/util/Set;"); QAndroidJniObject iterator = keySet.callObjectMethod("iterator", "()Ljava/util/Iterator;"); // 遍历所有键 while (iterator.callMethod<jboolean>("hasNext")) { QAndroidJniObject key = iterator.callObjectMethod("next", "()Ljava/lang/Object;"); QString keyStr = key.toString(); // 根据键获取对应的值 QAndroidJniObject value = bundle.callObjectMethod("get", "(Ljava/lang/String;)Ljava/lang/Object;", key.object<jstring>()); if (value.isNull()) { extrasMap.insert(keyStr, QVariant()); continue; } // 转换Java类型到QVariant QVariant variantValue = convertJniValueToQVariant(value); extrasMap.insert(keyStr, variantValue); } // 检查JNI调用是否有异常 if (QAndroidJniEnvironment::CheckException()) { QAndroidJniEnvironment env; env->ExceptionClear(); qWarning() << "JNI exception occurred while processing Intent extras"; } return extrasMap; } QVariant convertJniValueToQVariant(const QAndroidJniObject &jniValue) { // 获取对象的类名 QAndroidJniObject className = jniValue.callObjectMethod("getClass", "()Ljava/lang/Class;"); className = className.callObjectMethod("getName", "()Ljava/lang/String;"); QString typeName = className.toString(); // 处理常见类型 if (typeName == "java.lang.String") { return QVariant(jniValue.toString()); } else if (typeName == "java.lang.Integer") { return QVariant(jniValue.callMethod<jint>("intValue")); } else if (typeName == "java.lang.Long") { return QVariant(jniValue.callMethod<jlong>("longValue")); } else if (typeName == "java.lang.Boolean") { return QVariant(jniValue.callMethod<jboolean>("booleanValue")); } else if (typeName == "java.lang.Float") { return QVariant(jniValue.callMethod<jfloat>("floatValue")); } else if (typeName == "java.lang.Double") { return QVariant(jniValue.callMethod<jdouble>("doubleValue")); } else if (typeName == "android.os.Bundle") { // 递归处理嵌套Bundle QMap<QString, QVariant> nestedMap; QAndroidJniObject keySet = jniValue.callObjectMethod("keySet", "()Ljava/util/Set;"); QAndroidJniObject iterator = keySet.callObjectMethod("iterator", "()Ljava/util/Iterator;"); while (iterator.callMethod<jboolean>("hasNext")) { QAndroidJniObject key = iterator.callObjectMethod("next", "()Ljava/lang/Object;"); QString keyStr = key.toString(); QAndroidJniObject nestedValue = jniValue.callObjectMethod("get", "(Ljava/lang/String;)Ljava/lang/Object;", key.object<jstring>()); nestedMap.insert(keyStr, convertJniValueToQVariant(nestedValue)); } return QVariant::fromValue(nestedMap); } // 可根据需求扩展其他类型(如数组、Parcelable等) else { qWarning() << "Unsupported extra type:" << typeName; return QVariant(); } }
使用示例
// 假设你已经有了Intent的QAndroidJniObject实例 QAndroidJniObject intent = ...; // 比如从Activity中获取 QMap<QString, QVariant> extras = getIntentExtras(intent); // 遍历输出Extras for (auto it = extras.constBegin(); it != extras.constEnd(); ++it) { qDebug() << "Key:" << it.key() << "Value:" << it.value(); }
注意事项
- 代码中处理了常见的基础类型和嵌套Bundle,若需要支持更多类型(如字符串数组、Parcelable对象等),可在
convertJniValueToQVariant函数中扩展对应类型的转换逻辑。 - 每次JNI调用后建议检查异常,避免未处理的JNI异常导致程序崩溃。
- 确保项目已正确配置Qt Android环境,包含必要的JNI头文件和依赖。
内容的提问来源于stack exchange,提问作者Fausto01
相关产品推荐
相关产品推荐

