diff --git a/qbluetoothleuartclient.cpp b/qbluetoothleuartclient.cpp index cae3f13..fb5d509 100644 --- a/qbluetoothleuartclient.cpp +++ b/qbluetoothleuartclient.cpp @@ -30,28 +30,81 @@ QBluetoothLeUartClient::~QBluetoothLeUartClient(){ // - Slots for QBluetoothLeUart - // ------------------------------ +bool QBluetoothLeUartClient::requestLocationPermission() { + + if(this->isLocationPermissionGranted()) + return true; + +#ifdef Q_OS_ANDROID + // try to get permission + QtAndroid::PermissionResultMap resultMap = QtAndroid::requestPermissionsSync({"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION"}); + bool resultBool = true; + for(QtAndroid::PermissionResult result : resultMap) { + if(result != QtAndroid::PermissionResult::Granted) { + resultBool = false; + } + } + + if(resultBool) { + if(this->state == LocationPermissionDenied) + this->setState(Idle); + return true; + } + + // getting permission the traditional way failed -> open the settings app + QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); //activity is valid + if (activity.isValid()) + { + // get the package name + QAndroidJniObject context = QtAndroid::androidContext(); + QAndroidJniObject applicationPackageName = context.callObjectMethod("getPackageName"); + + QAndroidJniObject param = QAndroidJniObject::fromString("package:" + applicationPackageName.toString()); + + // Equivalent to Jave code: 'Uri uri = Uri::parse("...");' + QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", param.object()); + if (!uri.isValid()) { + qWarning("ERROR: Unable to create Uri object"); + return false; + } + QAndroidJniObject packageName = QAndroidJniObject::fromString("android.settings.APPLICATION_DETAILS_SETTINGS"); + + QAndroidJniObject intent("android/content/Intent","(Ljava/lang/String;)V", packageName.object()); + if (!intent.isValid()) { + qWarning("ERROR: Unable to create Intent object"); + return false; + } + intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("android.intent.category.DEFAULT").object()); + intent.callObjectMethod("setData", "(Landroid/net/Uri;)Landroid/content/Intent;", uri.object()); + + activity.callMethod("startActivity","(Landroid/content/Intent;)V",intent.object()); + } + else { + qWarning() << "ERROR: Activity not valid!"; + return false; + } + + return true; +#else + return false; +#endif + +} + +bool QBluetoothLeUartClient::isLocationPermissionGranted() { +#ifdef Q_OS_ANDROID + QtAndroid::PermissionResult fineLocationAccess = QtAndroid::checkPermission("android.permission.ACCESS_FINE_LOCATION"); + QtAndroid::PermissionResult coarseLocationAccess = QtAndroid::checkPermission("android.permission.ACCESS_COARSE_LOCATION"); + + return fineLocationAccess == QtAndroid::PermissionResult::Granted && coarseLocationAccess == QtAndroid::PermissionResult::Granted; +#else + return true; +#endif +} + bool QBluetoothLeUartClient::startScanningForDevices(){ if(this->state != Idle && this->state != AdapterTurnedOff && this->state != ScanFinished && this->state != LocationPermissionDenied) return false; -#ifdef Q_OS_ANDROID - else if(this->state == LocationPermissionDenied) { - // try to get permission - QtAndroid::PermissionResultMap resultMap = QtAndroid::requestPermissionsSync({"android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION"}); - bool resultBool = true; - for(QtAndroid::PermissionResult result : resultMap) { - if(result != QtAndroid::PermissionResult::Granted) { - resultBool = false; - break; - } - } - - if(!resultBool) { - emit this->scanningErrorOccured(LocationPermissionDeniedError); - return false; - } - - } -#endif this->availableDevicesModel->clear(); @@ -233,20 +286,15 @@ void QBluetoothLeUartClient::handleDeviceScanError(QBluetoothDeviceDiscoveryAgen this->setState(AdapterTurnedOff); emit this->scanningErrorOccured(InputOutputError); } -#ifdef Q_OS_ANDROID else if (error == QBluetoothDeviceDiscoveryAgent::UnknownError) { // check for permission error - QtAndroid::PermissionResult fineLocationAccess = QtAndroid::checkPermission("android.permission.ACCESS_FINE_LOCATION"); - QtAndroid::PermissionResult coarseLocationAccess = QtAndroid::checkPermission("android.permission.ACCESS_COARSE_LOCATION"); - - if(fineLocationAccess != QtAndroid::PermissionResult::Granted || coarseLocationAccess != QtAndroid::PermissionResult::Granted) { + if(!this->isLocationPermissionGranted()) { this->setState(LocationPermissionDenied); emit this->scanningErrorOccured(LocationPermissionDeniedError); } else emit this->scanningErrorOccured(UnknownError); } -#endif else emit this->scanningErrorOccured(UnknownError); @@ -372,7 +420,7 @@ void QBluetoothLeUartClient::handleServiceCharacteristicChange(const QLowEnergyC } void QBluetoothLeUartClient::handleServiceDescriptorWritten(const QLowEnergyDescriptor &d, - const QByteArray &value) + const QByteArray &value) { if (d.isValid() && d == bluetoothTransmissionDescriptor && value == QByteArray("0000")) { //disabled notifications -> assume disconnect intent diff --git a/qbluetoothleuartclient.h b/qbluetoothleuartclient.h index 8914646..1707d44 100644 --- a/qbluetoothleuartclient.h +++ b/qbluetoothleuartclient.h @@ -192,6 +192,10 @@ private: public slots: + Q_INVOKABLE bool requestLocationPermission(); + + Q_INVOKABLE bool isLocationPermissionGranted(); + /*! * \brief Fuction to start scanning for devices *