void ScreenValues::updateScreenValues() { #ifdef Q_OS_ANDROID if (m_system.sdkInt() >= 19) { QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); QAndroidJniObject wm = activity.callObjectMethod("getWindowManager", "()Landroid/view/WindowManager;"); QAndroidJniObject display = wm.callObjectMethod("getDefaultDisplay", "()Landroid/view/Display;"); QAndroidJniObject realSize = QAndroidJniObject("android/graphics/Point"); display.callMethod<void>("getRealSize", "(Landroid/graphics/Point;)V", realSize.object()); QAndroidJniObject displayFrame = QAndroidJniObject("android/graphics/Rect"); QAndroidJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;"); QAndroidJniObject view = window.callObjectMethod("getDecorView", "()Landroid/view/View;"); QAndroidJniObject rootView = view.callObjectMethod("getRootView", "()Landroid/view/View;"); rootView.callMethod<void>("getWindowVisibleDisplayFrame", "(Landroid/graphics/Rect;)V", displayFrame.object()); if (((int) realSize.getField<jint>("y") - (int) displayFrame.callMethod<jint>("height")) - m_statusBarHeight == 0) setNavBarVisible(false); else setNavBarVisible(true); } #endif }
AsemanAndroidLocationListenerCore *getLocationListenerObject(jobject obj) { QHashIterator<jobject, AsemanAndroidLocationListenerCore*> i(android_location_listener_objects); while(i.hasNext()) { i.next(); if(QAndroidJniObject(i.key()) == QAndroidJniObject(obj)) return i.value(); } return 0; }
QAndroidJniObject QQmlAndroidScrollView::onCreate() { return QAndroidJniObject("qt/android/widget/QmlScrollView", "(Landroid/content/Context;J)V", ctx().object(), reinterpret_cast<jlong>(this)); }
void PaymentAndroid::init() { QAndroidJniObject payClass(PAYMENT_CLASS_NAME_C_STR); m_class = QAndroidJniObject(PAYMENT_CLASS_NAME_C_STR); if(!m_class.isValid()){ qCritical() << "Can't find class : " << PAYMENT_CLASS_NAME; } // QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); // QAndroidJniObject activity = QtAndroid::androidActivity(); // if(!activity.isValid()) // qCritical() << "Activity is not valid!"; // QAndroidJniObject fragment = m_class.callObjectMethod( // "createBraintreeFragment", // "(Landroid/app/Activity;)Lcom/braintreepayments/api/BraintreeFragment;", // activity.object<jobject>()); // if(!fragment.isValid()) // qCritical() << "Fragment is not valid!"; // QAndroidJniObject result = m_class.getObjectField<jstring>("fragmentResult"); // if(result.isValid()) // qDebug() << "fragment result: " << result.toString(); // else // qCritical() << "Result is not valid!"; // QAndroidJniObject sessionId = fragment.callObjectMethod<jstring>("getSessionId"); // qDebug() << "session id: " << sessionId.toString(); }
QAndroidJniObject QQmlAndroidTranslateAnimation::onCreate() { return QAndroidJniObject("android/view/animation/TranslateAnimation", "(IFIFIFIF)V", m_fromXType, m_fromX, m_toXType, m_toX, m_fromYType, m_fromY, m_toYType, m_toY); }
void QBluetoothSocketPrivate::inputThreadError(int errorCode) { Q_Q(QBluetoothSocket); if (errorCode != -1) { //magic error which is expected and can be ignored errorString = QBluetoothSocket::tr("Network error during read"); q->setSocketError(QBluetoothSocket::NetworkError); } //finally we can delete the InputStreamThread InputStreamThread *client = qobject_cast<InputStreamThread *>(sender()); if (client) client->deleteLater(); if (socketObject.isValid()) { //triggered when remote side closed the socket //cleanup internal objects //if it was call to local close()/abort() the objects are cleaned up already QAndroidJniEnvironment env; socketObject.callMethod<void>("close"); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); } inputStream = outputStream = remoteDevice = socketObject = QAndroidJniObject(); } q->setSocketState(QBluetoothSocket::UnconnectedState); q->setOpenMode(QIODevice::NotOpen); emit q->disconnected(); }
bool QBluetoothSocketPrivate::setSocketDescriptor(const QAndroidJniObject &socket, QBluetoothServiceInfo::Protocol socketType_, QBluetoothSocket::SocketState socketState, QBluetoothSocket::OpenMode openMode) { Q_Q(QBluetoothSocket); if (q->state() != QBluetoothSocket::UnconnectedState || !socket.isValid()) return false; if (!ensureNativeSocket(socketType_)) return false; socketObject = socket; QAndroidJniEnvironment env; inputStream = socketObject.callObjectMethod("getInputStream", "()Ljava/io/InputStream;"); outputStream = socketObject.callObjectMethod("getOutputStream", "()Ljava/io/OutputStream;"); if (env->ExceptionCheck() || !inputStream.isValid() || !outputStream.isValid()) { env->ExceptionDescribe(); env->ExceptionClear(); //close socket again socketObject.callMethod<void>("close"); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); } socketObject = inputStream = outputStream = remoteDevice = QAndroidJniObject(); errorString = QBluetoothSocket::tr("Obtaining streams for service failed"); q->setSocketError(QBluetoothSocket::NetworkError); q->setSocketState(QBluetoothSocket::UnconnectedState); return false; } remoteDevice = socketObject.callObjectMethod("getRemoteDevice", "()Landroid/bluetooth/BluetoothDevice;"); if (inputThread) { inputThread->deleteLater(); inputThread = 0; } inputThread = new InputStreamThread(this); QObject::connect(inputThread, SIGNAL(dataAvailable()), q, SIGNAL(readyRead()), Qt::QueuedConnection); QObject::connect(inputThread, SIGNAL(error(int)), this, SLOT(inputThreadError(int)), Qt::QueuedConnection); inputThread->run(); q->setSocketState(socketState); q->setOpenMode(openMode | QIODevice::Unbuffered); if (openMode == QBluetoothSocket::ConnectedState) emit q->connected(); return true; }
AndroidBroadcastReceiver::AndroidBroadcastReceiver(QObject* parent) : QObject(parent), valid(false) { //get QtActivity activityObject = QAndroidJniObject(QtAndroidPrivate::activity()); broadcastReceiverObject = QAndroidJniObject("org/qtproject/qt5/android/bluetooth/QtBluetoothBroadcastReceiver"); if (!broadcastReceiverObject.isValid()) return; broadcastReceiverObject.setField<jlong>("qtObject", reinterpret_cast<long>(this)); intentFilterObject = QAndroidJniObject("android/content/IntentFilter"); if (!intentFilterObject.isValid()) return; valid = true; }
AsemanAndroidLocationListenerCore::AsemanAndroidLocationListenerCore(QObject *parent) : AsemanAbstractLocationListenerCore(parent) { p = new AsemanAndroidLocationListenerPrivate; qRegisterMetaType<QGeoPositionInfo>("QGeoPositionInfo"); p->object = QAndroidJniObject("land/aseman/android/extra/AsemanLocationListener"); android_location_listener_objects.insert(p->object.object<jobject>(), this); }
AndroidScreenDevPrivate::AndroidScreenDevPrivate(AndroidScreenDev *self): self(self) { this->registerNatives(); this->m_callbacks = QAndroidJniObject(JCLASS(AkAndroidScreenCallbacks), "(J)V", this); }
bool LocalDeviceBroadcastReceiver::pairingConfirmation(bool accept) { if (!pairingDevice.isValid()) return false; bool success = pairingDevice.callMethod<jboolean>("setPairingConfirmation", "(Z)Z", accept); pairingDevice = QAndroidJniObject(); return success; }
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnCreate(JNIEnv* env, jobject obj, jobject instance, jobject asset_mgr) { g_assetManager = AAssetManager_fromJava(env, asset_mgr); qRegisterMetaType<QAndroidJniObject>("QAndroidJniObject"); __interfaceActivity = QAndroidJniObject(instance); auto oldMessageHandler = qInstallMessageHandler(tempMessageHandler); unpackAndroidAssets(); qInstallMessageHandler(oldMessageHandler); JavaVM* jvm; env->GetJavaVM(&jvm); QObject::connect(&AndroidHelper::instance(), &AndroidHelper::androidActivityRequested, [jvm](const QString& a, const bool backToScene, QMap<QString, QString> args) { JNIEnv* myNewEnv; JavaVMAttachArgs jvmArgs; jvmArgs.version = JNI_VERSION_1_6; // choose your JNI version jvmArgs.name = NULL; // you might want to give the java thread a name jvmArgs.group = NULL; // you might want to assign the java thread to a ThreadGroup int attachedHere = 0; // know if detaching at the end is necessary jint res = jvm->GetEnv((void**)&myNewEnv, JNI_VERSION_1_6); // checks if current env needs attaching or it is already attached if (JNI_OK != res) { qDebug() << "[JCRASH] GetEnv env not attached yet, attaching now.."; res = jvm->AttachCurrentThread(reinterpret_cast<JNIEnv **>(&myNewEnv), &jvmArgs); if (JNI_OK != res) { qDebug() << "[JCRASH] Failed to AttachCurrentThread, ErrorCode = " << res; return; } else { attachedHere = 1; } } QAndroidJniObject string = QAndroidJniObject::fromString(a); jboolean jBackToScene = (jboolean) backToScene; jclass hashMapClass = myNewEnv->FindClass("java/util/HashMap"); jmethodID mapClassConstructor = myNewEnv->GetMethodID(hashMapClass, "<init>", "()V"); jobject hashmap = myNewEnv->NewObject(hashMapClass, mapClassConstructor); jmethodID mapClassPut = myNewEnv->GetMethodID(hashMapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); QMap<QString, QString>::iterator i; for (i = args.begin(); i != args.end(); ++i) { QAndroidJniObject jKey = QAndroidJniObject::fromString(i.key()); QAndroidJniObject jValue = QAndroidJniObject::fromString(i.value()); myNewEnv->CallObjectMethod(hashmap, mapClassPut, jKey.object<jstring>(), jValue.object<jstring>()); } __interfaceActivity.callMethod<void>("openAndroidActivity", "(Ljava/lang/String;ZLjava/util/HashMap;)V", string.object<jstring>(), jBackToScene, hashmap); if (attachedHere) { jvm->DetachCurrentThread(); } }); QObject::connect(&AndroidHelper::instance(), &AndroidHelper::hapticFeedbackRequested, [](int duration) { jint iDuration = (jint) duration; __interfaceActivity.callMethod<void>("performHapticFeedback", "(I)V", iDuration); }); }
JNIEXPORT void JNICALL Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *env, jobject instance, jstring username_, jstring password_, jobject usernameChangedListener) { const char *c_username = env->GetStringUTFChars(username_, 0); const char *c_password = env->GetStringUTFChars(password_, 0); QString username = QString(c_username); QString password = QString(c_password); env->ReleaseStringUTFChars(username_, c_username); env->ReleaseStringUTFChars(password_, c_password); auto accountManager = DependencyManager::get<AccountManager>(); __loginCompletedListener = QAndroidJniObject(instance); __usernameChangedListener = QAndroidJniObject(usernameChangedListener); QObject::connect(accountManager.data(), &AccountManager::loginComplete, [](const QUrl& authURL) { jboolean jSuccess = (jboolean) true; if (__loginCompletedListener.isValid()) { __loginCompletedListener.callMethod<void>("handleLoginCompleted", "(Z)V", jSuccess); } }); QObject::connect(accountManager.data(), &AccountManager::loginFailed, []() { jboolean jSuccess = (jboolean) false; if (__loginCompletedListener.isValid()) { __loginCompletedListener.callMethod<void>("handleLoginCompleted", "(Z)V", jSuccess); } }); QObject::connect(accountManager.data(), &AccountManager::usernameChanged, [](const QString& username) { QAndroidJniObject string = QAndroidJniObject::fromString(username); if (__usernameChangedListener.isValid()) { __usernameChangedListener.callMethod<void>("handleUsernameChanged", "(Ljava/lang/String;)V", string.object<jstring>()); } }); QMetaObject::invokeMethod(accountManager.data(), "requestAccessToken", Q_ARG(const QString&, username), Q_ARG(const QString&, password)); }
void Gallery::loadExternalAlbumBrowser(const QObject * receiver, const char * method) { loadExternalAlbumFinishedReceiver = receiver; loadExternalAlbumFinishedMethod = method; #if defined(Q_OS_ANDROID) /* * Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "请选择"), PICK_FROM_FILE); */ QAndroidJniObject Intent__ACTION_GET_CONTENT = QAndroidJniObject::getStaticObjectField( "android/content/Intent", "ACTION_GET_CONTENT", "Ljava/lang/String;"); qDebug() << __FUNCTION__ << "Intent__ACTION_GET_CONTENT.isValid()=" << Intent__ACTION_GET_CONTENT.isValid(); QAndroidJniObject activity = QtAndroid::androidActivity(); qDebug() << __FUNCTION__ << "activity.isValid()=" << activity.isValid(); QAndroidJniObject intent=QAndroidJniObject("android/content/Intent","()V"); qDebug() << __FUNCTION__ << "intent.isValid()=" << intent.isValid(); QAndroidJniObject imageTypeStr = QAndroidJniObject::fromString(QString("image/*")); qDebug() << __FUNCTION__ << "imageTypeStr.isValid()=" << imageTypeStr.isValid(); intent.callObjectMethod("setType","(Ljava/lang/String;)Landroid/content/Intent;", imageTypeStr.object<jobject>()); intent.callObjectMethod("setAction","(Ljava/lang/String;)Landroid/content/Intent;", Intent__ACTION_GET_CONTENT.object<jobject>()); QAndroidJniObject chooseText = QAndroidJniObject::fromString(QString("Please pick on photo")); qDebug() << __FUNCTION__ << "chooseText.isValid()=" << chooseText.isValid(); QAndroidJniObject chooserIntent = QAndroidJniObject::callStaticObjectMethod( "android/content/Intent", "createChooser", "(Landroid/content/Intent;Ljava/lang/CharSequence;)Landroid/content/Intent;", intent.object<jobject>(), chooseText.object<jobject>()); qDebug() << __FUNCTION__ << "chooserIntent.isValid()=" << chooserIntent.isValid(); int PICK_FROM_FILE = 1; QtAndroid::startActivity(chooserIntent, PICK_FROM_FILE, this); #endif }
JNIEXPORT void JNICALL Java_io_highfidelity_hifiinterface_SplashActivity_registerLoadCompleteListener(JNIEnv *env, jobject instance) { __loadCompleteListener = QAndroidJniObject(instance); QObject::connect(&AndroidHelper::instance(), &AndroidHelper::qtAppLoadComplete, []() { __loadCompleteListener.callMethod<void>("onAppLoadedComplete", "()V"); __interfaceActivity.callMethod<void>("onAppLoadedComplete", "()V"); QObject::disconnect(&AndroidHelper::instance(), &AndroidHelper::qtAppLoadComplete, nullptr, nullptr); }); }
JNIEXPORT void JNICALL Java_io_highfidelity_oculus_OculusMobileActivity_questNativeOnCreate(JNIEnv *env, jobject obj) { __android_log_print(ANDROID_LOG_INFO, "QQQ", __FUNCTION__); initOculusPlatform(env, obj); getClassName(env, obj); __interfaceActivity = QAndroidJniObject(obj); QObject::connect(&AndroidHelper::instance(), &AndroidHelper::qtAppLoadComplete, []() { __interfaceActivity.callMethod<void>("onAppLoadedComplete", "()V"); QObject::disconnect(&AndroidHelper::instance(), &AndroidHelper::qtAppLoadComplete, nullptr, nullptr); }); }
void Wpp::downloadURL(const QString& url) { #ifdef Q_OS_ANDROID /* String serviceString = Context.DOWNLOAD_SERVICE; DownloadManager downloadManager; downloadManager = (DownloadManager)getSystemService(serviceString); Uri uri = Uri.parse("http://developer.android.com/shareables/icon_templates-v4.0.zip"); DownloadManager.Request request = new Request(uri); long reference = downloadManager.enqueue(request); */ QAndroidJniObject Context__DOWNLOAD_SERVICE = QAndroidJniObject::getStaticObjectField( "android/content/Context", "DOWNLOAD_SERVICE", "Ljava/lang/String;"); qDebug() << __FUNCTION__ << "Context__DOWNLOAD_SERVICE.isValid()=" << Context__DOWNLOAD_SERVICE.isValid(); QAndroidJniObject activity = QtAndroid::androidActivity(); qDebug() << __FUNCTION__ << "activity.isValid()=" << activity.isValid(); QAndroidJniObject downloadManager = activity.callObjectMethod( "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;", Context__DOWNLOAD_SERVICE.object<jstring>() ); qDebug() << __FUNCTION__ << "downloadManager.isValid()=" << downloadManager.isValid(); QAndroidJniObject urlJavaString = QAndroidJniObject::fromString(url); QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod( "android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", urlJavaString.object<jstring>() ); qDebug() << __FUNCTION__ << "uri.isValid()=" << uri.isValid(); QAndroidJniObject request = QAndroidJniObject( "android/app/DownloadManager$Request","(Landroid/net/Uri;)V", uri.object<jobject>() ); qDebug() << __FUNCTION__ << "request.isValid()=" << request.isValid(); jlong reference = downloadManager.callMethod<jlong>( "enqueue","(Landroid/app/DownloadManager$Request;)J", request.object<jobject>()); qDebug() << "reference=" << reference; #endif }
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(); } }
bool Wpp::dial(const QString& phone, bool direct) { #ifdef Q_OS_ANDROID /* * http://stackoverflow.com/questions/5230912/android-app-to-call-a-number-on-button-click Intent callIntent = new Intent(Intent.ACTION_CALL); callIntent.setData(Uri.parse("tel:"+txtPhn.getText().toString())); startActivity(callIntent); */ //发送号码到打电话那里 // Uri uri = Uri.parse("tel:XXXXXXX"); // Intent intent = new Intent(Intent.ACTION_DIAL,uri);//直接拨打:ACTION_CALL, 弹出窗口:ACTION_DIAL // // 或者Intent intent = new Intent("android.intent.action.DIAL"); // // Intent.ACTION_DIAL是内置常量,值为"android.intent.action.DIAL" // m_instance.startActivity(intent); QString uriQString("tel:"); uriQString.append( phone ); QAndroidJniObject uriString = QAndroidJniObject::fromString(uriQString); QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod( "android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", uriString.object<jstring>()); qDebug() << "uri.isValid()=" << uri.isValid(); QAndroidJniObject Intent__ACTION_DIAL = QAndroidJniObject::getStaticObjectField( "android/content/Intent", "ACTION_DIAL", "Ljava/lang/String;"); qDebug() << "Intent__ACTION_DIAL.isValid()=" << Intent__ACTION_DIAL.isValid(); QAndroidJniObject Intent__ACTION_CALL = QAndroidJniObject::getStaticObjectField( "android/content/Intent", "ACTION_CALL", "Ljava/lang/String;"); qDebug() << "Intent__ACTION_CALL.isValid()=" << Intent__ACTION_CALL.isValid(); QAndroidJniObject intent=QAndroidJniObject("android/content/Intent","(Ljava/lang/String;Landroid/net/Uri;)V", direct? Intent__ACTION_CALL.object<jstring>() : Intent__ACTION_DIAL.object<jstring>(), uri.object<jobject>()); qDebug() << __FUNCTION__ << "intent.isValid()=" << intent.isValid(); QtAndroid::startActivity(intent, 0, 0); #endif }
JNIEXPORT void JNICALL Java_io_highfidelity_hifiinterface_fragment_SignupFragment_nativeSignup(JNIEnv *env, jobject instance, jstring email_, jstring username_, jstring password_) { const char *c_email = env->GetStringUTFChars(email_, 0); const char *c_username = env->GetStringUTFChars(username_, 0); const char *c_password = env->GetStringUTFChars(password_, 0); QString email = QString(c_email); QString username = QString(c_username); QString password = QString(c_password); env->ReleaseStringUTFChars(email_, c_email); env->ReleaseStringUTFChars(username_, c_username); env->ReleaseStringUTFChars(password_, c_password); __signupCompletedListener = QAndroidJniObject(instance); // disconnect any previous callback QObject::disconnect(&AndroidHelper::instance(), &AndroidHelper::handleSignupCompleted, nullptr, nullptr); QObject::disconnect(&AndroidHelper::instance(), &AndroidHelper::handleSignupFailed, nullptr, nullptr); QObject::connect(&AndroidHelper::instance(), &AndroidHelper::handleSignupCompleted, []() { jboolean jSuccess = (jboolean) true; if (__signupCompletedListener.isValid()) { __signupCompletedListener.callMethod<void>("handleSignupCompleted", "()V", jSuccess); } }); QObject::connect(&AndroidHelper::instance(), &AndroidHelper::handleSignupFailed, [](QString errorString) { jboolean jSuccess = (jboolean) false; jstring jError = QAndroidJniObject::fromString(errorString).object<jstring>(); if (__signupCompletedListener.isValid()) { QAndroidJniObject string = QAndroidJniObject::fromString(errorString); __signupCompletedListener.callMethod<void>("handleSignupFailed", "(Ljava/lang/String;)V", string.object<jstring>()); } }); AndroidHelper::instance().signup(email, username, password); }
void QBluetoothSocketPrivate::abort() { if (state == QBluetoothSocket::UnconnectedState) return; if (socketObject.isValid()) { QAndroidJniEnvironment env; /* * BluetoothSocket.close() triggers an abort of the input stream * thread because inputStream.read() throws IOException * In turn the thread stops and throws an error which sets * new state, error and emits relevant signals. * See QBluetoothSocketPrivate::inputThreadError() for details */ if (inputThread) inputThread->prepareForClosure(); //triggers abort of input thread as well socketObject.callMethod<void>("close"); if (env->ExceptionCheck()) { qCWarning(QT_BT_ANDROID) << "Error during closure of socket"; env->ExceptionDescribe(); env->ExceptionClear(); } if (inputThread) { //don't delete here as signals caused by Java Thread are still //going to be emitted //delete occurs in inputThreadError() inputThread = 0; } inputStream = outputStream = socketObject = remoteDevice = QAndroidJniObject(); } }
QAndroidJniObject QQmlAndroidColorDrawable::onCreate() { return QAndroidJniObject("android/graphics/drawable/ColorDrawable"); }
JNIEXPORT void Java_io_highfidelity_gvrinterface_InterfaceActivity_handleHifiURL(JNIEnv *jni, jclass clazz, jstring hifiURLString) { launchURLString = QAndroidJniObject(hifiURLString).toString(); }
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; }
void QBluetoothSocketPrivate::connectToServiceConc(const QBluetoothAddress &address, const QBluetoothUuid &uuid, QIODevice::OpenMode openMode, int fallbackServiceChannel) { Q_Q(QBluetoothSocket); Q_UNUSED(openMode); qCDebug(QT_BT_ANDROID) << "connectToServiceConc()" << address.toString() << uuid.toString(); if (!adapter.isValid()) { qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth"; errorString = QBluetoothSocket::tr("Device does not support Bluetooth"); q->setSocketError(QBluetoothSocket::NetworkError); q->setSocketState(QBluetoothSocket::UnconnectedState); return; } const int state = adapter.callMethod<jint>("getState"); if (state != 12 ) { //BluetoothAdapter.STATE_ON qCWarning(QT_BT_ANDROID) << "Bt device offline"; errorString = QBluetoothSocket::tr("Device is powered off"); q->setSocketError(QBluetoothSocket::NetworkError); q->setSocketState(QBluetoothSocket::UnconnectedState); return; } QAndroidJniEnvironment env; QAndroidJniObject inputString = QAndroidJniObject::fromString(address.toString()); remoteDevice = adapter.callObjectMethod("getRemoteDevice", "(Ljava/lang/String;)Landroid/bluetooth/BluetoothDevice;", inputString.object<jstring>()); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); errorString = QBluetoothSocket::tr("Cannot access address %1", "%1 = Bt address e.g. 11:22:33:44:55:66").arg(address.toString()); q->setSocketError(QBluetoothSocket::HostNotFoundError); q->setSocketState(QBluetoothSocket::UnconnectedState); return; } //cut leading { and trailing } {xxx-xxx} QString tempUuid = uuid.toString(); tempUuid.chop(1); //remove trailing '}' tempUuid.remove(0, 1); //remove first '{' inputString = QAndroidJniObject::fromString(tempUuid); QAndroidJniObject uuidObject = QAndroidJniObject::callStaticObjectMethod("java/util/UUID", "fromString", "(Ljava/lang/String;)Ljava/util/UUID;", inputString.object<jstring>()); socketObject = remoteDevice.callObjectMethod("createRfcommSocketToServiceRecord", "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothSocket;", uuidObject.object<jobject>()); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); socketObject = remoteDevice = QAndroidJniObject(); errorString = QBluetoothSocket::tr("Cannot connect to %1 on %2", "%1 = uuid, %2 = Bt address").arg(uuid.toString()).arg(address.toString()); q->setSocketError(QBluetoothSocket::ServiceNotFoundError); q->setSocketState(QBluetoothSocket::UnconnectedState); return; } socketObject.callMethod<void>("connect"); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); bool success = fallBackConnect(uuidObject, fallbackServiceChannel); if (!success) { errorString = QBluetoothSocket::tr("Connection to service failed"); socketObject = remoteDevice = QAndroidJniObject(); q->setSocketError(QBluetoothSocket::ServiceNotFoundError); q->setSocketState(QBluetoothSocket::UnconnectedState); env->ExceptionClear(); //just in case return; } } if (inputThread) { inputThread->deleteLater(); inputThread = 0; } inputStream = socketObject.callObjectMethod("getInputStream", "()Ljava/io/InputStream;"); outputStream = socketObject.callObjectMethod("getOutputStream", "()Ljava/io/OutputStream;"); if (env->ExceptionCheck() || !inputStream.isValid() || !outputStream.isValid()) { env->ExceptionDescribe(); env->ExceptionClear(); //close socket again socketObject.callMethod<void>("close"); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); } socketObject = inputStream = outputStream = remoteDevice = QAndroidJniObject(); errorString = QBluetoothSocket::tr("Obtaining streams for service failed"); q->setSocketError(QBluetoothSocket::NetworkError); q->setSocketState(QBluetoothSocket::UnconnectedState); return; } inputThread = new InputStreamThread(this); QObject::connect(inputThread, SIGNAL(dataAvailable()), q, SIGNAL(readyRead()), Qt::QueuedConnection); QObject::connect(inputThread, SIGNAL(error(int)), this, SLOT(inputThreadError(int)), Qt::QueuedConnection); if (!inputThread->run()) { //close socket again socketObject.callMethod<void>("close"); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); } socketObject = inputStream = outputStream = remoteDevice = QAndroidJniObject(); delete inputThread; inputThread = 0; errorString = QBluetoothSocket::tr("Input stream thread cannot be started"); q->setSocketError(QBluetoothSocket::NetworkError); q->setSocketState(QBluetoothSocket::UnconnectedState); return; } // only unbuffered behavior supported at this stage q->setOpenMode(QIODevice::ReadWrite|QIODevice::Unbuffered); q->setSocketState(QBluetoothSocket::ConnectedState); emit q->connected(); }
QAndroidJniObject QQmlAndroidRadioButton::onCreate() { return QAndroidJniObject("android/widget/RadioButton", "(Landroid/content/Context;)V", ctx().object()); }
QAndroidJniObject QQmlAndroidViewFlipper::onCreate() { return QAndroidJniObject("android/widget/ViewFlipper", "(Landroid/content/Context;)V", ctx().object()); }
/* * This function operates on the assumption that each * field is of type java/lang/String. */ QAndroidJniObject valueForStaticField(JavaNames javaName, JavaNames javaFieldName) { //construct key //the switch statements are used to reduce the number of duplicated strings //in the library const char* className; switch (javaName) { case JavaNames::BluetoothAdapter: className = javaBluetoothAdapterClassName; break; case JavaNames::BluetoothDevice: className = javaBluetoothDeviceClassName; break; default: qCWarning(QT_BT_ANDROID) << "Unknown java class name passed to valueForStaticField():" << javaName; return QAndroidJniObject(); } const char *fieldName; switch (javaFieldName) { case JavaNames::ActionAclConnected: fieldName = javaActionAclConnected; break; case JavaNames::ActionAclDisconnected: fieldName = javaActionAclDisconnected; break; case JavaNames::ActionBondStateChanged: fieldName = javaActionBondStateChanged; break; case JavaNames::ActionDiscoveryStarted: fieldName = javaActionDiscoveryStarted; break; case JavaNames::ActionDiscoveryFinished: fieldName = javaActionDiscoveryFinished; break; case JavaNames::ActionFound: fieldName = javaActionFound; break; case JavaNames::ActionPairingRequest: fieldName = javaActionPairingRequest; break; case JavaNames::ActionScanModeChanged: fieldName = javaActionScanModeChanged; break; case JavaNames::ActionUuid: fieldName = javaActionUuid; break; case JavaNames::ExtraBondState: fieldName = javaExtraBondState; break; case JavaNames::ExtraDevice: fieldName = javaExtraDevice; break; case JavaNames::ExtraPairingKey: fieldName = javaExtraPairingKey; break; case JavaNames::ExtraPairingVariant: fieldName = javaExtraPairingVariant; break; case JavaNames::ExtraRssi: fieldName = javaExtraRssi; break; case JavaNames::ExtraScanMode: fieldName = javaExtraScanMode; break; case JavaNames::ExtraUuid: fieldName = javaExtraUuid; break; default: qCWarning(QT_BT_ANDROID) << "Unknown java field name passed to valueForStaticField():" << javaFieldName; return QAndroidJniObject(); } int offset_class = qstrlen(className); int offset_field = qstrlen(fieldName); QByteArray key(offset_class + offset_field, Qt::Uninitialized); memcpy(key.data(), className, offset_class); memcpy(key.data()+offset_class, fieldName, offset_field); JCachedStringFields::iterator it = cachedStringFields()->find(key); if (it == cachedStringFields()->end()) { QAndroidJniEnvironment env; QAndroidJniObject fieldValue = QAndroidJniObject::getStaticObjectField( className, fieldName, "Ljava/lang/String;"); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); cachedStringFields()->insert(key, QAndroidJniObject()); return QAndroidJniObject(); } cachedStringFields()->insert(key, fieldValue); return fieldValue; } else { return it.value(); } }
QAndroidJniObject QQmlAndroidContextual::ctx() const { if (!m_context) return QAndroidJniObject(); return m_context->instance(); }
bool QAndroidActivityResultReceiverPrivate::handleActivityResult(jint requestCode, jint resultCode, jobject data) { if (globalToLocalRequestCode.contains(requestCode)) { q->handleActivityResult(globalToLocalRequestCode.value(requestCode), resultCode, QAndroidJniObject(data)); return true; } return false; }