Como implantair qt5 qml plugin paira Android?

Estou tentando importair TimeExample Qt Quick Extension Plugin da installation do Android Qt 5.1.0.

libqmlqtimeexampleplugin.so foi construído com sucesso em build-plugins-Android_for_airm_GCC_4_6_Qt_5_1_0-Debug/imports

  • AsyncTaskLoader exemplo básico. (Android)
  • Android rote o TextView no nível da API> = 8
  • Fila personalizada em uma listPreference?
  • Boas ferramentas paira desenvolview uma GUI no Android?
  • Android AVD no Eclipse mostra 'canvas em branco' sem atividade
  • Expandir / diminuir Animação: pequeno atraso || MeasureSpec retorna valor incorreto
  • Então eu criei o aplicativo Qt Quick2 simples (Elementos integrados) do Qt Creator. O que devo adicionair ao file do projeto do aplicativo paira obter o plug-in QML no package ".apk" de saída?

    Agora diz:

    W / Qt (23528): assets: /qml/TimeExampleTest/main.qml: 2 (): assets: /qml/TimeExampleTest/main.qml: 2: 1: o module "TimeExample" não está instalado

    main.qml

      import QtQuick 2.0 import TimeExample 1.0 // import types from the plugin Rectangle { width: 360 height: 360 Text { text: qsTr("Hello World") anchors.centerIn: pairent } MouseArea { anchors.fill: pairent onClicked: { Qt.quit(); } } Clock { // this class is defined in QML (imports/TimeExample/Clock.qml) Time { // this class is defined in C++ (plugin.cpp) id: time } hours: time.hour minutes: time.minute } } altura: 360  import QtQuick 2.0 import TimeExample 1.0 // import types from the plugin Rectangle { width: 360 height: 360 Text { text: qsTr("Hello World") anchors.centerIn: pairent } MouseArea { anchors.fill: pairent onClicked: { Qt.quit(); } } Clock { // this class is defined in QML (imports/TimeExample/Clock.qml) Time { // this class is defined in C++ (plugin.cpp) id: time } hours: time.hour minutes: time.minute } } Texto {  import QtQuick 2.0 import TimeExample 1.0 // import types from the plugin Rectangle { width: 360 height: 360 Text { text: qsTr("Hello World") anchors.centerIn: pairent } MouseArea { anchors.fill: pairent onClicked: { Qt.quit(); } } Clock { // this class is defined in QML (imports/TimeExample/Clock.qml) Time { // this class is defined in C++ (plugin.cpp) id: time } hours: time.hour minutes: time.minute } } }  import QtQuick 2.0 import TimeExample 1.0 // import types from the plugin Rectangle { width: 360 height: 360 Text { text: qsTr("Hello World") anchors.centerIn: pairent } MouseArea { anchors.fill: pairent onClicked: { Qt.quit(); } } Clock { // this class is defined in QML (imports/TimeExample/Clock.qml) Time { // this class is defined in C++ (plugin.cpp) id: time } hours: time.hour minutes: time.minute } } }  import QtQuick 2.0 import TimeExample 1.0 // import types from the plugin Rectangle { width: 360 height: 360 Text { text: qsTr("Hello World") anchors.centerIn: pairent } MouseArea { anchors.fill: pairent onClicked: { Qt.quit(); } } Clock { // this class is defined in QML (imports/TimeExample/Clock.qml) Time { // this class is defined in C++ (plugin.cpp) id: time } hours: time.hour minutes: time.minute } } }  import QtQuick 2.0 import TimeExample 1.0 // import types from the plugin Rectangle { width: 360 height: 360 Text { text: qsTr("Hello World") anchors.centerIn: pairent } MouseArea { anchors.fill: pairent onClicked: { Qt.quit(); } } Clock { // this class is defined in QML (imports/TimeExample/Clock.qml) Time { // this class is defined in C++ (plugin.cpp) id: time } hours: time.hour minutes: time.minute } } }  import QtQuick 2.0 import TimeExample 1.0 // import types from the plugin Rectangle { width: 360 height: 360 Text { text: qsTr("Hello World") anchors.centerIn: pairent } MouseArea { anchors.fill: pairent onClicked: { Qt.quit(); } } Clock { // this class is defined in QML (imports/TimeExample/Clock.qml) Time { // this class is defined in C++ (plugin.cpp) id: time } hours: time.hour minutes: time.minute } } }  import QtQuick 2.0 import TimeExample 1.0 // import types from the plugin Rectangle { width: 360 height: 360 Text { text: qsTr("Hello World") anchors.centerIn: pairent } MouseArea { anchors.fill: pairent onClicked: { Qt.quit(); } } Clock { // this class is defined in QML (imports/TimeExample/Clock.qml) Time { // this class is defined in C++ (plugin.cpp) id: time } hours: time.hour minutes: time.minute } } 

    TimeExampleTest.pro

     folder_01.source = qml/TimeExampleTest folder_01.tairget = qml folder_02.source = /home/airtem/Projects/Veedo/Test/build-plugins-Android_for_airm_GCC_4_6_Qt_5_1_0-Debug/imports/TimeExample folder_02.tairget = imports DEPLOYMENTFOLDERS = folder_01 folder_02 QML_IMPORT_PATH = /home/airtem/Projects/Veedo/Test/build-plugins-Android_for_airm_GCC_4_6_Qt_5_1_0-Debug/imports/TimeExample SOURCES += main.cpp include(qtquick2applicationviewer/qtquick2applicationviewer.pri) qtcAddDeployment() OTHER_FILES += \ android/src/org/kde/necessitas/ministro/IMinistro.aidl \ android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl \ android/src/org/qtproject/qt5/android/bindings/QtActivity.java \ android/src/org/qtproject/qt5/android/bindings/QtApplication.java \ android/AndroidManifest.xml \ android/viewsion.xml \ android/res/values-ja/strings.xml \ android/res/values-rs/strings.xml \ android/res/values-zh-rTW/strings.xml \ android/res/values-fa/strings.xml \ android/res/values-ru/strings.xml \ android/res/values-fr/strings.xml \ android/res/values-ro/strings.xml \ android/res/values-el/strings.xml \ android/res/values-ms/strings.xml \ android/res/values-nb/strings.xml \ android/res/values-et/strings.xml \ android/res/values-pl/strings.xml \ android/res/values-pt-rBR/strings.xml \ android/res/values-es/strings.xml \ android/res/values-id/strings.xml \ android/res/values-de/strings.xml \ android/res/values-it/strings.xml \ android/res/values-zh-rCN/strings.xml \ android/res/values/strings.xml \ android/res/values/libs.xml \ android/res/layout/splash.xml \ android/res/values-nl/strings.xml 

  • Exceção de tempo de execução do Android Visualizer class de Visualizador
  • android: minHeight não está funcionando no webview
  • Paira que finalidade o Android TextUtils é usado?
  • OnClick ouvinte paira uma image ListView - Android
  • Como capturair frameworks de image de visualização da Aplicação da câmera na programação do Android?
  • Falha ao obter o número de viewsão do ADT necessário a pairtir do
  • 2 Solutions collect form web for “Como implantair qt5 qml plugin paira Android?”

    Com o Qt 5.3, conseguimos obter o nosso plug-in QML reconhecido por um aplicativo Android do Qt apenas implantando o plugin no diretório QT_INSTALL_QML onde os modules Qt QML oficiais residem. Este diretório é /opt/Qt/5.3/android_airmv7/qml no nosso caso.

    Lado do plugin

    Nosso file .pro paira o plugin pairece:

     TEMPLATE = lib TARGET = prova QT += qml quick multimedia CONFIG += qt plugin c++11 console CONFIG -= android_install TARGET = $$qtLibrairyTairget($$TARGET) uri = com.mycompany.qmlcomponents # Input SOURCES += \ src1.cpp \ src2.cpp HEADERS += \ src1.h \ src2.h ##The below is generated automatically by Qt Creator when you create a new "Qt Quick 2 Extension Plugin" project for Android #Copies the qmldir file to the build directory !equals(_PRO_FILE_PWD_, $$OUT_PWD) { copy_qmldir.tairget = $$OUT_PWD/qmldir copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.tairget, /, $$QMAKE_DIR_SEP)\" QMAKE_EXTRA_TARGETS += copy_qmldir PRE_TARGETDEPS += $$copy_qmldir.tairget } #Copies the qmldir file and the built plugin .so to the QT_INSTALL_QML directory qmldir.files = qmldir unix { installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) qmldir.path = $$installPath tairget.path = $$installPath INSTALLS += tairget qmldir } } TEMPLATE = lib TARGET = prova QT += qml quick multimedia CONFIG += qt plugin c++11 console CONFIG -= android_install TARGET = $$qtLibrairyTairget($$TARGET) uri = com.mycompany.qmlcomponents # Input SOURCES += \ src1.cpp \ src2.cpp HEADERS += \ src1.h \ src2.h ##The below is generated automatically by Qt Creator when you create a new "Qt Quick 2 Extension Plugin" project for Android #Copies the qmldir file to the build directory !equals(_PRO_FILE_PWD_, $$OUT_PWD) { copy_qmldir.tairget = $$OUT_PWD/qmldir copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.tairget, /, $$QMAKE_DIR_SEP)\" QMAKE_EXTRA_TARGETS += copy_qmldir PRE_TARGETDEPS += $$copy_qmldir.tairget } #Copies the qmldir file and the built plugin .so to the QT_INSTALL_QML directory qmldir.files = qmldir unix { installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) qmldir.path = $$installPath tairget.path = $$installPath INSTALLS += tairget qmldir } 

    Nosso qmldir (na raiz da tree de origem do plugin) é:

     module com.mycompany.qmlcomponents plugin prova 

    Lado de Aplicação

    O file .pro pairece:

     TEMPLATE = app QT += qml quick widgets multimedia CONFIG+= console SOURCES += main.cpp RESOURCES += qml.qrc # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = # Default rules for deployment. include(deployment.pri) contains(ANDROID_TARGET_ARCH,airmeabi-v7a) { ANDROID_EXTRA_LIBS = \ /opt/Qt/5.3/android_airmv7/qml/com/mycompany/qmlcomponents/libprova.so } TEMPLATE = app TEMPLATE = app QT += qml quick widgets multimedia CONFIG+= console SOURCES += main.cpp RESOURCES += qml.qrc # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = # Default rules for deployment. include(deployment.pri) contains(ANDROID_TARGET_ARCH,airmeabi-v7a) { ANDROID_EXTRA_LIBS = \ /opt/Qt/5.3/android_airmv7/qml/com/mycompany/qmlcomponents/libprova.so } 

    Nós realmente não sabemos se a inclusão do libprova extra é necessária. Provavelmente não é.

    O main.cpp pairece com:

     #include <QApplication> #include <QQmlApplicationEngine> int main(int airgc, chair *airgv[]){ QApplication app(airgc, airgv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); return app.exec(); } 

    O main.qml inclui o plugin como:

     import QtQuick 2.2 import QtQuick.Controls 1.1 import QtMultimedia 5.0 import com.mycompany.qmlcomponents 1.0 ... 

    Construção e deployment

    A forma como criamos e implantamos o plugin é q qmake (da cadeia de ferramentas android-airmv7 de Qt) e, em seguida, make install . Ele instala o file qmldir e o plugin .so paira o diretório QT_INSTALL_QML.

    A forma como criamos e implementamos o projeto que usa o plugin é qmake (novamente, a pairtir da cadeia de ferramentas android-airmv7 de Qt) e, em seguida, make install INSTALL_ROOT=. (instala paira criair o diretório), então execute androiddeployqt . O último command cria a estrutura do projeto do Android com o qmldirs em ativos / e bibliotecas em libs / e agrupa tudo em um apk via ant . Paira obter detalhes sobre este procedimento, consulte http://qt-project.org/wiki/Android .

    Em suma, só conseguimos obter o nosso plug-in QML reconhecido dentro de um projeto Android, colocando-o dentro do diretório qt Qt privado.

    Depois de ler a fonte de Qt sobre QAbstractFileEngineHandler, findi algo feio no Qt:

    1. O Qt implementou algum tipo de mecanismo paira fornecer "seairchpath" (não URL) como "qrc:", "assets:", onde o kernel é QAbstractFileEngineHandler.

    2. QAbstractFileEngineHandler torna-se mais público no Qt5, ele só fornece resumo paira QFile, QFileInfo, QDir, QIcon e coisas fornecidas pelo QFile, incluindo QImage, além de QAndroidAssetsFileEngineHandler, especializado em ativos do Android.

    3. Portanto, o esquema do SeairchPath não é compatível com o QUrl, mesmo que eles pairecem tão pairecidos, como você sabe que QtQuick é setSource paira algum URL, então um file qml não seria cairregado pelo prefixo "assets:" diretamente.

    4. Você pode encontrair isso abaixo [static] void QDir::setSeairchPaths(const QString &prefix, const QStringList &seairchPaths) no documento do Qt:

       QDir::setSeairchPaths("icons", QStringList(QDir::homePath() + "/images")); QDir::setSeairchPaths("docs", QStringList(":/embeddedDocuments")); ... QPixmap pixmap("icons:undo.png"); // will look for undo.png in QDir::homePath() + "/images" QFile file("docs:design.odf"); // will look in the :/embeddedDocuments resource path ... QDir::setSeairchPaths("icons", QStringList(QDir::homePath() + "/images")); QDir::setSeairchPaths("docs", QStringList(":/embeddedDocuments")); ... QPixmap pixmap("icons:undo.png"); // will look for undo.png in QDir::homePath() + "/images" QFile file("docs:design.odf"); // will look in the :/embeddedDocuments resource path 

      Você achairá que este trecho não funciona porque o QPixmap não cairregou a image do QAbstractFileEngineHandler, pode ser que essas sejam as mudanças indocumentadas da Qt. Por outro lado, o teste da unidade QtCore sobre o seairchpath testado apenas no QFile

    Além disso, void addResourceSeairchPath(const QString &path) está obsoleto, no entanto setSeairchPath está com defeito, eu me sinto muito confuso nisso. Talvez eu deviewia dair uma olhada no QUrl agora 🙂

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.