Android, select image using Gallery
Dear all,
I'm trying to port existing application to Android, iOS and Windows platforms. The application needs the user to select an image and on my first trial I discovered that Qt for Android uses some sort of its own dialog. Is there is a way to use the standard Android image selector (Gallery app I guess) in Qt app? If not, can I somehow write a small piece of Android code, execute it from Qt and get the filename of selected image?
Thank you in advance
Re: Android, select image using Gallery
Hello,
The gallery doesn't return the filename of the selected image, it returns an URI. This URI is used for a content resolver to retrieve the image.
My solution is to launch the gallery from QT code and pass the result to the Android code to retrieve the image.
QT Code:
Code:
class AndroidImagePicker: public QAndroidActivityResultReceiver
{
public:
AndroidImagePicker() {}
void show() override {
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);
}
}
virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject & data) override {
jint RESULT_OK = QAndroidJniObject::getStaticField<jint>("android/app/Activity", "RESULT_OK");
if (receiverRequestCode == 101 && resultCode == RESULT_OK) {
QAndroidJniObject activity = QtAndroid::androidActivity();
QAndroidJniObject bytes = QAndroidJniObject::callStaticObjectMethod("lqsa/util/ImageFromActivityResult",
"getImage",
"(Landroid/content/Intent;Lorg/qtproject/qt5/android/bindings/QtActivity;)[B",
data.object<jobject>(), activity.object<jobject>());
QAndroidJniEnvironment env;
jbyteArray imageDataArray = bytes.object<jbyteArray>();
if (imageDataArray) {
jsize imageSize = env->GetArrayLength(imageDataArray);
if (imageSize > 0) {
jboolean isCopy;
jbyte *imageBytes = env->GetByteArrayElements(imageDataArray, &isCopy);
env->ReleaseByteArrayElements(imageDataArray, imageBytes, JNI_ABORT);
emit imageSelected(image);
}
}
}
}
};
Android code (file ImageFromActivityResult.java):
Code:
package lqsa.util;
import android.content.Intent;
import org.qtproject.qt5.android.bindings.QtActivity;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class ImageFromActivityResult {
public static byte[] getImage(Intent intent, QtActivity activity) throws IOException {
InputStream is = activity.getContentResolver().openInputStream(intent.getData());
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
return buffer.toByteArray();
}
}