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 }
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; }
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 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(); } } }
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 }
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()); }