diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
index 963952294c66f5f6f691e0fe0f38d5d0a01ae0d1..90d223c34cee22b4e6351ed304f1ac341b7474a5 100644
--- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
+++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
@@ -331,11 +331,12 @@ bool QAndroidCameraSession::startPreview()
     if (m_previewStarted)
         return true;
 
-    if (m_videoOutput->isReady())
-        m_camera->setPreviewTexture(m_videoOutput->surfaceTexture());
-    else
+    if (!m_videoOutput->isReady())
         return true; // delay starting until the video output is ready
 
+    if (!m_camera->setPreviewTexture(m_videoOutput->surfaceTexture()))
+        return false;
+
     m_status = QCamera::StartingStatus;
     emit statusChanged(m_status);
 
diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp
index c917bf2b732787422a2e248d687cfdebfc880479..32fc4bbaf8f83627773d6e9280ed206af7cf9dcd 100644
--- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp
@@ -56,6 +56,19 @@ static QMutex g_cameraMapMutex;
 typedef QMap<int, AndroidCamera *> CameraMap;
 Q_GLOBAL_STATIC(CameraMap, g_cameraMap)
 
+static inline bool exceptionCheckAndClear(JNIEnv *env)
+{
+    if (Q_UNLIKELY(env->ExceptionCheck())) {
+#ifdef QT_DEBUG
+        env->ExceptionDescribe();
+#endif // QT_DEBUG
+        env->ExceptionClear();
+        return true;
+    }
+
+    return false;
+}
+
 static QRect areaToRect(jobject areaObj)
 {
     QJNIObjectPrivate area(areaObj);
@@ -132,9 +145,9 @@ public:
     Q_INVOKABLE bool init(int cameraId);
 
     Q_INVOKABLE void release();
-    Q_INVOKABLE void lock();
-    Q_INVOKABLE void unlock();
-    Q_INVOKABLE void reconnect();
+    Q_INVOKABLE bool lock();
+    Q_INVOKABLE bool unlock();
+    Q_INVOKABLE bool reconnect();
 
     Q_INVOKABLE AndroidCamera::CameraFacing getFacing();
     Q_INVOKABLE int getNativeOrientation();
@@ -147,7 +160,7 @@ public:
 
     Q_INVOKABLE QSize previewSize() const { return m_previewSize; }
     Q_INVOKABLE void updatePreviewSize();
-    Q_INVOKABLE void setPreviewTexture(void *surfaceTexture);
+    Q_INVOKABLE bool setPreviewTexture(void *surfaceTexture);
 
     Q_INVOKABLE bool isZoomSupported();
     Q_INVOKABLE int getMaxZoom();
@@ -266,7 +279,7 @@ AndroidCamera *AndroidCamera::open(int cameraId)
     worker->start();
     d->moveToThread(worker);
     connect(worker, &QThread::finished, d, &AndroidCameraPrivate::deleteLater);
-    bool ok = false;
+    bool ok = true;
     QMetaObject::invokeMethod(d, "init", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok), Q_ARG(int, cameraId));
     if (!ok) {
         worker->quit();
@@ -289,22 +302,28 @@ int AndroidCamera::cameraId() const
     return d->m_cameraId;
 }
 
-void AndroidCamera::lock()
+bool AndroidCamera::lock()
 {
     Q_D(AndroidCamera);
-    QMetaObject::invokeMethod(d, "lock", Qt::BlockingQueuedConnection);
+    bool ok = true;
+    QMetaObject::invokeMethod(d, "lock", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok));
+    return ok;
 }
 
-void AndroidCamera::unlock()
+bool AndroidCamera::unlock()
 {
     Q_D(AndroidCamera);
-    QMetaObject::invokeMethod(d, "unlock", Qt::BlockingQueuedConnection);
+    bool ok = true;
+    QMetaObject::invokeMethod(d, "unlock", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok));
+    return ok;
 }
 
-void AndroidCamera::reconnect()
+bool AndroidCamera::reconnect()
 {
     Q_D(AndroidCamera);
-    QMetaObject::invokeMethod(d, "reconnect");
+    bool ok = true;
+    QMetaObject::invokeMethod(d, "reconnect", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok));
+    return ok;
 }
 
 void AndroidCamera::release()
@@ -368,13 +387,16 @@ void AndroidCamera::setPreviewSize(const QSize &size)
     QMetaObject::invokeMethod(d, "updatePreviewSize");
 }
 
-void AndroidCamera::setPreviewTexture(AndroidSurfaceTexture *surfaceTexture)
+bool AndroidCamera::setPreviewTexture(AndroidSurfaceTexture *surfaceTexture)
 {
     Q_D(AndroidCamera);
+    bool ok = true;
     QMetaObject::invokeMethod(d,
                               "setPreviewTexture",
                               Qt::BlockingQueuedConnection,
+                              Q_RETURN_ARG(bool, ok),
                               Q_ARG(void *, surfaceTexture ? surfaceTexture->surfaceTexture() : 0));
+    return ok;
 }
 
 bool AndroidCamera::isZoomSupported()
@@ -698,12 +720,12 @@ AndroidCameraPrivate::~AndroidCameraPrivate()
 bool AndroidCameraPrivate::init(int cameraId)
 {
     m_cameraId = cameraId;
+    QJNIEnvironmentPrivate env;
     m_camera = QJNIObjectPrivate::callStaticObjectMethod("android/hardware/Camera",
                                                          "open",
                                                          "(I)Landroid/hardware/Camera;",
                                                          cameraId);
-
-    if (!m_camera.isValid())
+    if (exceptionCheckAndClear(env) || !m_camera.isValid())
         return false;
 
     m_cameraListener = QJNIObjectPrivate(g_qtCameraListenerClass, "(I)V", m_cameraId);
@@ -731,26 +753,25 @@ void AndroidCameraPrivate::release()
         m_camera.callMethod<void>("release");
 }
 
-void AndroidCameraPrivate::lock()
+bool AndroidCameraPrivate::lock()
 {
+    QJNIEnvironmentPrivate env;
     m_camera.callMethod<void>("lock");
+    return !exceptionCheckAndClear(env);
 }
 
-void AndroidCameraPrivate::unlock()
+bool AndroidCameraPrivate::unlock()
 {
+    QJNIEnvironmentPrivate env;
     m_camera.callMethod<void>("unlock");
+    return !exceptionCheckAndClear(env);
 }
 
-void AndroidCameraPrivate::reconnect()
+bool AndroidCameraPrivate::reconnect()
 {
     QJNIEnvironmentPrivate env;
     m_camera.callMethod<void>("reconnect");
-    if (env->ExceptionCheck()) {
-#ifdef QT_DEBUG
-        env->ExceptionDescribe();
-#endif // QT_DEBUG
-        env->ExceptionDescribe();
-    }
+    return !exceptionCheckAndClear(env);
 }
 
 AndroidCamera::CameraFacing AndroidCameraPrivate::getFacing()
@@ -832,11 +853,13 @@ void AndroidCameraPrivate::updatePreviewSize()
     emit previewSizeChanged();
 }
 
-void AndroidCameraPrivate::setPreviewTexture(void *surfaceTexture)
+bool AndroidCameraPrivate::setPreviewTexture(void *surfaceTexture)
 {
+    QJNIEnvironmentPrivate env;
     m_camera.callMethod<void>("setPreviewTexture",
                               "(Landroid/graphics/SurfaceTexture;)V",
                               static_cast<jobject>(surfaceTexture));
+    return !exceptionCheckAndClear(env);
 }
 
 bool AndroidCameraPrivate::isZoomSupported()
@@ -1020,8 +1043,7 @@ void AndroidCameraPrivate::setFocusAreas(const QList<QRect> &areas)
             arrayList.callMethod<jboolean>("add",
                                            "(Ljava/lang/Object;)Z",
                                            rectToArea(areas.at(i)).object());
-            if (env->ExceptionCheck())
-                env->ExceptionClear();
+            exceptionCheckAndClear(env);
         }
         list = arrayList;
     }
@@ -1347,9 +1369,11 @@ void AndroidCameraPrivate::fetchLastPreviewFrame()
 
 void AndroidCameraPrivate::applyParameters()
 {
+    QJNIEnvironmentPrivate env;
     m_camera.callMethod<void>("setParameters",
                               "(Landroid/hardware/Camera$Parameters;)V",
                               m_parameters.object());
+    exceptionCheckAndClear(env);
 }
 
 QStringList AndroidCameraPrivate::callParametersStringListMethod(const QByteArray &methodName)
@@ -1386,10 +1410,8 @@ static JNINativeMethod methods[] = {
 bool AndroidCamera::initJNI(JNIEnv *env)
 {
     jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtCameraListener");
-    if (env->ExceptionCheck())
-        env->ExceptionClear();
 
-    if (clazz) {
+    if (!exceptionCheckAndClear(env) && clazz) {
         g_qtCameraListenerClass = static_cast<jclass>(env->NewGlobalRef(clazz));
         if (env->RegisterNatives(g_qtCameraListenerClass,
                                  methods,
diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.h b/src/plugins/android/src/wrappers/jni/androidcamera.h
index 2ea69b7e3ac28563fe95546221d06c87c9925723..010f089fb9cfb429a5285684b859c6be3a145670 100644
--- a/src/plugins/android/src/wrappers/jni/androidcamera.h
+++ b/src/plugins/android/src/wrappers/jni/androidcamera.h
@@ -90,9 +90,9 @@ public:
 
     int cameraId() const;
 
-    void lock();
-    void unlock();
-    void reconnect();
+    bool lock();
+    bool unlock();
+    bool reconnect();
     void release();
 
     CameraFacing getFacing();
@@ -106,7 +106,7 @@ public:
 
     QSize previewSize() const;
     void setPreviewSize(const QSize &size);
-    void setPreviewTexture(AndroidSurfaceTexture *surfaceTexture);
+    bool setPreviewTexture(AndroidSurfaceTexture *surfaceTexture);
 
     bool isZoomSupported();
     int getMaxZoom();