diff --git a/.gitmodules b/.gitmodules
index f2a53617a074dd7c32d8d78c47a5f1d09f8769ae..0406ca94d5d4f98c432216f3072c15fea38be8b9 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,9 @@
 [submodule "qtquickdesigner-components"]
-path = qtquickdesigner-components
+path = 3rdparty/qtquickdesigner-components
 url = https://git.qt.io/design-studio/kit-dependencies/qt-quickdesigner-components.git
-[submodule "emsdk"]
-path = emsdk
-url = https://github.com/emscripten-core/emsdk.git
+[submodule "3rdparty/zxing-cpp"]
+	path = 3rdparty/zxing-cpp
+	url = https://github.com/zxing-cpp/zxing-cpp.git
+[submodule "3rdparty/qtquickdesigner-components"]
+	path = 3rdparty/qtquickdesigner-components
+	url = https://git.qt.io/design-studio/kit-dependencies/qt-quickdesigner-components
diff --git a/3rdparty/qtquickdesigner-components b/3rdparty/qtquickdesigner-components
new file mode 160000
index 0000000000000000000000000000000000000000..5736952b4b0c8aab4ae56b622ea9a53ae718b60a
--- /dev/null
+++ b/3rdparty/qtquickdesigner-components
@@ -0,0 +1 @@
+Subproject commit 5736952b4b0c8aab4ae56b622ea9a53ae718b60a
diff --git a/3rdparty/zxing-cpp b/3rdparty/zxing-cpp
new file mode 160000
index 0000000000000000000000000000000000000000..c97fc94e0e129feb0c3596371f86d725540322d7
--- /dev/null
+++ b/3rdparty/zxing-cpp
@@ -0,0 +1 @@
+Subproject commit c97fc94e0e129feb0c3596371f86d725540322d7
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7978a7ea1b01cad6c410229a349a3baf30f360eb..9c2f4ad05e4d7c34fd07cdc1f411032e2c9bfe77 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,7 +19,7 @@ find_package(
 
 find_package(
     Qt6
-    COMPONENTS Core Widgets Quick Gui Qml
+    COMPONENTS Core Widgets Quick Gui Qml Multimedia MultimediaWidgets
     REQUIRED
 )
 
@@ -28,6 +28,9 @@ if(QT_VERSION VERSION_LESS QT_MINIMUM_VERSION)
     message(FATAL_ERROR "Minimum supported Qt version: ${QT_MINIMUM_VERSION}")
 endif()
 
+
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/zxing-cpp)
+
 qt_add_executable(${PROJECT_NAME}
     src/importdummy.qml
     src/main.cpp
@@ -35,14 +38,16 @@ qt_add_executable(${PROJECT_NAME}
     src/serviceConnector.cpp src/serviceConnector.h
     src/projectManager.cpp src/projectManager.h
     src/dsConnector.cpp src/dsConnector.h
+    3rdparty/zxing-cpp/example/ZXingQtReader.h
     ui/main.qml
     ui/resources.qrc
 )
 
 target_link_libraries(${PROJECT_NAME} PRIVATE
-    Qt6::Core Qt6::Widgets
-    Qt6::Quick Qt6::Gui
-    Qt6::Qml Qt6::GuiPrivate
+    Qt::Core Qt::Widgets
+    Qt::Quick Qt::Gui
+    Qt::Qml Qt::GuiPrivate Qt::Multimedia Qt::MultimediaWidgets
+    ZXing::ZXing
 )
 
 set_property(TARGET ${PROJECT_NAME}
@@ -69,11 +74,13 @@ set_property(TARGET ${PROJECT_NAME} PROPERTY QT_ANDROID_TARGET_SDK_VERSION 34)
 qt6_import_qml_plugins(${PROJECT_NAME})
 
 execute_process(COMMAND git describe --always --tags OUTPUT_VARIABLE GIT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
-execute_process(COMMAND git -C ${CMAKE_SOURCE_DIR}/qtquickdesigner-components describe --always --tags OUTPUT_VARIABLE QT_QUICK_COMPONENTS_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
+execute_process(COMMAND git -C ${CMAKE_SOURCE_DIR}/3rdparty/qtquickdesigner-components describe --always --tags OUTPUT_VARIABLE QT_QUICK_COMPONENTS_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
+execute_process(COMMAND git -C ${CMAKE_SOURCE_DIR}/3rdparty/zxing-cpp describe --always --tags OUTPUT_VARIABLE ZXING-CPP OUTPUT_STRIP_TRAILING_WHITESPACE)
 
 add_definitions( -DGIT_VERSION="${GIT_VERSION}" )
 add_definitions( -DQT_QUICK_COMPONENTS_VERSION="${QT_QUICK_COMPONENTS_VERSION}" )
 
-message(STATUS "GIT_VERSION: ${GIT_VERSION}")
-message(STATUS "QT_QUICK_COMPONENTS_VERSION: ${QT_QUICK_COMPONENTS_VERSION}")
+message(STATUS "PROJECT VERSION: ${GIT_VERSION}")
 message(STATUS "QT_VERSION: ${QT_VERSION}")
+message(STATUS "QT_QUICK_COMPONENTS_VERSION: ${QT_QUICK_COMPONENTS_VERSION}")
+message(STATUS "ZXING-CPP: ${ZXING-CPP}")
diff --git a/README.md b/README.md
index 10c34f863b6553edd5cd9385b8adfa59133db690..171d62e41ff9dfec9c3d35150d7d38f2c5ef0ab9 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,9 @@ Qt Design Viewer works with minimum Android 33.
 * android: Files needed for Android build system
 * src: Backend source files
 * ui: UI source files
-* qtquickdesigner-components: Required 3rd party QML components
+* 3rdparty: Required 3rd party libraries
+    * qtquickdesigner-components: QML components
+    * zxing-cpp: QR code decoding/encoding
 
 ## Building
 
@@ -36,7 +38,7 @@ Build instructions are provided for Linux and macOS hosts. Windows should work a
 First build and install QtQuickDesigner Components for Android:
 
 ```bash
-cd qtquickdesigner-components
+pushd 3rdparty/qtquickdesigner-components
 cmake \
     -S . \
     -B build \
@@ -50,7 +52,7 @@ cmake \
 
 cmake --build build
 cmake --install build
-cd ..
+popd
 ```
 
 Then build the Qt Design Viewer:
@@ -71,3 +73,13 @@ cmake --build build
 ## Usage
 
 Upload the final APK file to your Android device and run. Then follow the instructions within the app.
+
+## 3rd Party Libraries/Components
+
+* [zxing-cpp](https://github.com/zxing-cpp/zxing-cpp.git)
+  Apache License 2.0
+  ZXing C++ port for QR code decoding.
+
+* [QtQuickDesigner Components](https://codereview.qt-project.org/gitweb?p=qt-labs%2Fqtquickdesigner-components.git;a=summary)
+  GNU GENERAL PUBLIC LICENSE
+  QtQuickDesigner Components is a collection of QML components for Qt Quick Designer.
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index 991eba4fbe321927ab6067e0c9d2a49695e5be29..874d2a0c03b874f89d2885778f608a221ee90354 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.qt.qtdesignviewer"
-    android:installLocation="auto" android:versionCode="21" android:versionName="1.2">
+    android:installLocation="auto" android:versionCode="22" android:versionName="1.2">
     <!-- %%INSERT_PERMISSIONS -->
     <!-- %%INSERT_FEATURES -->
     <supports-screens android:anyDensity="true" android:largeScreens="true"
@@ -9,6 +9,7 @@
         android:extractNativeLibs="true" android:hardwareAccelerated="true"
         android:label="Qt UI Viewer" android:requestLegacyExternalStorage="true"
         android:allowNativeHeapPointerTagging="false" android:icon="@mipmap/app_icon">
+        <profileable android:shell="true" android:enabled="true" />
         <activity android:name="org.qtproject.qt.android.bindings.QtActivity"
             android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
             android:label="Qt UI Viewer" android:launchMode="singleTask"
diff --git a/cicd/gitlab-ci.yml b/cicd/gitlab-ci.yml
index 276bcefd5718a81582ff856626f962aea2d11ea5..4e583bfdfb111790deac64cf5c00a3d46c6b3b98 100644
--- a/cicd/gitlab-ci.yml
+++ b/cicd/gitlab-ci.yml
@@ -1,9 +1,10 @@
 variables:
   QDS_CI_QT_VERSION:
-    value: "652"
+    value: "661"
     options:
       - "643"
       - "652"
+      - "661"
     description: "Qt version for build"
   QDS_CI_ARTIFACTS_PATH: "${CI_PROJECT_DIR}/artifacts"
   DEBIAN_FRONTEND: non-interactive
diff --git a/cicd/stages/build.yml b/cicd/stages/build.yml
index 8ae57968560a8827310e12afd15c5a603793ffd5..5ea8a310ec6be6216207b3bd26330409acf3fc7b 100644
--- a/cicd/stages/build.yml
+++ b/cicd/stages/build.yml
@@ -20,7 +20,6 @@ build-android-multiarch:
     QDS_BUILD_PATH: "${CI_PROJECT_DIR}/outdir/build"
     QDS_CI_JOB_ARTIFACTS_PATH: ${QDS_CI_ARTIFACTS_PATH}/${QDS_CI_JOB_TARGET_PLATFORM}/${QDS_CI_JOB_TARGET_ARCH}
     QDS_CI_JOB_TARGET_PLATFORM: "android"
-    QDS_CI_QT_VERSION: "652"
   image: "git.qt.io:4567/design-studio/maintenance/docker-images/${QDS_CI_JOB_TARGET_PLATFORM}:${QDS_CI_QT_VERSION}-${QDS_CI_JOB_TARGET_PLATFORM}-${QDS_CI_JOB_TARGET_ARCH}"
   artifacts:
     name: design-viewer-${CI_JOB_ID}-qt${QDS_CI_QT_VERSION}-${QDS_CI_JOB_TARGET_PLATFORM}-${QDS_CI_JOB_TARGET_ARCH}
@@ -31,9 +30,9 @@ build-android-multiarch:
     - if: $QDS_CI_QT_VERSION_ANDROID != "none"
   script:
     - mkdir -p ${QDS_CI_JOB_ARTIFACTS_PATH}
-    - cd qtquickdesigner-components
     - ls -l /opt/openssl/ssl_3/
     - ls -l ${QDS_CI_JOB_OPENSSL_PATH}
+    - pushd 3rdparty/qtquickdesigner-components
     - |
       cmake \
       -S . \
@@ -47,7 +46,7 @@ build-android-multiarch:
       -DANDROID_OPENSSL_PATH=${QDS_CI_JOB_OPENSSL_PATH}
     - cmake --build .
     - cmake --install .
-    - cd ..
+    - popd
     - |
       cmake \
       -S . \
diff --git a/qtquickdesigner-components b/qtquickdesigner-components
deleted file mode 160000
index 55dfd50975935efbe67ea8cdb77ac01e4640db88..0000000000000000000000000000000000000000
--- a/qtquickdesigner-components
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 55dfd50975935efbe67ea8cdb77ac01e4640db88
diff --git a/src/backend.cpp b/src/backend.cpp
index a94691d8566e3c094f9bdc31fb09b6dfd4bab826..04315c03da66a60b25e983ed0011f50a5dd2985a 100644
--- a/src/backend.cpp
+++ b/src/backend.cpp
@@ -26,13 +26,19 @@
 #include "backend.h"
 #include "qapplication.h"
 
+#include <QCameraDevice>
 #include <QDesktopServices>
 #include <QFileInfo>
 #include <QJsonArray>
 #include <QJsonObject>
-
+#include <QMediaDevices>
 #include <QSettings>
 #include <QSslSocket>
+#include <QVideoSink>
+
+#include "../3rdparty/zxing-cpp/example/ZXingQtReader.h"
+
+using namespace ZXingQt;
 
 Backend::Backend(QObject *parent)
     : QObject(parent)
@@ -104,6 +110,50 @@ void Backend::updateInBackground(const bool &enabled)
     }
 }
 
+void Backend::scanQrCode()
+{
+    m_captureSession.reset(new QMediaCaptureSession(this));
+    m_captureSession->setCamera(new QCamera(this));
+    m_captureSession->setVideoOutput(new CustomVideoWidget);
+
+    m_captureSession->camera()->setFocusMode(QCamera::FocusModeAuto);
+
+    CustomVideoWidget *videoWidget = qobject_cast<CustomVideoWidget *>(
+        m_captureSession->videoOutput());
+
+    connect(m_captureSession->videoSink(),
+            &QVideoSink::videoFrameChanged,
+            this,
+            [&](const QVideoFrame &frame) {
+                static int i = 0;
+                if (i++ < 30) {
+                    return;
+                }
+
+                i = 0;
+
+                auto results = ReadBarcodes(frame.toImage());
+                for (auto &result : results) {
+                    qDebug() << "Text:   " << result.text();
+                    qDebug() << "Format: " << result.format();
+                    qDebug() << "Content:" << result.contentType();
+                    parseDesignViewerUrl(result.text());
+                    qobject_cast<CustomVideoWidget *>(m_captureSession->videoOutput())->close();
+                }
+            });
+
+    connect(videoWidget, &CustomVideoWidget::closed, this, [&] {
+        qDebug() << "Video widget closed. Clearing capture session";
+        m_captureSession->camera()->stop();
+        m_captureSession->camera()->deleteLater();
+        m_captureSession->videoOutput()->deleteLater();
+        m_captureSession.clear();
+    });
+
+    videoWidget->show();
+    m_captureSession->camera()->start();
+}
+
 void Backend::cacheDemoProjects(const bool &enabled)
 {
     QSettings().setValue("system/cacheDemoProjects", enabled);
diff --git a/src/backend.h b/src/backend.h
index 124c9490073c1d5ad84877948c0e3fca2bedd6a1..a061edb48278b9fee1246c9d0f0a28ed8604c5b0 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -26,12 +26,35 @@
 #ifndef DV_ANDROID_H
 #define DV_ANDROID_H
 
+#include <QCamera>
+#include <QImageCapture>
+#include <QMediaCaptureSession>
 #include <QThread>
+#include <QVideoWidget>
+#include <QWidget>
 
 #include "dsConnector.h"
 #include "projectManager.h"
 #include "serviceConnector.h"
 
+#include <QLabel>
+#include <QVBoxLayout>
+
+class CustomVideoWidget : public QVideoWidget
+{
+    Q_OBJECT
+public:
+    explicit CustomVideoWidget(QWidget *parent = nullptr)
+        : QVideoWidget(parent)
+    {}
+    ~CustomVideoWidget() override {}
+
+    void closeEvent(QCloseEvent *event) override { emit closed(); }
+
+signals:
+    void closed();
+};
+
 class Backend : public QObject
 {
     Q_OBJECT
@@ -64,6 +87,7 @@ private:
     QThread m_dsConnectorThread;
 
     QTimer m_backgroundTimer;
+    QSharedPointer<QMediaCaptureSession> m_captureSession;
 
     // member functions
     void updateUserProjectList();
@@ -84,6 +108,8 @@ signals:
     void urlUpdated(QString);
 
 public slots:
+    void scanQrCode();
+
     void runOnlineProject(const QString &url);
     void runUserProject(const QString &projectName);
     void runDemoProject(const QString &projectName);
diff --git a/src/main.cpp b/src/main.cpp
index 24974a06aeafbd3f0cec030801f785659fceaf6d..a4cc5408f20cb46cc3569bef758d62b11f779c79 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -24,8 +24,10 @@
 ****************************************************************************/
 
 #include <android/log.h>
+
 #include <QApplication>
 #include <QMessageBox>
+#include <QPermission>
 #include <QQmlContext>
 
 #include "backend.h"
@@ -83,6 +85,25 @@ int main(int argc, char *argv[])
     QQuickView view;
     backend = new Backend();
 
+    // request permissions
+    QCameraPermission permission;
+    switch (app.checkPermission(permission)) {
+    case Qt::PermissionStatus::Granted:
+        break;
+    case Qt::PermissionStatus::Undetermined:
+    case Qt::PermissionStatus::Denied:
+        app.requestPermission(permission, [](const QPermission &permission) {
+            if (permission.status() == Qt::PermissionStatus::Denied) {
+                QMessageBox msgBox{QMessageBox::Critical,
+                                   "Critical:",
+                                   "Camera permission denied",
+                                   QMessageBox::Ok};
+                msgBox.exec();
+            }
+        });
+        break;
+    }
+
     view.engine()->rootContext()->setContextProperty("backend", backend);
     view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
     view.setResizeMode(QQuickView::SizeRootObjectToView);
diff --git a/src/projectManager.cpp b/src/projectManager.cpp
index 1150c23243d2ecb02e97770fb6f86c7d7c542e8b..1b3867cd5bf8e735bb0d3ecf10561ce256762ce8 100644
--- a/src/projectManager.cpp
+++ b/src/projectManager.cpp
@@ -40,7 +40,11 @@
 #include <QStandardPaths>
 #include <QTemporaryDir>
 #include <QTemporaryFile>
+#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
+#include <QtCore/private/qzipreader_p.h>
+#else
 #include <QtGui/private/qzipreader_p.h>
+#endif
 
 ProjectManager::ProjectManager(QObject *parent)
     : QObject(parent)
diff --git a/ui/HomePage.qml b/ui/HomePage.qml
index 4ed0c0264c06913eb29206fa48367886d0433700..add017c5e392360228402655c4af2b167d92bcbd 100644
--- a/ui/HomePage.qml
+++ b/ui/HomePage.qml
@@ -46,7 +46,21 @@ Item {
             wrapMode: Text.WordWrap
             Layout.fillWidth: true
         }
+        Button {
+            id: scanQrCode
+            text: qsTr("Scan QR Code")
+            onClicked: backend.scanQrCode()
+            Layout.fillWidth: true
+            Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+        }
 
+        Item {
+            id: item4
+            Layout.preferredWidth: 10
+            Layout.preferredHeight: 10
+            Layout.fillWidth: true
+            Layout.fillHeight: true
+        }
         ColumnLayout {
             id: column2
             Layout.fillWidth: true