diff --git a/android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java b/android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java index f9bad7086d1b6fc065ebb9751d7d3651d6ab6846..b317c408c1081606512abcb7da7e84febfe3456f 100644 --- a/android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java +++ b/android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java @@ -79,7 +79,6 @@ public class UsbDeviceJNI extends QtActivity } }; - // NATIVE C++ FUNCTION THAT WILL BE CALLED IF THE DEVICE IS UNPLUGGED private static native void nativeDeviceHasDisconnected(int userDataA); private static native void nativeDeviceException(int userDataA, String messageA); diff --git a/libs/qtandroidserialport/src/qserialport.cpp b/libs/qtandroidserialport/src/qserialport.cpp index 54cbee2e28e7a06c9db986e970a0215ae6886cf5..c306e7f5d4df1bcd078291c953e45a142e652000 100644 --- a/libs/qtandroidserialport/src/qserialport.cpp +++ b/libs/qtandroidserialport/src/qserialport.cpp @@ -1370,6 +1370,12 @@ void QSerialPort::setError(QSerialPort::SerialPortError serialPortError, const Q emit error(serialPortError); } +void QSerialPort::setNativeMethods(void) +{ + QSerialPortPrivate::setNativeMethods(); +} + + #include "moc_qserialport.cpp" QT_END_NAMESPACE diff --git a/libs/qtandroidserialport/src/qserialport.h b/libs/qtandroidserialport/src/qserialport.h index e1b6aea92d2ced14cf3a7f5dda84b05ee4d33a6f..0fae3545ad8a70fa17292d16718e07512a951d77 100644 --- a/libs/qtandroidserialport/src/qserialport.h +++ b/libs/qtandroidserialport/src/qserialport.h @@ -247,6 +247,8 @@ public: Handle handle() const; + static void setNativeMethods(void); + Q_SIGNALS: void baudRateChanged(qint32 baudRate, QSerialPort::Directions directions); void dataBitsChanged(QSerialPort::DataBits dataBits); diff --git a/libs/qtandroidserialport/src/qserialport_android.cpp b/libs/qtandroidserialport/src/qserialport_android.cpp index 4c15cd2ea97f092d6f5eafda80aec03fc45e7447..675805a459572798b2cd078cc728e82d17918a57 100644 --- a/libs/qtandroidserialport/src/qserialport_android.cpp +++ b/libs/qtandroidserialport/src/qserialport_android.cpp @@ -106,7 +106,6 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) , isCustomBaudRateSupported(false) , emittedBytesWritten(false) , pendingBytesWritten(0) - , hasRegisteredFunctions(false) , jniDataBits(8) , jniStopBits(1) , jniParity(0) @@ -115,6 +114,43 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) { } +void QSerialPortPrivate::setNativeMethods(void) +{ + __android_log_print(ANDROID_LOG_INFO, kJTag, "Registering Native Functions"); + + // REGISTER THE C++ FUNCTION WITH JNI + JNINativeMethod javaMethods[] { + {"nativeDeviceHasDisconnected", "(I)V", reinterpret_cast(jniDeviceHasDisconnected)}, + {"nativeDeviceNewData", "(I[B)V", reinterpret_cast(jniDeviceNewData)}, + {"nativeDeviceException", "(ILjava/lang/String;)V", reinterpret_cast(jniDeviceException)} + }; + + QAndroidJniEnvironment jniEnv; + if (jniEnv->ExceptionCheck()) { + jniEnv->ExceptionDescribe(); + jniEnv->ExceptionClear(); + } + + jclass objectClass = jniEnv->FindClass(kJniClassName); + if(!objectClass) { + __android_log_print(ANDROID_LOG_ERROR, kJTag, "Couldn't find class: %s", kJniClassName); + return; + } + + jint val = jniEnv->RegisterNatives(objectClass, javaMethods, sizeof(javaMethods) / sizeof(javaMethods[0])); + + __android_log_print(ANDROID_LOG_INFO, kJTag, "Native Functions Registered"); + + if (jniEnv->ExceptionCheck()) { + jniEnv->ExceptionDescribe(); + jniEnv->ExceptionClear(); + } + + if (val < 0) { + __android_log_print(ANDROID_LOG_ERROR, kJTag, "Error registering methods"); + } +} + bool QSerialPortPrivate::open(QIODevice::OpenMode mode) { rwMode = mode; @@ -140,45 +176,6 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode) return false; } - if (!hasRegisteredFunctions) - { - __android_log_print(ANDROID_LOG_INFO, kJTag, "Registering Native Functions"); - // REGISTER THE C++ FUNCTION WITH JNI - JNINativeMethod javaMethods[] { - {"nativeDeviceHasDisconnected", "(I)V", reinterpret_cast(jniDeviceHasDisconnected)}, - {"nativeDeviceNewData", "(I[B)V", reinterpret_cast(jniDeviceNewData)}, - {"nativeDeviceException", "(ILjava/lang/String;)V", reinterpret_cast(jniDeviceException)} - }; - - QAndroidJniEnvironment jniEnv; - if (jniEnv->ExceptionCheck()) { - jniEnv->ExceptionDescribe(); - jniEnv->ExceptionClear(); - } - - QAndroidJniObject javaClass(kJniClassName); - if(!javaClass.isValid()) { - __android_log_print(ANDROID_LOG_ERROR, kJTag, "Java class %s not valid", kJniClassName); - return false; - } - jclass objectClass = jniEnv->GetObjectClass(javaClass.object()); - jint val = jniEnv->RegisterNatives(objectClass, javaMethods, sizeof(javaMethods) / sizeof(javaMethods[0])); - jniEnv->DeleteLocalRef(objectClass); - hasRegisteredFunctions = true; - __android_log_print(ANDROID_LOG_INFO, kJTag, "Native Functions Registered"); - - if (jniEnv->ExceptionCheck()) { - jniEnv->ExceptionDescribe(); - jniEnv->ExceptionClear(); - } - - if(val < 0) { - __android_log_print(ANDROID_LOG_ERROR, kJTag, "Error registering methods"); - q_ptr->setError(QSerialPort::OpenError); - return false; - } - } - __android_log_print(ANDROID_LOG_INFO, kJTag, "Calling Java getDeviceHandle"); cleanJavaException(); descriptor = QAndroidJniObject::callStaticMethod( diff --git a/libs/qtandroidserialport/src/qserialport_android_p.h b/libs/qtandroidserialport/src/qserialport_android_p.h index f105c1fd74f0441ede8327a2b9bd297aa5bef232..c10c41cc4a29cd61b0d9b6213a9abca9821fd695 100644 --- a/libs/qtandroidserialport/src/qserialport_android_p.h +++ b/libs/qtandroidserialport/src/qserialport_android_p.h @@ -108,10 +108,11 @@ public: qint64 pendingBytesWritten; + static void setNativeMethods(void); + private: QIODevice::OpenMode rwMode; int deviceId; - bool hasRegisteredFunctions; int jniDataBits; int jniStopBits; int jniParity; diff --git a/src/main.cc b/src/main.cc index 1b48c55ca2565b1860afe24dcbe1f5832b4b7923..3fa649377c45f4b9af6819a415f0721a99c1da1f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -86,6 +86,25 @@ int WindowsCrtReportHook(int reportType, char* message, int* returnValue) #endif +#ifdef __android__ +#include +#include "qserialport.h" + +jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + Q_UNUSED(reserved); + + JNIEnv* env; + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { + return -1; + } + + QSerialPort::setNativeMethods(); + + return JNI_VERSION_1_6; +} +#endif + /** * @brief Starts the application *