diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index 28751cdc99aca2a34347ebdcc355e0deae7dd780..4cfc937603cfe7578f41b6675b7ebd3298ccdc4d 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
diff --git a/android/src/org/mavlink/qgroundcontrol/QGCActivity.java b/android/src/org/mavlink/qgroundcontrol/QGCActivity.java
index a716392e6eacc4a9a920f2d9cc0f70533a63a836..c3f4fbe8b65af037e0f3247962c42af6c1522d48 100644
--- a/android/src/org/mavlink/qgroundcontrol/QGCActivity.java
+++ b/android/src/org/mavlink/qgroundcontrol/QGCActivity.java
@@ -48,6 +48,7 @@ import android.util.Log;
import android.os.PowerManager;
import android.view.WindowManager;
import android.os.Bundle;
+import android.bluetooth.BluetoothDevice;
import com.hoho.android.usbserial.driver.*;
import org.qtproject.qt5.android.bindings.QtActivity;
@@ -133,6 +134,12 @@ public class QGCActivity extends QtActivity
}
}
}
+
+ try {
+ nativeUpdateAvailableJoysticks();
+ } catch(Exception e) {
+ Log.e(TAG, "Exception nativeUpdateAvailableJoysticks()");
+ }
}
};
@@ -140,6 +147,7 @@ public class QGCActivity extends QtActivity
private static native void nativeDeviceHasDisconnected(int userData);
private static native void nativeDeviceException(int userData, String messageA);
private static native void nativeDeviceNewData(int userData, byte[] dataA);
+ private static native void nativeUpdateAvailableJoysticks();
// Native C++ functions called to log output
public static native void qgcLogDebug(String message);
@@ -171,8 +179,11 @@ public class QGCActivity extends QtActivity
// Register for USB Detach and USB Permission intent
IntentFilter filter = new IntentFilter();
+ filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
filter.addAction(ACTION_USB_PERMISSION);
+ filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
+ filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
_instance.registerReceiver(_instance._usbReceiver, filter);
// Create intent for usb permission request
diff --git a/src/Joystick/JoystickAndroid.cc b/src/Joystick/JoystickAndroid.cc
index d66f0c0b928499271c248b828c3b99196092c408..3a1a1da31d9bbd9f277ef3cefc2551b35955b684 100644
--- a/src/Joystick/JoystickAndroid.cc
+++ b/src/Joystick/JoystickAndroid.cc
@@ -134,7 +134,6 @@ QMap JoystickAndroid::discover(MultiVehicleManager* _multiVe
env->ReleaseIntArrayElements(jarr, buff, 0);
-
return ret;
}
@@ -171,7 +170,6 @@ bool JoystickAndroid::handleGenericMotionEvent(jobject event) {
return true;
}
-
bool JoystickAndroid::_open(void) {
return true;
}
@@ -199,8 +197,14 @@ uint8_t JoystickAndroid::_getHat(int hat,int i) {
return 0;
}
+static JoystickManager *_manager = nullptr;
+
//helper method
-bool JoystickAndroid::init() {
+bool JoystickAndroid::init(JoystickManager *manager) {
+ if (_manager == nullptr) {
+ setNativeMethods(manager);
+ }
+
//this gets list of all possible buttons - this is needed to check how many buttons our gamepad supports
//instead of the whole logic below we could have just a simple array of hardcoded int values as these 'should' not change
@@ -239,3 +243,52 @@ bool JoystickAndroid::init() {
return true;
}
+static const char kJniClassName[] {"org/mavlink/qgroundcontrol/QGCActivity"};
+
+static void jniUpdateAvailableJoysticks(JNIEnv *envA, jobject thizA)
+{
+ Q_UNUSED(envA);
+ Q_UNUSED(thizA);
+
+ if (_manager != nullptr) {
+ qCDebug(JoystickLog) << "jniUpdateAvailableJoysticks triggered";
+ emit _manager->updateAvailableJoysticksSignal();
+ }
+}
+
+void JoystickAndroid::setNativeMethods(JoystickManager *manager)
+{
+ qCDebug(JoystickLog) << "Registering Native Functions";
+
+ _manager = manager;
+
+ // REGISTER THE C++ FUNCTION WITH JNI
+ JNINativeMethod javaMethods[] {
+ {"nativeUpdateAvailableJoysticks", "()V", reinterpret_cast(jniUpdateAvailableJoysticks)}
+ };
+
+ QAndroidJniEnvironment jniEnv;
+ if (jniEnv->ExceptionCheck()) {
+ jniEnv->ExceptionDescribe();
+ jniEnv->ExceptionClear();
+ }
+
+ jclass objectClass = jniEnv->FindClass(kJniClassName);
+ if(!objectClass) {
+ qWarning() << "Couldn't find class:" << kJniClassName;
+ return;
+ }
+
+ jint val = jniEnv->RegisterNatives(objectClass, javaMethods, sizeof(javaMethods) / sizeof(javaMethods[0]));
+
+ if (val < 0) {
+ qWarning() << "Error registering methods: " << val;
+ } else {
+ qCDebug(JoystickLog) << "Native Functions Registered";
+ }
+
+ if (jniEnv->ExceptionCheck()) {
+ jniEnv->ExceptionDescribe();
+ jniEnv->ExceptionClear();
+ }
+}
diff --git a/src/Joystick/JoystickAndroid.h b/src/Joystick/JoystickAndroid.h
index 78defedf51fc568d22a0cf084c1374e5d6ba9fdf..329194ed65d9273ba216abc6736504829a5777ce 100644
--- a/src/Joystick/JoystickAndroid.h
+++ b/src/Joystick/JoystickAndroid.h
@@ -19,7 +19,7 @@ public:
~JoystickAndroid();
- static bool init();
+ static bool init(JoystickManager *manager);
static QMap discover(MultiVehicleManager* _multiVehicleManager);
@@ -27,6 +27,8 @@ private:
bool handleKeyEvent(jobject event);
bool handleGenericMotionEvent(jobject event);
+ static void setNativeMethods(JoystickManager *manager);
+
virtual bool _open();
virtual void _close();
virtual bool _update();
diff --git a/src/Joystick/JoystickManager.cc b/src/Joystick/JoystickManager.cc
index 2383a4b6ac19cce9ee77e92d34b6e8d65d35d48e..1cac13960e590b2b8424914a6e0a0b3d713a5f44 100644
--- a/src/Joystick/JoystickManager.cc
+++ b/src/Joystick/JoystickManager.cc
@@ -59,11 +59,13 @@ void JoystickManager::init() {
}
_setActiveJoystickFromSettings();
#elif defined(__android__)
- if (!JoystickAndroid::init()) {
+ if (!JoystickAndroid::init(this)) {
return;
}
+ connect(this, &JoystickManager::updateAvailableJoysticksSignal, this, &JoystickManager::restartJoystickCheckTimer);
#endif
connect(&_joystickCheckTimer, &QTimer::timeout, this, &JoystickManager::_updateAvailableJoysticks);
+ _joystickCheckTimerCounter = 5;
_joystickCheckTimer.start(1000);
}
@@ -185,7 +187,7 @@ void JoystickManager::setActiveJoystickName(const QString& name)
/*
* TODO: move this to the right place: JoystickSDL.cc and JoystickAndroid.cc respectively and call through Joystick.cc
*/
-void JoystickManager::_updateAvailableJoysticks(void)
+void JoystickManager::_updateAvailableJoysticks()
{
#ifdef __sdljoystick__
SDL_Event event;
@@ -207,6 +209,16 @@ void JoystickManager::_updateAvailableJoysticks(void)
}
}
#elif defined(__android__)
+ _joystickCheckTimerCounter--;
_setActiveJoystickFromSettings();
+ if (_joystickCheckTimerCounter <= 0) {
+ _joystickCheckTimer.stop();
+ }
#endif
}
+
+void JoystickManager::restartJoystickCheckTimer()
+{
+ _joystickCheckTimerCounter = 5;
+ _joystickCheckTimer.start(1000);
+}
diff --git a/src/Joystick/JoystickManager.h b/src/Joystick/JoystickManager.h
index 6418886b404868e3fcfe07f39baa785a373b4af1..f6736ff8a91b094c5a8b7db776e5a9ad927548f0 100644
--- a/src/Joystick/JoystickManager.h
+++ b/src/Joystick/JoystickManager.h
@@ -45,6 +45,8 @@ public:
QString activeJoystickName(void);
void setActiveJoystickName(const QString& name);
+ void restartJoystickCheckTimer(void);
+
// Override from QGCTool
virtual void setToolbox(QGCToolbox *toolbox);
@@ -55,6 +57,7 @@ signals:
void activeJoystickChanged(Joystick* joystick);
void activeJoystickNameChanged(const QString& name);
void availableJoysticksChanged(void);
+ void updateAvailableJoysticksSignal();
private slots:
void _updateAvailableJoysticks(void);
@@ -70,6 +73,7 @@ private:
static const char * _settingsGroup;
static const char * _settingsKeyActiveJoystick;
+ int _joystickCheckTimerCounter;
QTimer _joystickCheckTimer;
};