Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Call for Presentations - Qt World Summit

    Solved Qt Java - Get image from gallery

    Mobile and Embedded
    qt programming java android
    3
    4
    3125
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • guidupas
      guidupas last edited by

      I am trying to get an image from Android gallery using Qt. I have already called the intent from Java using a Java file, but I don't know how to return it to Qt.

      I have a Qt class that calls a method from a Java file that opens the Android Image Picker. How can I return the selected image or the selected URI to Qt?

      the .h file

      #ifndef CAMINHOIMAGENS_H
      #define CAMINHOIMAGENS_H
      
      #include <QObject>
      
      #include <QDebug>
      
      class caminhoImagens : public QObject
      {
          Q_OBJECT
      
          Q_PROPERTY(QString imagemCaminho READ imagemCaminho NOTIFY imagemCaminhoChanged)
      
      slots:
          void atualizaImagem();
      
      public:
          QString imagemCaminho();
      
      private:
          QString m_imagemCaminho = "";
      
      signals:
          void imagemCaminhoChanged();
      };
      
      #endif // CAMINHOIMAGENS_H
      

      The .cpp file

      #include "caminhoimagens.h"
      
      #include <QtAndroidExtras>
      
      caminhoImagens::caminhoImagens()
      {
          
      }
      
      void caminhoImagens::atualizaImagem()
      {
          //org.qtproject.example.acessargaleriatest
          QAndroidJniObject intent = QAndroidJniObject::callStaticObjectMethod (
      "org/qtproject/example/AcessarGaleriaTest/ImagePickerAndroid",
       "imagePicker",
       "()Landroid/content/Intent;");
      
          QtAndroid::startActivity(intent, 192837465, 0);
      }
      
      QString caminhoImagens::imagemCaminho()
      {
          return m_imagemCaminho;
      }
      

      The .java file

      package org.qtproject.example.AcessarGaleriaTest;
      
      import org.qtproject.qt5.android.bindings.QtActivity;
      import android.content.Intent;
      import android.app.Activity;
      
      public class ImagePickerAndroid extends QtActivity
      {
          public static Intent imagePicker()
          {
              Intent i = new Intent(Intent.ACTION_PICK);
              i.setType( "image/*");
              return Intent.createChooser(i, "Select Image");
          }
      }
      

      Att.
      Guilherme Cortada Dupas

      1 Reply Last reply Reply Quote 0
      • V
        Vi67 last edited by

        Hello,

        In your ImagePickerAndroid you should override the onActivityResult function. With this you get the path name.

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data)
        {
            if (requestCode == "YourCode") {
                if (resultCode == RESULT_OK) {
                    String path;
        
                    Cursor cursor = getContentResolver().query(data.getData(), null, null, null, null);
                    if (cursor == null) { // Source is Dropbox or other similar local file path
                        path = data.getData().getPath();
                    } else {
                        cursor.moveToFirst();
                        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                        path = cursor.getString(idx);
                        cursor.close();
                    }
        
                    MyNative. notifyExtra(path);
                }
            }
            super.onActivityResult(requestCode, resultCode, data);
        }
        

        Then to send this path to Qt side, you need to create a native function like this :
        MyNative.java

        public class MyNative {
            public static native void notifyExtra(String path);
        }
        

        Then in Qt side :
        mynative.h

        #include <QtAndroidExtras/QAndroidJniObject>
        #include <QtAndroidExtras/QAndroidJniEnvironment>
        #include <QtAndroid>
        
        static void notifyExtra(JNIEnv *env, jobject thiz, jstring path) {
            Q_UNUSED(env)
            Q_UNUSED(thiz)
            // emit a signal to your listener
        }
        
        // call this function in your main.cpp
        void registerNativeMethods() {
            JNINativeMethod methods[] {
                {"notifyExtra", "(Ljava/lang/String;)V", reinterpret_cast<void *>(notifyExtra)}
            };
        
            QAndroidJniObject javaClass("path/to/your/MyNative");
            QAndroidJniEnvironment env;
            jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());
            env->RegisterNatives(objectClass, methods, sizeof(methods) / sizeof(methods[0]));
            env->DeleteLocalRef(objectClass);
        }
        
        1 Reply Last reply Reply Quote 0
        • benlau
          benlau Qt Champions 2016 last edited by

          An alternative way is to use existing library. e.g ImagePicker from QuickAndroid project.

          quickandroid/ImagePicker.qml at master · benlau/quickandroid
          quickandroid/ImagePicker.java at master · benlau/quickandroid

          1 Reply Last reply Reply Quote 0
          • guidupas
            guidupas last edited by

            Thanks for the help @Vi67

            I have done my code in Qt using QAndroidJniObject to write a equivalent java code.

            Register the caminhoimages.h as a QML type in the main.cpp and call the method buscaImagem()

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

            Att.
            Guilherme Cortada Dupas

            1 Reply Last reply Reply Quote 0
            • First post
              Last post