예제 #1
0
파일: Wpp.cpp 프로젝트: AndrewDesign/wpp-qt
void Wpp::addToImageGallery(const QString& imageFullPath)
{

#if defined(Q_OS_ANDROID)
	/*
	 http://stackoverflow.com/questions/2170214/image-saved-to-sdcard-doesnt-appear-in-androids-gallery-app
	File imageFile = ...
	MediaScannerConnection.scanFile(this, new String[] { imageFile.getPath() }, new String[] { "image/jpeg" }, null);
	 */

	QAndroidJniObject activity = QtAndroid::androidActivity();
	qDebug() << __FUNCTION__ << "activity.isValid()=" << activity.isValid();

	QAndroidJniEnvironment env;

	//new String[] { imageFile.getPath() }
	jobjectArray imageFilePaths = (jobjectArray)env->NewObjectArray(
		1,
		env->FindClass("java/lang/String"),
		(jobject)0
	);
	QAndroidJniObject imagePathJString = QAndroidJniObject::fromString(imageFullPath);
	env->SetObjectArrayElement(
		imageFilePaths, 0, imagePathJString.object<jstring>() );

	//new String[] { "image/jpeg", "image/png", "image/gif" }
	jobjectArray imageFileTypes = (jobjectArray)env->NewObjectArray(
		3,
		env->FindClass("java/lang/String"),
		(jobject)0
	);
	QAndroidJniObject imageType1 = QAndroidJniObject::fromString("image/jpeg");
	env->SetObjectArrayElement(
		imageFileTypes, 0, imageType1.object<jstring>() );
	QAndroidJniObject imageType2 = QAndroidJniObject::fromString("image/png");
	env->SetObjectArrayElement(
		imageFileTypes, 1, imageType2.object<jstring>() );
	QAndroidJniObject imageType3 = QAndroidJniObject::fromString("image/gif");
	env->SetObjectArrayElement(
		imageFileTypes, 2, imageType3.object<jstring>() );


	QAndroidJniObject::callStaticMethod<void>("android/media/MediaScannerConnection",
											  "scanFile",
											  "(Landroid/content/Context;[Ljava/lang/String;[Ljava/lang/String;Landroid/media/MediaScannerConnection$OnScanCompletedListener;)V",
											  activity.object<jobject>(),
											  imageFilePaths, imageFileTypes, (jobject)0);



	env->DeleteLocalRef(imageFilePaths);
	env->DeleteLocalRef(imageFileTypes);

#else

#endif


}
static jobject createHashMap(const QVariantMap &data) {
    QAndroidJniEnvironment env;

    jclass mapClass = env->FindClass("java/util/HashMap");

    if (mapClass == NULL)  {
        qWarning() << "Failed to find class" << "java/util/HashMap";
        return NULL;
    }

    jclass integerClass = env->FindClass("java/lang/Integer");

    jmethodID integerConstructor = env->GetMethodID(integerClass, "<init>", "(I)V");

    jclass booleanClass = env->FindClass("java/lang/Boolean");
    jmethodID booleanConstructor = env->GetMethodID(booleanClass,"<init>","(Z)V");


    jsize map_len = data.size();

    jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V");
    jobject hashMap = env->NewObject( mapClass, init, map_len);

    jmethodID put = env->GetMethodID( mapClass, "put",
                "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");


    QMapIterator<QString, QVariant> iter(data);
    while (iter.hasNext()) {
        iter.next();

//        qDebug() << iter.key() << iter.value();
        QString key = iter.key();
        jstring jkey = env->NewStringUTF(key.toLocal8Bit().data());
        QVariant v = iter.value();
        if (v.type() == QVariant::String) {
            QString str = v.toString();
            jstring vString = env->NewStringUTF(str.toLocal8Bit().data());
            env->CallObjectMethod(hashMap,put,jkey,vString);
        } else if (v.type() == QVariant::Int) {
            jobject integer = env->NewObject(integerClass,integerConstructor,v.toInt());
            env->CallObjectMethod(hashMap,put,jkey,integer);
        } else if (v.type() == QVariant::Bool) {
            jobject boolean = env->NewObject(booleanClass,booleanConstructor,v.toBool());
            env->CallObjectMethod(hashMap,put,jkey,boolean);
        } else {
            qWarning() << "QASystemDispatcher: Non-supported data type - " <<  v.type();
        }
     }

    if (env->ExceptionOccurred()) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }

    return hashMap;
}
void tst_QAndroidJniObject::callStaticBooleanMethod()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Boolean");
    QVERIFY(cls != 0);

    {
        QAndroidJniObject parameter = QAndroidJniObject::fromString("true");
        QVERIFY(parameter.isValid());

        jboolean b = QAndroidJniObject::callStaticMethod<jboolean>(cls,
                                                            "parseBoolean",
                                                            "(Ljava/lang/String;)Z",
                                                            parameter.object<jstring>());
        QVERIFY(b);
    }

    {
        QAndroidJniObject parameter = QAndroidJniObject::fromString("false");
        QVERIFY(parameter.isValid());

        jboolean b = QAndroidJniObject::callStaticMethod<jboolean>(cls,
                                                            "parseBoolean",
                                                            "(Ljava/lang/String;)Z",
                                                            parameter.object<jstring>());
        QVERIFY(!b);
    }
}
void QASystemDispatcher::registerNatives()
{
#ifdef Q_OS_ANDROID
    QAndroidJniEnvironment env;
    jclass clazz = env->FindClass(JCLASS_Name);
    if (!clazz)
    {
        qCritical() << QString("Can't find %1 class").arg(QString(JCLASS_Name));
        return ;
    }

    JNINativeMethod methods[] =
    {
        {"jniEmit", EMIT_SIGNATURE, (void *)&jniEmit},
    };

    int numMethods = sizeof(methods) / sizeof(methods[0]);
    if (env->RegisterNatives(clazz, methods, numMethods) < 0) {
        if (env->ExceptionOccurred()) {
            env->ExceptionDescribe();
            env->ExceptionClear();
            qCritical() << "Exception occurred!!!";
            return;
        }
    }
#endif
}
void tst_QAndroidJniObject::getStaticIntField()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Double");
    QVERIFY(cls != 0);

    jint i = QAndroidJniObject::getStaticField<jint>(cls, "SIZE");
    QCOMPARE(i, 64);
}
void tst_QAndroidJniObject::getStaticByteField()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Byte");
    QVERIFY(cls != 0);

    jbyte i = QAndroidJniObject::getStaticField<jbyte>(cls, "MAX_VALUE");
    QCOMPARE(i, jbyte(127));
}
void tst_QAndroidJniObject::getStaticLongField()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Long");
    QVERIFY(cls != 0);

    jlong i = QAndroidJniObject::getStaticField<jlong>(cls, "MAX_VALUE");
    QCOMPARE(i, jlong(9223372036854775807L));
}
void tst_QAndroidJniObject::getStaticShortField()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Short");
    QVERIFY(cls != 0);

    jshort i = QAndroidJniObject::getStaticField<jshort>(cls, "MAX_VALUE");
    QCOMPARE(i, jshort(32767));
}
void tst_QAndroidJniObject::getStaticCharField()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Character");
    QVERIFY(cls != 0);

    jchar i = QAndroidJniObject::getStaticField<jchar>(cls, "MAX_VALUE");
    QCOMPARE(i, jchar(0xffff));
}
void tst_QAndroidJniObject::getStaticDoubleField()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Double");
    QVERIFY(cls != 0);

    jdouble i = QAndroidJniObject::getStaticField<jdouble>(cls, "NaN");
    jlong *k = reinterpret_cast<jlong*>(&i);
    QCOMPARE(*k, jlong(0x7ff8000000000000L));
}
void tst_QAndroidJniObject::getStaticFloatField()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Float");
    QVERIFY(cls != 0);

    jfloat i = QAndroidJniObject::getStaticField<jfloat>(cls, "NaN");
    unsigned *k = reinterpret_cast<unsigned*>(&i);
    QCOMPARE(*k, unsigned(0x7fc00000));
}
void tst_QAndroidJniObject::callStaticCharMethod()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Character");
    QVERIFY(cls != 0);

    jchar returnValue = QAndroidJniObject::callStaticMethod<jchar>(cls,
                                                            "toUpperCase",
                                                            "(C)C",
                                                            jchar('a'));
    QCOMPARE(returnValue, jchar('A'));
}
void tst_QAndroidJniObject::ctor()
{
    {
        QAndroidJniObject object;
        QVERIFY(!object.isValid());
    }

    {
        QAndroidJniObject object("java/lang/String");
        QVERIFY(object.isValid());
    }

    {
        QAndroidJniObject string = QAndroidJniObject::fromString(QLatin1String("Hello, Java"));
        QAndroidJniObject object("java/lang/String", "(Ljava/lang/String;)V", string.object<jstring>());
        QVERIFY(object.isValid());
        QCOMPARE(string.toString(), object.toString());
    }

    {
        QAndroidJniEnvironment env;
        jclass javaStringClass = env->FindClass("java/lang/String");
        QAndroidJniObject string(javaStringClass);
        QVERIFY(string.isValid());
    }

    {
        QAndroidJniEnvironment env;
        const QString qString = QLatin1String("Hello, Java");
        jclass javaStringClass = env->FindClass("java/lang/String");
        QAndroidJniObject string = QAndroidJniObject::fromString(qString);
        QAndroidJniObject stringCpy(javaStringClass, "(Ljava/lang/String;)V", string.object<jstring>());
        QVERIFY(stringCpy.isValid());
        QCOMPARE(qString, stringCpy.toString());
    }
}
void tst_QAndroidJniObject::callStaticByteMethod()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Byte");
    QVERIFY(cls != 0);

    QString number = QString::number(123);
    QAndroidJniObject parameter = QAndroidJniObject::fromString(number);

    jbyte returnValue = QAndroidJniObject::callStaticMethod<jbyte>(cls,
                                                            "parseByte",
                                                            "(Ljava/lang/String;)B",
                                                            parameter.object<jstring>());
    QCOMPARE(returnValue, jbyte(number.toInt()));
}
void tst_QAndroidJniObject::callStaticLongMethod()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Long");
    QVERIFY(cls != 0);

    QString number = QString::number(123);
    QAndroidJniObject parameter = QAndroidJniObject::fromString(number);

    jlong returnValue = QAndroidJniObject::callStaticMethod<jlong>(cls,
                                                          "parseLong",
                                                          "(Ljava/lang/String;)J",
                                                          parameter.object<jstring>());
    QCOMPARE(returnValue, jlong(number.toLong()));
}
void tst_QAndroidJniObject::callStaticShortMethod()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Short");
    QVERIFY(cls != 0);

    QString number = QString::number(123);
    QAndroidJniObject parameter = QAndroidJniObject::fromString(number);

    jshort returnValue = QAndroidJniObject::callStaticMethod<jshort>(cls,
                                                          "parseShort",
                                                          "(Ljava/lang/String;)S",
                                                          parameter.object<jstring>());
    QCOMPARE(returnValue, number.toShort());
}
void tst_QAndroidJniObject::callStaticDoubleMethod()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Double");
    QVERIFY(cls != 0);

    QString number = QString::number(123.45);
    QAndroidJniObject parameter = QAndroidJniObject::fromString(number);

    jdouble returnValue = QAndroidJniObject::callStaticMethod<jdouble>(cls,
                                                          "parseDouble",
                                                          "(Ljava/lang/String;)D",
                                                          parameter.object<jstring>());
    QCOMPARE(returnValue, number.toDouble());
}
    QString getLocalPathFromUri(const QAndroidJniObject& uri) {
        // uri: Landroid/net/Uri;
        // [url](http://stackoverflow.com/questions/34163437/qt-and-android-gallery-mediastore-using-qandroidjniobject)

        QAndroidJniObject dadosAndroid
                = QAndroidJniObject::getStaticObjectField(
                    "android/provider/MediaStore$MediaColumns",
                    "DATA",
                    "Ljava/lang/String;");

        QAndroidJniEnvironment env;
        jobjectArray projecao
                = (jobjectArray)env->NewObjectArray(1,
                                                    env->FindClass("java/lang/String"),
                                                    NULL);

        jobject projacaoDadosAndroid
                = env->NewStringUTF(dadosAndroid.toString().toStdString().c_str());

        env->SetObjectArrayElement(projecao, 0, projacaoDadosAndroid);

        QAndroidJniObject contentResolver
                = QtAndroid::androidActivity()
                .callObjectMethod("getContentResolver",
                                  "()Landroid/content/ContentResolver;");

        QAndroidJniObject cursor
                = contentResolver.callObjectMethod("query",
                                                   "(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;",
                                                   uri.object<jobject>(), projecao, NULL, NULL, NULL);

        jint columnIndex = cursor.callMethod<jint>("getColumnIndex",
                                                   "(Ljava/lang/String;)I",
                                                   dadosAndroid.object<jstring>());

        cursor.callMethod<jboolean>("moveToFirst", "()Z");

        QAndroidJniObject resultado
                = cursor.callObjectMethod("getString",
                                          "(I)Ljava/lang/String;",
                                          columnIndex);

        QString imagemCaminho = "file://" + resultado.toString();

        return imagemCaminho;
    }
void tst_QAndroidJniObject::callStaticObjectMethod()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/String");
    QVERIFY(cls != 0);

    QAndroidJniObject formatString = QAndroidJniObject::fromString(QLatin1String("test format"));
    QVERIFY(formatString.isValid());

    QAndroidJniObject returnValue = QAndroidJniObject::callStaticObjectMethod(cls,
                                                                "format",
                                                                "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;",
                                                                formatString.object<jstring>(),
                                                                jobjectArray(0));
    QVERIFY(returnValue.isValid());

    QString returnedString = returnValue.toString();

    QCOMPARE(returnedString, QString::fromLatin1("test format"));
}
void QSerialPortPrivate::setNativeMethods(void)
{
    qCDebug(AndroidSerialPortLog) << "Registering Native Functions";

    //  REGISTER THE C++ FUNCTION WITH JNI
    JNINativeMethod javaMethods[] {
        {"nativeDeviceHasDisconnected", "(I)V",                     reinterpret_cast<void *>(jniDeviceHasDisconnected)},
        {"nativeDeviceNewData",         "(I[B)V",                   reinterpret_cast<void *>(jniDeviceNewData)},
        {"nativeDeviceException",       "(ILjava/lang/String;)V",   reinterpret_cast<void *>(jniDeviceException)},
        {"qgcLogDebug",                 "(Ljava/lang/String;)V",    reinterpret_cast<void *>(jniLogDebug)},
        {"qgcLogWarning",               "(Ljava/lang/String;)V",    reinterpret_cast<void *>(jniLogWarning)}
    };

    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(AndroidSerialPortLog) << "Native Functions Registered";
    }

    if (jniEnv->ExceptionCheck()) {
        jniEnv->ExceptionDescribe();
        jniEnv->ExceptionClear();
    }
}
void tst_QAndroidJniObject::getStaticObjectField()
{
    QAndroidJniEnvironment env;
    jclass cls = env->FindClass("java/lang/Boolean");
    QVERIFY(cls != 0);

    {
        QAndroidJniObject boolObject = QAndroidJniObject::getStaticObjectField<jobject>(cls,
                                                                          "FALSE",
                                                                          "Ljava/lang/Boolean;");
        QVERIFY(boolObject.isValid());

        jboolean booleanValue = boolObject.callMethod<jboolean>("booleanValue");
        QVERIFY(!booleanValue);
    }

    {
        QAndroidJniObject boolObject = QAndroidJniObject::getStaticObjectField<jobject>(cls,
                                                                 "TRUE",
                                                                 "Ljava/lang/Boolean;");
        QVERIFY(boolObject.isValid());

        jboolean booleanValue = boolObject.callMethod<jboolean>("booleanValue");
        QVERIFY(booleanValue);
    }

    {
        QAndroidJniObject boolObject = QAndroidJniObject::getStaticObjectField(cls,
                                                                               "FALSE",
                                                                               "Ljava/lang/Boolean;");
        QVERIFY(boolObject.isValid());

        jboolean booleanValue = boolObject.callMethod<jboolean>("booleanValue");
        QVERIFY(!booleanValue);
    }
}
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;
}
예제 #23
0
void Gallery::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject & data)
{
	int PICK_FROM_FILE = 1;
	int SHOOT_PHOTO = 2;
	jint Activity__RESULT_OK = QAndroidJniObject::getStaticField<jint>(
				"android.app.Activity", "RESULT_OK");

	if ( receiverRequestCode == PICK_FROM_FILE && resultCode == Activity__RESULT_OK )
	{
		QAndroidJniEnvironment env;
		QAndroidJniObject uri = data.callObjectMethod("getData","()Landroid/net/Uri;");
		qDebug() << __FUNCTION__ << "uri.isValid()=" << uri.isValid();
		qDebug() << __FUNCTION__ << "uri=" << uri.toString();
		/*
		  url is like: "content://media/external/images/media/87332"
		 */
		QAndroidJniObject activity = QtAndroid::androidActivity();
		qDebug() << __FUNCTION__ << "activity.isValid()=" << activity.isValid();

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

/*
String [] proj={MediaStore.Images.Media.DATA};
	Cursor cursor = getContentResolver().query(uri, proj,  null, null, null);
	int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
	cursor.moveToFirst();
	String path = cursor.getString(column_index);
	cursor.close();
 */
		QAndroidJniObject MediaStore_Images_Media_DATA
				= QAndroidJniObject::getStaticObjectField(
				"android/provider/MediaStore$MediaColumns", "DATA", "Ljava/lang/String;");
		qDebug() << "MediaStore_Images_Media_DATA.isValid()=" << MediaStore_Images_Media_DATA.isValid();

		QAndroidJniObject nullObj;
		jstring emptyJString = env->NewStringUTF("");
		jobjectArray projection = (jobjectArray)env->NewObjectArray(
			1,
			env->FindClass("java/lang/String"),
			emptyJString
		);
		jobject projection0 = env->NewStringUTF( MediaStore_Images_Media_DATA.toString().toStdString().c_str() );
		env->SetObjectArrayElement(
			projection, 0, projection0 );

		//	Cursor cursor = getContentResolver().query(uri, proj,  null, null, null);
		QAndroidJniObject cursor = contentResolver.callObjectMethod("query",
			"(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;",
			uri.object<jobject>(), projection, nullObj.object<jstring>(), nullObj.object<jobjectArray>(), nullObj.object<jstring>());
		qDebug() << __FUNCTION__ << "cursor.isValid()=" << cursor.isValid();

		//int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		jint column_index = cursor.callMethod<jint>(
					"getColumnIndexOrThrow","(Ljava/lang/String;)I", MediaStore_Images_Media_DATA.object<jstring>());
		qDebug() << "column_index=" << column_index;

		//cursor.moveToFirst();
		cursor.callMethod<jboolean>("moveToFirst");

		//	String path = cursor.getString(column_index);
		QAndroidJniObject path = cursor.callObjectMethod(
					"getString",
					"(I)Ljava/lang/String;", column_index );
		qDebug() << __FUNCTION__ << "path.isValid()=" << path.isValid();
		QString filePath = path.toString();

		//cursor.close();
		cursor.callMethod<jboolean>("close");


		env->DeleteLocalRef(emptyJString);
		env->DeleteLocalRef(projection);
		env->DeleteLocalRef(projection0);
/*
		QAndroidJniObject inputStream = contentResolver.callObjectMethod(
					"openInputStream","(Landroid/net/Uri;)Ljava/io/InputStream;", uri.object<jobject>());
		qDebug() << __FUNCTION__ << "inputStream.isValid()=" << inputStream.isValid();

		QStringList paths = QStandardPaths::standardLocations(QStandardPaths::DataLocation);
		QDir dir( paths.first() );
		QDir parentDir( dir.filePath("..") );
		qDebug() << "parent path: " << parentDir.absolutePath();
		if ( !dir.exists() )
		{
			qDebug() << "dir not exist, make it:" << dir;
			qDebug() << "dir.name: " << dir.dirName();
			qDebug() << "new make dir returns: " << parentDir.mkpath( dir.dirName() );
			//qDebug() << "make dir returns: " << dir.mkdir(".");
		}
		QString pickFile = paths.first().append("/").append("PickFile");

		QAndroidJniEnvironment env;
		jbyteArray byteArray = env->NewByteArray(1024);

		jint fileSize = inputStream.callMethod<jint>(
					"available","()I");
		qDebug() << "fileSize=" << fileSize;

		QFile file( pickFile );
		file.open(QIODevice::WriteOnly);
		jint bytesRead = 0;
		do
		{
			bytesRead = inputStream.callMethod<jint>(
						"read","([B)I", byteArray);
			qDebug() << "bytes read:" << bytesRead;
			if ( bytesRead > 0 )
			{
				jboolean isCopy;
				jbyte* a = env->GetByteArrayElements(byteArray,&isCopy);
				file.write((char *)a, bytesRead);
				env->ReleaseByteArrayElements(byteArray, a, 0);
			}
		}
		while ( bytesRead > 0 );
		file.close();

		qDebug() << "output file size:" << file.size();
*/

		//env->Delete

		//QAndroidJniObject absPath = uri.callObjectMethod("getPath","()Ljava/lang/String;");
		//qDebug() << __FUNCTION__ << "absPath.isValid()=" << absPath.isValid();
		//qDebug() << __FUNCTION__ << "absPath=" << absPath.toString();

		connect(this, SIGNAL(finishedPickPhoto(const QString&)), loadExternalAlbumFinishedReceiver, loadExternalAlbumFinishedMethod.toStdString().c_str());
		emit this->finishedPickPhoto(filePath);
		disconnect(this, SIGNAL(finishedPickPhoto(const QString&)), loadExternalAlbumFinishedReceiver, loadExternalAlbumFinishedMethod.toStdString().c_str());
	}
예제 #24
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
}
예제 #25
0
void ImagePicker::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject & data)
{
	qDebug() << __FUNCTION__;
	int PICK_FROM_FILE = 2;
	int PICK_FROM_FILE_KITKAT = 3;
	jint Activity__RESULT_OK = QAndroidJniObject::getStaticField<jint>(
				"android/app/Activity", "RESULT_OK");
	qDebug() << __FUNCTION__ <<":receiverRequestCode=" << receiverRequestCode
								<< ",resultCode=" << resultCode
								<< ",Activity__RESULT_OK=" << Activity__RESULT_OK;

	if ( ( receiverRequestCode == PICK_FROM_FILE || receiverRequestCode == PICK_FROM_FILE_KITKAT
		   || receiverRequestCode == 200
		   || receiverRequestCode == 9000 )
		 && resultCode == Activity__RESULT_OK )
	{
		if ( receiverRequestCode == 200 )
		{
			QAndroidJniEnvironment env;

			QAndroidJniObject pathsJavaObj = data.callObjectMethod("getStringArrayExtra","(Ljava/lang/String;)[Ljava/lang/String;");
			qDebug() << __FUNCTION__ << "pathsJavaObj.isValid()=" << pathsJavaObj.isValid();

			jobjectArray pathArray = pathsJavaObj.object<jobjectArray>();
			int stringCount = env->GetArrayLength(pathArray);

			QStringList paths;
			for (int i=0; i<stringCount; i++)
			{
				jstring string = (jstring) env->GetObjectArrayElement(pathArray, i);
				const char *rawString = env->GetStringUTFChars(string, 0);
				// Don't forget to call `ReleaseStringUTFChars` when you're done.

				QString path(rawString);
				qDebug() << "path[]=" << path;
				paths.append(path);

				env->ReleaseStringUTFChars(string, rawString);
			}
			emit this->accepted(paths);

		}
		else if ( receiverRequestCode == 9000 )//PhotoPicker
		{
			qDebug() << __FUNCTION__ << ":code=9000";
			QAndroidJniEnvironment env;

			QAndroidJniObject PhotoPickerActivity__KEY_SELECTED_PHOTOS
					= QAndroidJniObject::getStaticObjectField(
						"me/iwf/photopicker/PhotoPickerActivity", "KEY_SELECTED_PHOTOS", "Ljava/lang/String;");
			qDebug() << "PhotoPickerActivity__KEY_SELECTED_PHOTOS.isValid()=" << PhotoPickerActivity__KEY_SELECTED_PHOTOS.isValid();

			QAndroidJniObject photos = data.callObjectMethod("getStringArrayListExtra","(Ljava/lang/String;)Ljava/util/ArrayList;",
														  PhotoPickerActivity__KEY_SELECTED_PHOTOS.object<jstring>());
			qDebug() << "photos.isValid()=" << photos.isValid();

			QAndroidJniObject photosObjectArray = photos.callObjectMethod("toArray","()[Ljava/lang/Object;");
			qDebug() << "photosObjectArray.isValid()=" << photosObjectArray.isValid();

			jobjectArray pathArray = photosObjectArray.object<jobjectArray>();
			int stringCount = env->GetArrayLength(pathArray);
			qDebug() << "pathArray=" << (void*)pathArray;
			qDebug() << "stringCount=" << stringCount;

			QStringList paths;
			for (int i=0; i<stringCount; i++)
			{
				qDebug() << "for pathArray...i=" << i;
				jstring string = (jstring) env->GetObjectArrayElement(pathArray, i);
				const char *rawString = env->GetStringUTFChars(string, 0);
				// Don't forget to call `ReleaseStringUTFChars` when you're done.
				qDebug() << "for pathArray...i=" << i << ":rawString=" << rawString;

				QString path(rawString);
				qDebug() << "path[]=" << path;
				paths.append(path);

				env->ReleaseStringUTFChars(string, rawString);
			}
			emit this->accepted(paths);

		}
		else
		{
			QAndroidJniEnvironment env;
			QAndroidJniObject uri = data.callObjectMethod("getData","()Landroid/net/Uri;");
			qDebug() << __FUNCTION__ << "uri.isValid()=" << uri.isValid();
			qDebug() << __FUNCTION__ << "uri=" << uri.toString();
			/*
			  url is like: "content://media/external/images/media/87332"
			  for KitKat(android 4.4), uri is like: "content://com.android.providers.media.documents/document/image:3951"
			 */
			QAndroidJniObject activity = QtAndroid::androidActivity();
			qDebug() << __FUNCTION__ << "activity.isValid()=" << activity.isValid();

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

			/*if ( receiverRequestCode == PICK_FROM_FILE_KITKAT )
			{
				jint Intent__FLAG_GRANT_READ_URI_PERMISSION = QAndroidJniObject::getStaticField<jint>(
							"android.content.Intent", "FLAG_GRANT_READ_URI_PERMISSION");
				jint Intent__FLAG_GRANT_WRITE_URI_PERMISSION = QAndroidJniObject::getStaticField<jint>(
							"android.content.Intent", "FLAG_GRANT_WRITE_URI_PERMISSION");
				jint takeFlags = data.callMethod<jint>("getFlags","()I");
				takeFlags = takeFlags & ( Intent__FLAG_GRANT_READ_URI_PERMISSION | Intent__FLAG_GRANT_WRITE_URI_PERMISSION );

				contentResolver.callMethod<void>("takePersistableUriPermission","(Landroid/net/Uri;I)V",
																  uri.object<jobject>(), takeFlags);
			}*/
	/*
	String [] proj={MediaStore.Images.Media.DATA};
		Cursor cursor = getContentResolver().query(uri, proj,  null, null, null);
		int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		cursor.moveToFirst();
		String path = cursor.getString(column_index);
		cursor.close();
	 */
			QAndroidJniObject MediaStore_Images_Media_DATA
					= QAndroidJniObject::getStaticObjectField(
						"android/provider/MediaStore$MediaColumns", "DATA", "Ljava/lang/String;");
						//"android/provider/MediaStore$Images$Media", "DATA", "Ljava/lang/String;");
			qDebug() << "MediaStore_Images_Media_DATA.isValid()=" << MediaStore_Images_Media_DATA.isValid();

			QAndroidJniObject nullObj;
			jstring emptyJString = env->NewStringUTF("");
			jobjectArray projection = (jobjectArray)env->NewObjectArray(
				1,
				env->FindClass("java/lang/String"),
				emptyJString
			);
			jobject projection0 = env->NewStringUTF( MediaStore_Images_Media_DATA.toString().toStdString().c_str() );
			env->SetObjectArrayElement(
				projection, 0, projection0 );

			//	Cursor cursor = getContentResolver().query(uri, proj,  null, null, null);
			QAndroidJniObject cursor = contentResolver.callObjectMethod("query",
				"(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;",
				uri.object<jobject>(), projection, nullObj.object<jstring>(), nullObj.object<jobjectArray>(), nullObj.object<jstring>());
			qDebug() << __FUNCTION__ << "cursor.isValid()=" << cursor.isValid();

			//int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			jint column_index = cursor.callMethod<jint>(
						"getColumnIndexOrThrow","(Ljava/lang/String;)I", MediaStore_Images_Media_DATA.object<jstring>());
			qDebug() << "column_index=" << column_index;

			//cursor.moveToFirst();
			cursor.callMethod<jboolean>("moveToFirst");

			//	String path = cursor.getString(column_index);
			QAndroidJniObject path = cursor.callObjectMethod(
						"getString",
						"(I)Ljava/lang/String;", column_index );
			qDebug() << __FUNCTION__ << "path.isValid()=" << path.isValid();
			QString filePath = path.toString();
			qDebug() << "filePath=" << filePath;
			//cursor.close();
			cursor.callMethod<jboolean>("close");


			env->DeleteLocalRef(emptyJString);
			env->DeleteLocalRef(projection);
			env->DeleteLocalRef(projection0);

			QStringList paths;
			paths.append(filePath);
			emit this->accepted(paths);
			//m_imagePath = filePath;
			//emit this->imagePathChanged();
		}
	}
}
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;
}