iOS 和 Android 中的照片库

Photo gallery in iOS and Android

我正在 iOSAndroid 中开发 运行 的移动应用程序,我在使用 [=] 访问设备的 image gallery 时遇到了一些困难19=].

我需要在 GridView 中列出图片库中的图片。

我曾尝试使用 QStandardPaths return 图片文件夹,但它仅适用于台式计算机。对于智能手机 运行ning iOSAndroid 它 return 是一个不是图库文件夹的文件夹。

有人可以帮我弄清楚我该怎么做吗?我的代码如下:

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

回答我自己的问题。

在iOS中只需在QML file中创建一个FileDialog并设置folder: shortcuts.pictures。它将调用 iOS 画廊。

在 Android 中,一旦需要集成 java 代码,就会变得更加困难。

我在 Qt 中使用 QAndroidJniObject 编写了等效的 java 代码。

caminhoimagens.h

#ifndef CAMINHOIMAGENS_H
#define CAMINHOIMAGENS_H

#include <QObject>

#include "imagepickerandroid.h"

#include <QDebug>

class caminhoImagens : public QObject
{
    Q_OBJECT

    Q_PROPERTY(QString imagemCaminho READ imagemCaminho NOTIFY imagemCaminhoChanged)

public slots:
    void buscaImagem();
    void retornaImagem(QString path);

public:
    caminhoImagens();

    QString imagemCaminho();

private:
    QString m_imagemCaminho = "";

signals:
    void imagemCaminhoChanged();
};

#endif //CAMINHOIMAGENS_H

caminhoimagens.cpp

#include "caminhoimagens.h"

caminhoImagens::caminhoImagens()
{

}

void caminhoImagens::buscaImagem()
{
    imagePickerAndroid *imagePicker = new imagePickerAndroid();
    connect(imagePicker, SIGNAL(imagemCaminhoSignal(QString)), this, SLOT(retornaImagem(QString)));

    imagePicker->buscaImagem();
}

void caminhoImagens::retornaImagem(QString path)
{
    qDebug() << path;

    m_imagemCaminho = path;

    emit imagemCaminhoChanged();
}

QString caminhoImagens::imagemCaminho()
{
    return m_imagemCaminho;
}

imagepickerandroid.h

#ifndef IMAGEPICKERANDROID_H
#define IMAGEPICKERANDROID_H


#include <QObject>
#include <QtAndroidExtras>

#include <QDebug>

class imagePickerAndroid : public QObject, public QAndroidActivityResultReceiver
{
    Q_OBJECT

public:
    imagePickerAndroid();

    void buscaImagem();

    virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject & data);

signals:
    void imagemCaminhoSignal(QString);
};

#endif // IMAGEPICKERANDROID_H

imagepickerandroid.cpp

#include "imagepickerandroid.h"

imagePickerAndroid::imagePickerAndroid()
{

}

void imagePickerAndroid::buscaImagem()
{
    QAndroidJniObject ACTION_PICK = QAndroidJniObject::fromString("android.intent.action.GET_CONTENT");
    QAndroidJniObject intent("android/content/Intent");
    if (ACTION_PICK.isValid() && intent.isValid())
    {
        intent.callObjectMethod("setAction", "(Ljava/lang/String;)Landroid/content/Intent;", ACTION_PICK.object<jstring>());
        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)
{
    qDebug() << "Trabalha com os dados";

    jint RESULT_OK = QAndroidJniObject::getStaticField<jint>("android/app/Activity", "RESULT_OK");
    if (receiverRequestCode == 101 && resultCode == RESULT_OK) {
        QString imagemCaminho = data.callObjectMethod("getData", "()Landroid/net/Uri;").callObjectMethod("getPath", "()Ljava/lang/String;").toString();
        emit imagemCaminhoSignal(imagemCaminho);

        qDebug() << imagemCaminho;
    }
    else
    {
        qDebug() << "Caminho errado";
    }
}