Photo gallery in iOS and Android



  • Hello!

    I am developing an app for mobile to run in iOS and Android and I am facing some difficulties to access the photo gallery of the devices with Qt and Qml.

    Could someone help me to figure out how I can do that?

    Thanks a lot.


  • Lifetime Qt Champion

    Hi,

    IIRC, QFileDialog handles that for iOS but I don't remember the state for Android



  • I am developing an app for mobile to run in iOS and Android and I am facing some difficulties to access the image gallery of the devices with Qml.

    I need to list the images from the image gallery in a GridView.

    I have tried to return the pictures folder using QStandardPaths but it just works for desktop computers. For smartphones running iOS and Android it returns a folder that is not the folder of the gallery.

    Could someone help me to figure out how I can do that? My code is below:

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    #include <QtQml>
    
    #include "caminhoimagens.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        qmlRegisterType<caminhoImagens>("PathImagens", 1, 0, "CaminhoImagens");
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    
        return app.exec();
    }
    

    main.qml

    import QtQuick 2.4
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.3
    import QtQuick.Dialogs 1.2
    
    import Qt.labs.folderlistmodel 2.1
    
    import PathImagens 1.0
    
    Window {
        visible: true
    
        width: 360
        height: 640
    
        maximumHeight: 640
        minimumHeight: 640
    
        maximumWidth: 360
        minimumWidth: 360
    
        title: "Acessar Galeria Test"
    
        Rectangle {
            id: principal
    
            anchors.fill: parent
    
            ListModel {
                id: listModel
            }
    
            FolderListModel {
                id: folderListModel
    
                folder: "file://" + caminhoImagens.retornaCaminhoImagens()
                nameFilters: "*.jpeg"
            }
    
            CaminhoImagens {
                id: caminhoImagens
            }
    
            Item {
                id: listaFotosDelegate
    
                property Component delegateComponent: listaFotosDelegateComponent
    
                Component {
                    id: listaFotosDelegateComponent
    
                    Image {
                        id: imagem
    
                        source: folderListModel.folder + "/" + fileName
    
                        width: principal.width / 4.2
                        height: principal.width / 4.2
    
                        fillMode: Image.PreserveAspectCrop
                    }
                }
            }
    
            GridView {
                id: listaFotosGridView
    
                anchors.fill: parent
    
                clip: true
    
                model: folderListModel
    
                delegate: listaFotosDelegate.delegateComponent
    
                cellWidth: parent.width / 4
                cellHeight: parent.width / 4
            }
        }
    }
    

    caminhoimagens.h

    #ifndef CAMINHOIMAGENS_H
    #define CAMINHOIMAGENS_H
    
    #include <QObject>
    #include <QStandardPaths>
    
    class caminhoImagens : public QObject
    {
        Q_OBJECT
    
    public slots:
        QString retornaCaminhoImagens();
    
    public:
        caminhoImagens();
    };
    
    #endif // CAMINHOIMAGENS_H
    

    caminhoimagens.cpp

    #include "caminhoimagens.h"
    
    caminhoImagens::caminhoImagens()
    {
    
    }
    
    QString caminhoImagens::retornaCaminhoImagens()
    {
        return QStandardPaths::locate(QStandardPaths::PicturesLocation, QString(), QStandardPaths::LocateDirectory);
    }


  • @guidupas You can checkout this post on how to access image gallery in Qt using JNI but I am not so sure how you can apply it to QML.



  • Thanks for the reply @amahta

    I am doing that with QAndroidJniObject to write a equivalent code with Qt

    My problem now is that I am trying to get the MediaStore columns using QAndroidJniObject because the path returned is a reference to a column position like this /document/image:30

    Do you know how can I get the columns of MediaStore using QAndroidJniObject?


  • Qt Champions 2016

    @guidupas

    If you mean to get the parameter of columns array to content resolver. You may try this code: (Didn't tested)

    QAndroidJniObject data = QAndroidJniObject::getStaticObjectField("android/provider/MediaStore$Images$Media","Data");
    

    btw, what you need to do it in JNI? I think it is just too troublesome.



  • @benlau I need to geed an image from gallery and sent it to QML
    Take a look at this post
    https://forum.qt.io/topic/61539/qt-and-android-gallery-mediastore-using-qandroidjniobject


  • Qt Champions 2016

    I mean why don't you just code in Java.

    Moreover, I think the signature should be "android/provider/MediaStore$Images$Media"



  • @benlau , I think it's easier to handle with the activity in Qt.
    Could you help me to solve the problem of the previous post link?



  • Solved

    Here is the code to get the full image path from android gallery using java equivalent code written with Qt:

    #include "imagepickerandroid.h"
    
    imagePickerAndroid::imagePickerAndroid()
    {
    
    }
    
    void imagePickerAndroid::buscaImagem()
    {
        QAndroidJniObject ACTION_PICK = QAndroidJniObject::getStaticObjectField("android/content/Intent", "ACTION_PICK", "Ljava/lang/String;");
        QAndroidJniObject EXTERNAL_CONTENT_URI = QAndroidJniObject::getStaticObjectField("android/provider/MediaStore$Images$Media", "EXTERNAL_CONTENT_URI", "Landroid/net/Uri;");
    
        QAndroidJniObject intent=QAndroidJniObject("android/content/Intent", "(Ljava/lang/String;Landroid/net/Uri;)V", ACTION_PICK.object<jstring>(), EXTERNAL_CONTENT_URI.object<jobject>());
    
        if (ACTION_PICK.isValid() && intent.isValid())
        {
            intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("image/*").object<jstring>());
            QtAndroid::startActivity(intent.object<jobject>(), 101, this);
            qDebug() << "OK";
        }
        else
        {
            qDebug() << "ERRO";
        }
    }
    
    void imagePickerAndroid::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data)
    {
        jint RESULT_OK = QAndroidJniObject::getStaticField<jint>("android/app/Activity", "RESULT_OK");
        if (receiverRequestCode == 101 && resultCode == RESULT_OK)
        {
            QAndroidJniObject uri = data.callObjectMethod("getData", "()Landroid/net/Uri;");
            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();
            emit imagemCaminhoSignal(imagemCaminho);
        }
        else
        {
            qDebug() << "Caminho errado";
        }
    }

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.