void QLowEnergyControllerPrivate::readDescriptor( const QSharedPointer<QLowEnergyServicePrivate> service, const QLowEnergyHandle /*charHandle*/, const QLowEnergyHandle descriptorHandle) { Q_ASSERT(!service.isNull()); QAndroidJniEnvironment env; bool result = false; if (hub) { qCDebug(QT_BT_ANDROID) << "Read descriptor with handle" << descriptorHandle << service->uuid; result = hub->javaObject().callMethod<jboolean>("readDescriptor", "(I)Z", descriptorHandle); } if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear(); result = false; } if (!result) service->setError(QLowEnergyService::DescriptorReadError); }
void QLowEnergyControllerPrivate::writeDescriptor( const QSharedPointer<QLowEnergyServicePrivate> service, const QLowEnergyHandle /*charHandle*/, const QLowEnergyHandle descHandle, const QByteArray &newValue) { Q_ASSERT(!service.isNull()); QAndroidJniEnvironment env; jbyteArray payload; payload = env->NewByteArray(newValue.size()); env->SetByteArrayRegion(payload, 0, newValue.size(), (jbyte *)newValue.constData()); bool result = false; if (hub) { qCDebug(QT_BT_ANDROID) << "Write descriptor with handle " << descHandle << newValue.toHex() << "(service:" << service->uuid << ")"; result = hub->javaObject().callMethod<jboolean>("writeDescriptor", "(I[B)Z", descHandle, payload); } if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear(); result = false; } env->DeleteLocalRef(payload); if (!result) service->setError(QLowEnergyService::DescriptorWriteError); }
void QLowEnergyControllerPrivate::readCharacteristic( const QSharedPointer<QLowEnergyServicePrivate> service, const QLowEnergyHandle charHandle) { Q_ASSERT(!service.isNull()); if (!service->characteristicList.contains(charHandle)) return; QAndroidJniEnvironment env; bool result = false; if (hub) { qCDebug(QT_BT_ANDROID) << "Read characteristic with handle" << charHandle << service->uuid; result = hub->javaObject().callMethod<jboolean>("readCharacteristic", "(I)Z", charHandle); } if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear(); result = false; } if (!result) service->setError(QLowEnergyService::CharacteristicReadError); }
void QASystemDispatcher::registerNatives() { #ifdef Q_OS_ANDROID QAndroidJniEnvironment env; jclass clazz = env->FindClass(JCLASS_Name); if (!clazz) { qCritical() << QString("Can't find %1 class").arg(QString(JCLASS_Name)); return ; } JNINativeMethod methods[] = { {"jniEmit", EMIT_SIGNATURE, (void *)&jniEmit}, }; int numMethods = sizeof(methods) / sizeof(methods[0]); if (env->RegisterNatives(clazz, methods, numMethods) < 0) { if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear(); qCritical() << "Exception occurred!!!"; return; } } #endif }
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; }
void run() { // Example code to create WebView using C++ method. // However, it is not recommended to construct // everything using C++. It is very troublesome. // It just show how can you execute code with // Android application UI thread QAndroidJniEnvironment env; QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); QAndroidJniObject webView("android/webkit/WebView", "(Landroid/content/Context;)V", activity.object<jobject>()); QAndroidJniObject frameLayout = activity.callObjectMethod("findViewById","(I)Landroid/view/View;", 0x01020002); // Hard coded value of android.R.id.content QAndroidJniObject layout("android/widget/RelativeLayout", "(Landroid/content/Context;)V", activity.object<jobject>()); QAndroidJniObject params = QAndroidJniObject("android/view/ViewGroup$LayoutParams", "(II)V", (int) 0xffffffff, (int) 0xffffffff); layout.callMethod<void>("addView", "(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V", webView.object<jobject>(), params.object<jobject>()); frameLayout.callMethod<void>("addView", "(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V", layout.object<jobject>(), params.object<jobject>()); QAndroidJniObject url = QAndroidJniObject::fromString("http://qt-project.org"); webView.callMethod<void>("loadUrl","(Ljava/lang/String;)V",url.object<jstring>()); if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear(); } }
void QLowEnergyControllerPrivate::writeCharacteristic( const QSharedPointer<QLowEnergyServicePrivate> service, const QLowEnergyHandle charHandle, const QByteArray &newValue, bool writeWithResponse) { //TODO don't ignore WriteWithResponse, right now we assume responses Q_ASSERT(!service.isNull()); if (!service->characteristicList.contains(charHandle)) return; QAndroidJniEnvironment env; jbyteArray payload; payload = env->NewByteArray(newValue.size()); env->SetByteArrayRegion(payload, 0, newValue.size(), (jbyte *)newValue.constData()); bool result = false; if (hub) { qCDebug(QT_BT_ANDROID) << "Write characteristic with handle " << charHandle << newValue.toHex() << "(service:" << service->uuid << ", writeWithResponse:" << writeWithResponse << ")"; result = hub->javaObject().callMethod<jboolean>("writeCharacteristic", "(I[BI)Z", charHandle, payload, writeWithResponse ? QLowEnergyService::WriteWithResponse : QLowEnergyService::WriteWithoutResponse); } if (env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear(); result = false; } env->DeleteLocalRef(payload); if (!result) service->setError(QLowEnergyService::CharacteristicWriteError); }
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; }