Android — начать внешнюю деятельность для сканирования штрих-кода

Я хочу запустить сканер штрих-кода из моего приложения и получить тег

Вот что у меня так далеко:

scan.h

class DecodeBarCode : public QObject
{
Q_OBJECT

BarCodeReceiver *m_receiver;

public:
explicit DecodeBarCode(QObject *parent = 0);
~DecodeBarCode();

Q_INVOKABLE void useZXingApp();

signals:
void tagFound(QString tag);
};

class BarCodeReceiver : public QAndroidActivityResultReceiver
{
DecodeBarCode *m_decoder;
public:
BarCodeReceiver(DecodeBarCode *decoder) : m_decoder(decoder) {}

virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data) {
emit m_decoder->tagFound("Receiver worked");
}

};

scan.cpp

DecodeBarCode::DecodeBarCode(QObject *parent) : QObject(parent)
{
m_receiver = new BarCodeReceiver(this);
}

DecodeBarCode::~DecodeBarCode()
{
delete m_receiver;
}

void DecodeBarCode::useZXingApp()
{
QAndroidJniObject intent = QAndroidJniObject::fromString("com/google/zxing/client/android/SCAN");
if (intent.isValid()) {
QtAndroid::startActivity(intent,0,m_receiver); // CRASH HERE
} else {
emit tagFound("Invalid"); // TEMP
}
}

Это первый раз, когда я использую JNI, никогда не использовал его ни в Java, ни в C ++ / Qt

Там должно быть что-то очень неправильно, что это?

0

Решение

Это мой пример использования намерения поделиться текстом из приложения:

void Sharer::share(const QString &content)
{
qDebug() << "sharing text: " << content;
#ifdef Q_OS_ANDROID
auto ACTION_SEND = QAndroidJniObject::getStaticObjectField("android/content/Intent", "ACTION_SEND", "Ljava/lang/String;");
auto EXTRA_TEXT = QAndroidJniObject::getStaticObjectField("android/content/Intent", "EXTRA_TEXT", "Ljava/lang/String;");
auto intent = QAndroidJniObject("android/content/Intent", "(Ljava/lang/String;)V", ACTION_SEND.object());

// Intent  Intent.putExtra(String name, String value)
intent.callObjectMethod("putExtra", "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;", EXTRA_TEXT.object(), QAndroidJniObject::fromString(content).object());

// Intent  Intent.setType(String type)
intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString(QString("text/plain")).object());
qDebug() << intent.toString();

// static Intent Intent.createChooser(Intent target, CharSequence title)
auto chooserIntent = QAndroidJniObject::callStaticObjectMethod("android/content/Intent", "createChooser", "(Landroid/content/Intent;Ljava/lang/CharSequence;)Landroid/content/Intent;", intent.object(), QAndroidJniObject::fromString(QString("It's Time To Choose...")).object());
qDebug() << chooserIntent.toString();

QtAndroid::startActivity(chooserIntent, 0, nullptr);

#endif
}

Как видите, вам нужно создать намерение самостоятельно, извлекая все необходимые объекты.

1

Другие решения

Я наконец получил его на работу, вот полный код:

decodebarcode.h

#ifndef DECODEBARCODE_H
#define DECODEBARCODE_H

#include <QObject>
#ifdef Q_OS_ANDROID
#include <QtAndroidExtras/QtAndroid>
#include <QtAndroidExtras/QAndroidJniObject>
#include <QtAndroidExtras/QAndroidJniEnvironment>
#include <QtAndroidExtras/QAndroidActivityResultReceiver>
#endif

class BarCodeReceiver;

class DecodeBarCode : public QObject
{
Q_OBJECT

BarCodeReceiver *m_receiver;

public:
explicit DecodeBarCode(QObject *parent = 0);
~DecodeBarCode();

Q_INVOKABLE void useZXingApp();

signals:
void tagFound(QString tag);
};

#ifdef Q_OS_ANDROID
class BarCodeReceiver : public QAndroidActivityResultReceiver
{
DecodeBarCode *m_decoder;
public:
BarCodeReceiver(DecodeBarCode *decoder);

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

};
#else
class BarCodeReceiver
{
public:
BarCodeReceiver(DecodeBarCode *decoder) {Q_UNUSED(decoder)};
};
#endif

#endif // DECODEBARCODE_H

decodebarcode.cpp

#include "decodebarcode.h"
DecodeBarCode::DecodeBarCode(QObject *parent) : QObject(parent)
{
m_receiver = new BarCodeReceiver(this);
}

DecodeBarCode::~DecodeBarCode()
{
delete m_receiver;
}

void DecodeBarCode::useZXingApp()
{
#ifdef Q_OS_ANDROID
QAndroidJniObject action = QAndroidJniObject::fromString("com.google.zxing.client.android.SCAN");

// Intent intent = new Intent(action)
QAndroidJniObject intent("android/content/Intent","(Ljava/lang/String;)V", action.object<jstring>());

jint flagCategorieDefault = QAndroidJniObject::getStaticField<jint>("android/content/Intent", "CATEGORY_DEFAULT");
jint flagActivityClearTop = QAndroidJniObject::getStaticField<jint>("android/content/Intent", "FLAG_ACTIVITY_CLEAR_TOP");
jint flagActivityClearTaskReset = QAndroidJniObject::getStaticField<jint>("android/content/Intent", "FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET");

// intentScan.addCategory(Intent.CATEGORY_DEFAULT);
intent.callObjectMethod("addCategory", "(I)V", flagCategorieDefault);

//intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.callObjectMethod("addFlags", "(I)V", flagActivityClearTop);

//intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.callObjectMethod("addFlags", "(I)V", flagActivityClearTaskReset);

QtAndroid::startActivity(intent, 0, m_receiver);
#endif
}#ifdef Q_OS_ANDROID
BarCodeReceiver::BarCodeReceiver(DecodeBarCode *decoder)
: m_decoder(decoder)
{

}

void BarCodeReceiver::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data)
{
QAndroidJniObject stringExtraScanResult = QAndroidJniObject::fromString("SCAN_RESULT");
QAndroidJniObject scanResult = data.callObjectMethod("getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;", stringExtraScanResult.object<jstring>());
emit m_decoder->tagFound(scanResult.toString());
}
#endif

Если у вас есть такая же проблема, я надеюсь, что поможет

1

используйте эту библиотеку, чтобы спасти свою жизнь 🙂 https://github.com/zxing/zxing

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector