static jobject createHashMap(const QVariantMap &data) {
    QAndroidJniEnvironment env;

    jclass mapClass = env->FindClass("java/util/HashMap");

    if (mapClass == NULL)  {
        qWarning() << "Failed to find class" << "java/util/HashMap";
        return NULL;
    }

    jclass integerClass = env->FindClass("java/lang/Integer");

    jmethodID integerConstructor = env->GetMethodID(integerClass, "<init>", "(I)V");

    jclass booleanClass = env->FindClass("java/lang/Boolean");
    jmethodID booleanConstructor = env->GetMethodID(booleanClass,"<init>","(Z)V");


    jsize map_len = data.size();

    jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V");
    jobject hashMap = env->NewObject( mapClass, init, map_len);

    jmethodID put = env->GetMethodID( mapClass, "put",
                "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");


    QMapIterator<QString, QVariant> iter(data);
    while (iter.hasNext()) {
        iter.next();

//        qDebug() << iter.key() << iter.value();
        QString key = iter.key();
        jstring jkey = env->NewStringUTF(key.toLocal8Bit().data());
        QVariant v = iter.value();
        if (v.type() == QVariant::String) {
            QString str = v.toString();
            jstring vString = env->NewStringUTF(str.toLocal8Bit().data());
            env->CallObjectMethod(hashMap,put,jkey,vString);
        } else if (v.type() == QVariant::Int) {
            jobject integer = env->NewObject(integerClass,integerConstructor,v.toInt());
            env->CallObjectMethod(hashMap,put,jkey,integer);
        } else if (v.type() == QVariant::Bool) {
            jobject boolean = env->NewObject(booleanClass,booleanConstructor,v.toBool());
            env->CallObjectMethod(hashMap,put,jkey,boolean);
        } else {
            qWarning() << "QASystemDispatcher: Non-supported data type - " <<  v.type();
        }
     }

    if (env->ExceptionOccurred()) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }

    return hashMap;
}
Exemplo n.º 2
0
float ScreenValues::retrieveDensity()
{
#ifdef Q_OS_ANDROID
    QAndroidJniEnvironment env;
    env->PushLocalFrame(9);

    QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative",
                                                                           "activity",
                                                                           "()Landroid/app/Activity;");
    jclass activityClass = env->GetObjectClass(activity.object<jobject>());

    jmethodID mIDGetResources = env->GetMethodID(activityClass,
                                                 "getResources",
                                                 "()Landroid/content/res/Resources;");

    jobject resources = env->CallObjectMethod(activity.object<jobject>(), mIDGetResources);
    jclass resourcesClass = env->GetObjectClass(resources);

    jmethodID mIDGetDisplayMetrics = env->GetMethodID(resourcesClass,
                                                      "getDisplayMetrics",
                                                      "()Landroid/util/DisplayMetrics;");

    jobject displayMetrics = env->CallObjectMethod(resources, mIDGetDisplayMetrics);
    jclass displayMetricsClass = env->GetObjectClass(displayMetrics);

    jfieldID fIDDensityDpi = env->GetFieldID(displayMetricsClass, "density", "F");
    jfloat densityDpi = env->GetFloatField(displayMetrics, fIDDensityDpi);

    float result = (float)densityDpi;

    env->PopLocalFrame(NULL);

    return result;
#else
    return QGuiApplication::primaryScreen()->physicalDotsPerInch();
#endif
}
bool QBluetoothSocketPrivate::fallBackConnect(QAndroidJniObject uuid, int channel)
{
    qCWarning(QT_BT_ANDROID) << "Falling back to workaround.";

    QAndroidJniEnvironment env;
    jclass remoteDeviceClazz = env->GetObjectClass(remoteDevice.object());
    jmethodID getClassMethod = env->GetMethodID(remoteDeviceClazz, "getClass", "()Ljava/lang/Class;");
    if (!getClassMethod) {
        qCWarning(QT_BT_ANDROID) << "BluetoothDevice.getClass method could not be found.";
        return false;
    }


    QAndroidJniObject remoteDeviceClass = QAndroidJniObject(env->CallObjectMethod(remoteDevice.object(), getClassMethod));
    if (!remoteDeviceClass.isValid()) {
        qCWarning(QT_BT_ANDROID) << "Could not invoke BluetoothDevice.getClass.";
        return false;
    }

    jclass classClass = env->FindClass("java/lang/Class");
    jclass integerClass = env->FindClass("java/lang/Integer");
    jfieldID integerType = env->GetStaticFieldID(integerClass, "TYPE", "Ljava/lang/Class;");
    jobject integerObject = env->GetStaticObjectField(integerClass, integerType);
    if (!integerObject) {
        qCWarning(QT_BT_ANDROID) << "Could not get Integer.TYPE";
        return false;
    }

    jobjectArray paramTypes = env->NewObjectArray(1, classClass, integerObject);
    if (!paramTypes) {
        qCWarning(QT_BT_ANDROID) << "Could not create new Class[]{Integer.TYPE}";
        return false;
    }

    QAndroidJniObject parcelUuid("android/os/ParcelUuid", "(Ljava/util/UUID;)V",
                                 uuid.object());
    if (parcelUuid.isValid()) {
        jint socketChannel = remoteDevice.callMethod<jint>("getServiceChannel",
                                                           "(Landroid/os/ParcelUuid;)I",
                                                           parcelUuid.object());
        if (env->ExceptionCheck()) {
            env->ExceptionDescribe();
            env->ExceptionClear();
        }

        if (socketChannel
                == remoteDevice.getStaticField<jint>("android/bluetooth/BluetoothDevice", "ERROR")) {
            qCWarning(QT_BT_ANDROID) << "Cannot determine RFCOMM service channel.";
        } else {
            qCWarning(QT_BT_ANDROID) << "Using found rfcomm channel" << socketChannel;
            channel = socketChannel;
        }
    }

    QAndroidJniObject method = remoteDeviceClass.callObjectMethod(
                "getMethod",
                "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;",
                QAndroidJniObject::fromString(QLatin1String("createRfcommSocket")).object<jstring>(),
                paramTypes);
    if (!method.isValid() || env->ExceptionCheck()) {
        qCWarning(QT_BT_ANDROID) << "Could not invoke getMethod";
        if (env->ExceptionCheck()) {
            env->ExceptionDescribe();
            env->ExceptionClear();
        }
        return false;
    }

    jclass methodClass = env->GetObjectClass(method.object());
    jmethodID invokeMethodId = env->GetMethodID(
                methodClass, "invoke",
                "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
    if (!invokeMethodId) {
        qCWarning(QT_BT_ANDROID) << "Could not invoke method.";
        return false;
    }

    jmethodID valueOfMethodId = env->GetStaticMethodID(integerClass, "valueOf", "(I)Ljava/lang/Integer;");
    jclass objectClass = env->FindClass("java/lang/Object");
    jobjectArray invokeParams = env->NewObjectArray(1, objectClass, env->CallStaticObjectMethod(integerClass, valueOfMethodId, channel));


    jobject invokeResult = env->CallObjectMethod(method.object(), invokeMethodId,
                                                 remoteDevice.object(), invokeParams);
    if (!invokeResult)
    {
        qCWarning(QT_BT_ANDROID) << "Invoke Resulted with error.";
        if (env->ExceptionCheck()) {
            env->ExceptionDescribe();
            env->ExceptionClear();
        }
        return false;
    }

    socketObject = QAndroidJniObject(invokeResult);
    socketObject.callMethod<void>("connect");
    if (env->ExceptionCheck()) {
        env->ExceptionDescribe();
        env->ExceptionClear();

        qCWarning(QT_BT_ANDROID) << "Socket connect via workaround failed.";

        return false;
    }

    qCWarning(QT_BT_ANDROID) << "Workaround invoked.";
    return true;
}
static QVariantMap createVariantMap(jobject data) {
    QVariantMap res;

    QAndroidJniEnvironment env;
    /* Reference : https://community.oracle.com/thread/1549999 */

    // Get the HashMap Class
    jclass jclass_of_hashmap = (env)->GetObjectClass(data);

    // Get link to Method "entrySet"
    jmethodID entrySetMethod = (env)->GetMethodID(jclass_of_hashmap, "entrySet", "()Ljava/util/Set;");

    // Invoke the "entrySet" method on the HashMap object
    jobject jobject_of_entryset = env->CallObjectMethod(data, entrySetMethod);

    // Get the Set Class
    jclass jclass_of_set = (env)->FindClass("java/util/Set"); // Problem during compilation !!!!!

    if (jclass_of_set == 0) {
         qWarning() << "java/util/Set lookup failed\n";
         return res;
    }

    jclass jclass_of_string = env->FindClass("java/lang/String");
    jclass jclass_of_integer = env->FindClass("java/lang/Integer");
    jclass jclass_of_boolean = env->FindClass("java/lang/Boolean");


    // Get link to Method "iterator"
    jmethodID iteratorMethod = env->GetMethodID(jclass_of_set, "iterator", "()Ljava/util/Iterator;");

    // Invoke the "iterator" method on the jobject_of_entryset variable of type Set
    jobject jobject_of_iterator = env->CallObjectMethod(jobject_of_entryset, iteratorMethod);

    // Get the "Iterator" class
    jclass jclass_of_iterator = (env)->FindClass("java/util/Iterator");

    // Get link to Method "hasNext"
    jmethodID hasNextMethod = env->GetMethodID(jclass_of_iterator, "hasNext", "()Z");

    jmethodID nextMethod = env->GetMethodID(jclass_of_iterator, "next", "()Ljava/lang/Object;");

    while (env->CallBooleanMethod(jobject_of_iterator, hasNextMethod) ) {
        QAndroidJniObject entry = env->CallObjectMethod(jobject_of_iterator,nextMethod);
        QAndroidJniObject key = entry.callObjectMethod("getKey","()Ljava/lang/Object;");
        QAndroidJniObject value = entry.callObjectMethod("getValue","()Ljava/lang/Object;");
        QString k = key.toString();

        if (!value.isValid())
            continue;

        if (env->IsInstanceOf(value.object<jobject>(),jclass_of_boolean)) {
            res[k] = QVariant::fromValue<bool>(value.callMethod<jboolean>("booleanValue","()Z"));
        } else if (env->IsInstanceOf(value.object<jobject>(),jclass_of_integer)) {
            res[k] = value.callMethod<jint>("intValue","()I");
        } else if (env->IsInstanceOf(value.object<jobject>(),jclass_of_string)) {
            QString v = value.toString();
            res[k] = v;
        }
    }

    if (env->ExceptionOccurred()) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }

    // Delete local reference
    return res;
}