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;
}
Esempio n. 2
0
QList<QObject *> Gallery::fetchAll()
{

#ifdef Q_OS_ANDROID
	//ref(android): http://stackoverflow.com/questions/4195660/get-list-of-photo-galleries-on-android
	//ref(thumbnail): http://stackoverflow.com/questions/5013176/displaying-photo-thumbnails-on-map
	/*
		// which image properties are we querying
			String[] projection = new String[]{
					MediaStore.Images.Media._ID,
					MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
					MediaStore.Images.Media.DATE_TAKEN
			};
	 */
	QAndroidJniObject MediaStore_Images_Media__ID
			= QAndroidJniObject::getStaticObjectField(
			"android/provider/BaseColumns", "_ID", "Ljava/lang/String;");
	qDebug() << "MediaStore_Images_Media__ID.isValid()=" << MediaStore_Images_Media__ID.isValid();

	QAndroidJniObject MediaStore_Images_Media_BUCKET_ID
			= QAndroidJniObject::getStaticObjectField(
			"android/provider/MediaStore$Images$ImageColumns", "BUCKET_ID", "Ljava/lang/String;");
	qDebug() << "MediaStore_Images_Media_BUCKET_ID.isValid()=" << MediaStore_Images_Media_BUCKET_ID.isValid();

	QAndroidJniObject MediaStore_Images_Media_BUCKET_DISPLAY_NAME
			= QAndroidJniObject::getStaticObjectField(
			"android/provider/MediaStore$Images$ImageColumns", "BUCKET_DISPLAY_NAME", "Ljava/lang/String;");
	qDebug() << "MediaStore_Images_Media_BUCKET_DISPLAY_NAME.isValid()=" << MediaStore_Images_Media_BUCKET_DISPLAY_NAME.isValid();

	QAndroidJniObject MediaStore_Images_Media_DATE_TAKEN
			= QAndroidJniObject::getStaticObjectField(
			"android/provider/MediaStore$Images$ImageColumns", "DATE_TAKEN", "Ljava/lang/String;");
	qDebug() << "MediaStore_Images_Media_DATE_TAKEN.isValid()=" << MediaStore_Images_Media_DATE_TAKEN.isValid();

	QAndroidJniObject MediaStore_MediaColumns_DATA
			= QAndroidJniObject::getStaticObjectField(
			"android/provider/MediaStore$MediaColumns", "DATA", "Ljava/lang/String;");
	qDebug() << "MediaStore_MediaColumns_DATA.isValid()=" << MediaStore_MediaColumns_DATA.isValid();

	QAndroidJniObject MediaStore_MediaColumns_WIDTH
			= QAndroidJniObject::getStaticObjectField(
			"android/provider/MediaStore$MediaColumns", "WIDTH", "Ljava/lang/String;");
	qDebug() << "MediaStore_MediaColumns_WIDTH.isValid()=" << MediaStore_MediaColumns_WIDTH.isValid();

	QAndroidJniObject MediaStore_MediaColumns_HEIGHT
			= QAndroidJniObject::getStaticObjectField(
			"android/provider/MediaStore$MediaColumns", "HEIGHT", "Ljava/lang/String;");
	qDebug() << "MediaStore_MediaColumns_HEIGHT.isValid()=" << MediaStore_MediaColumns_HEIGHT.isValid();

	QAndroidJniObject MediaStore_Images_ImageColumns_MINI_THUMB_MAGIC
			= QAndroidJniObject::getStaticObjectField(
			"android/provider/MediaStore$Images$ImageColumns", "MINI_THUMB_MAGIC", "Ljava/lang/String;");
	qDebug() << "MediaStore_Images_ImageColumns_MINI_THUMB_MAGIC.isValid()=" << MediaStore_Images_ImageColumns_MINI_THUMB_MAGIC.isValid();

	jint MediaStore_Images_Thumbnails_MICRO_KIND = QAndroidJniObject::getStaticField<jint>(
				"android/provider/MediaStore$Images$Thumbnails", "MICRO_KIND");
	qDebug() << "MediaStore_Images_Thumbnails_MICRO_KIND=" << MediaStore_Images_Thumbnails_MICRO_KIND;

	QAndroidJniObject MediaStore_Images_Thumbnails_IMAGE_ID
			= QAndroidJniObject::getStaticObjectField(
			"android/provider/MediaStore$Images$Thumbnails", "IMAGE_ID", "Ljava/lang/String;");
	qDebug() << "MediaStore_Images_Thumbnails_IMAGE_ID.isValid()=" << MediaStore_Images_Thumbnails_IMAGE_ID.isValid();

	QAndroidJniObject MediaStore_Images_ImageColumns_ORIENTATION
			= QAndroidJniObject::getStaticObjectField(
			"android/provider/MediaStore$Images$ImageColumns", "ORIENTATION", "Ljava/lang/String;");
	qDebug() << "MediaStore_Images_ImageColumns_ORIENTATION.isValid()=" << MediaStore_Images_ImageColumns_ORIENTATION.isValid();


	QAndroidJniEnvironment env;
	jstring emptyJString = env->NewStringUTF("");

	jobjectArray projection = (jobjectArray)env->NewObjectArray(
		9,
		env->FindClass("java/lang/String"),
		emptyJString
	);
	jobject projection0 = env->NewStringUTF( MediaStore_Images_Media__ID.toString().toStdString().c_str() );
	env->SetObjectArrayElement(
		projection, 0, projection0 );
	jobject projection1 = env->NewStringUTF( MediaStore_Images_Media_BUCKET_ID.toString().toStdString().c_str() );
	env->SetObjectArrayElement(
		projection, 1, projection1 );
	jobject projection2 = env->NewStringUTF( MediaStore_Images_Media_BUCKET_DISPLAY_NAME.toString().toStdString().c_str() );
	env->SetObjectArrayElement(
		projection, 2, projection2 );
	jobject projection3 = env->NewStringUTF( MediaStore_Images_Media_DATE_TAKEN.toString().toStdString().c_str() );
	env->SetObjectArrayElement(
		projection, 3, projection3 );
	jobject projection4 = env->NewStringUTF( MediaStore_MediaColumns_DATA.toString().toStdString().c_str() );
	env->SetObjectArrayElement(
		projection, 4, projection4 );
	jobject projection5 = env->NewStringUTF( MediaStore_MediaColumns_WIDTH.toString().toStdString().c_str() );
	env->SetObjectArrayElement(
		projection, 5, projection5 );
	jobject projection6 = env->NewStringUTF( MediaStore_MediaColumns_HEIGHT.toString().toStdString().c_str() );
	env->SetObjectArrayElement(
		projection, 6, projection6 );
	jobject projection7 = env->NewStringUTF( MediaStore_Images_ImageColumns_MINI_THUMB_MAGIC.toString().toStdString().c_str() );
	env->SetObjectArrayElement(
		projection, 7, projection7 );
	jobject projection8 = env->NewStringUTF( MediaStore_Images_ImageColumns_ORIENTATION.toString().toStdString().c_str() );
	env->SetObjectArrayElement(
		projection, 8, projection8 );


	/*
	// Get the base URI for the People table in the Contacts content provider.
	Uri Images_EXTERNAL_CONTENT_URI = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
	 */
	QAndroidJniObject Images_EXTERNAL_CONTENT_URI
			= QAndroidJniObject::getStaticObjectField(
			"android/provider/MediaStore$Images$Media", "EXTERNAL_CONTENT_URI", "Landroid/net/Uri;");
	qDebug() << "Images_EXTERNAL_CONTENT_URI.isValid()=" << Images_EXTERNAL_CONTENT_URI.isValid();

	/*
	// Make the query.
		Cursor cur = managedQuery(Images_EXTERNAL_CONTENT_URI,
				projection, // Which columns to return
				"",         // Which rows to return (all rows)
				null,       // Selection arguments (none)
				""          // Ordering
				);
	*/
	QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
	qDebug() << "activity.isValid()=" << activity.isValid();

	QAndroidJniObject contentResolver = activity.callObjectMethod("getContentResolver","()Landroid/content/ContentResolver;");

	QAndroidJniObject emptyString=QAndroidJniObject::fromString(QString("")); //path is valid
	qDebug() << "emptyString.isValid()=" << emptyString.isValid();
	QAndroidJniObject nullObj;

	QAndroidJniObject cur = activity.callObjectMethod("managedQuery",
							"(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;",
							Images_EXTERNAL_CONTENT_URI.object<jobject>(), projection,
							emptyString.object<jstring>(), nullObj.object<jobject>(), emptyString.object<jstring>()
							);
	qDebug() << "cur.isValid()=" << cur.isValid();
	if (env->ExceptionCheck())
	{
		// Handle exception here.
		qDebug() << "Exception when getting \"cur\"....";
		env->ExceptionDescribe();
		env->ExceptionClear();
	}

	QMap<QString, wpp::qt::GalleryFolder> folderList;

	//if (cur.moveToFirst()) {
	if ( cur.callMethod<jboolean>("moveToFirst") )
	{
		/*
		int bucketColumn = cur.getColumnIndex(
			MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
		*/
		jint bucketColumn = cur.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", MediaStore_Images_Media_BUCKET_DISPLAY_NAME.object<jstring>());
		qDebug() << "bucketColumn = " << bucketColumn;
		/*
		 int dateColumn = cur.getColumnIndex(
			MediaStore.Images.Media.DATE_TAKEN);
		*/
		jint dateColumn = cur.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", MediaStore_Images_Media_DATE_TAKEN.object<jstring>());
		qDebug() << "dateColumn = " << dateColumn;


		jint idColumn = cur.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", MediaStore_Images_Media__ID.object<jstring>());
		qDebug() << "idColumn = " << idColumn;

		jint bucketIdColumn = cur.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", MediaStore_Images_Media_BUCKET_ID.object<jstring>());
		qDebug() << "bucketIdColumn = " << bucketIdColumn;

		jint mediaColumnsDataColumn = cur.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", MediaStore_MediaColumns_DATA.object<jstring>());
		qDebug() << "mediaColumnsDataColumn = " << mediaColumnsDataColumn;

		jint widthColumn = cur.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", MediaStore_MediaColumns_WIDTH.object<jstring>());
		qDebug() << "widthColumn = " << widthColumn;

		jint heightColumn = cur.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", MediaStore_MediaColumns_HEIGHT.object<jstring>());
		qDebug() << "heightColumn = " << heightColumn;

		jint thumbIdColumn = cur.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", MediaStore_Images_ImageColumns_MINI_THUMB_MAGIC.object<jstring>());
		qDebug() << "thumbIdColumn = " << thumbIdColumn;

		//jint imageIdColumn = cur.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", MediaStore_Images_Media__ID.object<jstring>());
		//qDebug() << "imageIdColumn = " << imageIdColumn;

		jint orientationColumn = cur.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", MediaStore_Images_ImageColumns_ORIENTATION.object<jstring>());
		qDebug() << "orientationColumn = " << orientationColumn;

		do
		{
			//QAndroidJniObject _id = cur.callObjectMethod("getString","(I)Ljava/lang/String;", idColumn );
			//qDebug() << "_id.isValid()=" << _id.isValid();
			jlong _id = cur.callMethod<jlong>("getLong","(I)J", idColumn );
			qDebug() << "_id=" << _id;

			QAndroidJniObject bucketId = cur.callObjectMethod("getString","(I)Ljava/lang/String;", bucketIdColumn );
			qDebug() << "bucketId.isValid()=" << bucketId.isValid();

			QAndroidJniObject bucket = cur.callObjectMethod("getString","(I)Ljava/lang/String;", bucketColumn );
			qDebug() << "bucket.isValid()=" << bucket.isValid();

			QAndroidJniObject date = cur.callObjectMethod("getString","(I)Ljava/lang/String;", dateColumn );
			qDebug() << "date.isValid()=" << date.isValid();

			QAndroidJniObject mediaColumnsData = cur.callObjectMethod("getString","(I)Ljava/lang/String;", mediaColumnsDataColumn );
			qDebug() << "mediaColumnsData.isValid()=" << mediaColumnsData.isValid();

			QAndroidJniObject width = cur.callObjectMethod("getString","(I)Ljava/lang/String;", widthColumn );
			qDebug() << "width.isValid()=" << width.isValid();

			QAndroidJniObject height = cur.callObjectMethod("getString","(I)Ljava/lang/String;", heightColumn );
			qDebug() << "height.isValid()=" << height.isValid();

			QAndroidJniObject thumbId = cur.callObjectMethod("getString","(I)Ljava/lang/String;", thumbIdColumn );
			qDebug() << "thumbId.isValid()=" << thumbId.isValid();

			//jlong thumbId = cur.callMethod<jlong>("getLong", "(I)J", thumbIdColumn);
			if (env->ExceptionCheck())
			{
				// Handle exception here.
				qDebug() << "Exception when getting \"thumbId\"....";
				env->ExceptionDescribe();
				env->ExceptionClear();
			}
			qDebug() << "thumbId=" << thumbId.toString();

			//QAndroidJniObject imageId = cur.callObjectMethod("getString","(I)Ljava/lang/String;", imageIdColumn );
			//qDebug() << "imageId.isValid()=" << imageId.isValid();



			// MediaStore.Images.Thumbnails.getThumbnail(getContentResolver(), imageID, MediaStore.Images.Thumbnails.MINI_KIND, null);
			/*QAndroidJniObject thumbnailBitmap = QAndroidJniObject::callStaticObjectMethod(
						"android/provider/MediaStore$Images$Thumbnails", "getThumbnail",
						"(Landroid/content/ContentResolver;JILandroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;",
						contentResolver.object<jobject>(), _id,
						MediaStore_Images_Thumbnails_MICRO_KIND,
						nullObj.object<jobject>()
						);
			qDebug() << "thumbnailBitmap.isValid()=" << thumbnailBitmap.isValid();
			*/

			//QAndroidJniObject orientation = cur.callObjectMethod("getString","(I)Ljava/lang/String;", orientationColumn );
			//qDebug() << "orientation.isValid()=" << orientation.isValid();
			jint orientation = cur.callMethod<jint>("getInt","(I)I", orientationColumn );
			qDebug() << "orientation=" << orientation;



			QAndroidJniObject thumbData = QAndroidJniObject::fromString( QString("") );
			if ( false ) //if ( thumbId > 0 )
			{
				//        String[] args =  new String[]{String.valueOf(thumbId)};
				jobjectArray args = (jobjectArray)env->NewObjectArray(
					1,
					env->FindClass("java/lang/String"),
					emptyJString
				);
				jstring thumbIdJString = env->NewStringUTF( thumbId.toString().toStdString().c_str() );
				env->SetObjectArrayElement(
					//args, 0, env->NewStringUTF( QString().sprintf("%ld",thumbId).toStdString().c_str() ) );
					args, 0, thumbIdJString );

				//        Cursor curThumb = managedQuery(Thumbnails.EXTERNAL_CONTENT_URI, null, Thumbnails._ID + "= ?", args, null);
				QAndroidJniObject Images_Thumbnails__ID
						= QAndroidJniObject::getStaticObjectField(
						"android/provider/BaseColumns", "_ID", "Ljava/lang/String;");
				qDebug() << "Images_Thumbnails__ID.isValid()=" << Images_Thumbnails__ID.isValid();
				QAndroidJniObject selection=QAndroidJniObject::fromString( Images_Thumbnails__ID.toString() + "= ?" ); //path is valid

				QAndroidJniObject curThumb = activity.callObjectMethod("managedQuery",
										"(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;",
										Images_EXTERNAL_CONTENT_URI.object<jobject>(), nullObj.object<jobject>(),
										selection.object<jstring>(), args, nullObj.object<jobject>()
										);
				qDebug() << "curThumb.isValid()=" << curThumb.isValid();

				//if( curThumb.moveToFirst() ){
				if ( curThumb.callMethod<jboolean>("moveToFirst") )
				{
					//            String path = curThumb.getString(curThumb.getColumnIndex(Thumbnails.DATA));
					QAndroidJniObject Images_Thumbnails_DATA
							= QAndroidJniObject::getStaticObjectField(
							"android/provider/MediaStore$Images$Thumbnails", "DATA", "Ljava/lang/String;");
					qDebug() << "Images_Thumbnails_DATA.isValid()=" << Images_Thumbnails_DATA.isValid();

					jint thumbDataColumn = curThumb.callMethod<jint>("getColumnIndex", "(Ljava/lang/String;)I", Images_Thumbnails_DATA.object<jstring>());
					qDebug() << "thumbDataColumn = " << thumbDataColumn;

					thumbData = cur.callObjectMethod("getString","(I)Ljava/lang/String;", thumbDataColumn );
					qDebug() << "thumbData.isValid()=" << thumbData.isValid();

				}
				env->DeleteLocalRef(args);
				env->DeleteLocalRef(thumbIdJString);
			}

			qDebug() << "_id=" << _id
					 << ", bucketId=" << bucketId.toString()
					 << ", bucket=" << bucket.toString()
					 << ", date_taken=" << date.toString()
					 << ", WxH=" << width.toString() << "x" << height.toString()
					 << ", orientation=" << orientation
					 << ", thumbId=" << thumbId.toString()
					 << ", thumbData=" << thumbData.toString()
					 << ", abs_path=" << mediaColumnsData.toString();

			if ( !folderList.contains( bucketId.toString() ) )
			{
				qDebug() << "create folder:" << bucketId.toString();
				GalleryFolder galleryFolder;
				galleryFolder.setId( bucketId.toString() );
				galleryFolder.setName( bucket.toString() );
				folderList.insert(bucketId.toString(), galleryFolder);
			}

			wpp::qt::GalleryPhoto photo;
			photo.setAbsolutePath( mediaColumnsData.toString() );
			photo.setWidth( width.toString().toInt() );
			photo.setHeight( height.toString().toInt() );
			photo.setOrientation( orientation );
			qDebug()<<"orientation===" << photo.getOrientation();
			folderList[ bucketId.toString() ].addPhoto( photo );
		}
		while ( cur.callMethod<jboolean>("moveToNext") );
		//while (cur.moveToNext());
	}

	env->DeleteLocalRef(emptyJString);
	env->DeleteLocalRef(projection);
	env->DeleteLocalRef(projection0);
	env->DeleteLocalRef(projection1);
	env->DeleteLocalRef(projection2);
	env->DeleteLocalRef(projection3);
	env->DeleteLocalRef(projection4);
	env->DeleteLocalRef(projection5);
	env->DeleteLocalRef(projection6);
	env->DeleteLocalRef(projection7);
	env->DeleteLocalRef(projection8);

	//change QMap to QList
	QList<QObject *> finalFolderList;
	for ( wpp::qt::GalleryFolder folder : folderList )
	{
		finalFolderList.push_back( new wpp::qt::GalleryFolder( folder ) );
	}
	this->setFolders( QVariant::fromValue( finalFolderList ) );

	for ( const QObject *obj : finalFolderList )
	{
		const wpp::qt::GalleryFolder *f = dynamic_cast< const wpp::qt::GalleryFolder * >( obj );
		qDebug() << "FOLDER" << f->getPhotos().value< QList<QObject*> >().size() << ":" << f->getName();
	}

	return finalFolderList;

#else
	return QList<QObject *>();
#endif
}
Esempio n. 3
0
/*
 * 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();
    }
}