diff --git a/src/plugins/position/android/src/jnipositioning.cpp b/src/plugins/position/android/src/jnipositioning.cpp
index e0124eb6b7f26bb0b12490b0bb9655f221e166af..547d0fadf2ae6116195d09dce90b14879fa4d041 100644
--- a/src/plugins/position/android/src/jnipositioning.cpp
+++ b/src/plugins/position/android/src/jnipositioning.cpp
@@ -41,6 +41,7 @@
 #include <QDebug>
 #include <QMap>
 #include <QtGlobal>
+#include <QtCore/private/qjnihelpers_p.h>
 #include <android/log.h>
 #include <jni.h>
 #include <QGeoPositionInfo>
@@ -367,6 +368,20 @@ namespace AndroidPositioning {
         QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey);
 
         if (source) {
+            // Android v23+ requires runtime permission check and requests
+            QString permission(QLatin1String("android.permission.ACCESS_FINE_LOCATION"));
+
+            if (QtAndroidPrivate::checkPermission(permission) == QtAndroidPrivate::PermissionsResult::Denied) {
+                const QHash<QString, QtAndroidPrivate::PermissionsResult> results =
+                        QtAndroidPrivate::requestPermissionsSync(env.jniEnv, QStringList() << permission);
+                if (!results.contains(permission)
+                    || results[permission] == QtAndroidPrivate::PermissionsResult::Denied)
+                {
+                    qWarning() << "Position retrieval not possible due to missing permission (ACCESS_FINE_LOCATION)";
+                    return QGeoPositionInfoSource::AccessError;
+                }
+            }
+
             int errorCode = env.jniEnv->CallStaticIntMethod(positioningClass, startUpdatesMethodId,
                                              androidClassKey,
                                              positioningMethodToInt(source->preferredPositioningMethods()),
@@ -404,6 +419,20 @@ namespace AndroidPositioning {
         QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey);
 
         if (source) {
+            // Android v23+ requires runtime permission check and requests
+            QString permission(QLatin1String("android.permission.ACCESS_FINE_LOCATION"));
+
+            if (QtAndroidPrivate::checkPermission(permission) == QtAndroidPrivate::PermissionsResult::Denied) {
+                const QHash<QString, QtAndroidPrivate::PermissionsResult> results =
+                        QtAndroidPrivate::requestPermissionsSync(env.jniEnv, QStringList() << permission);
+                if (!results.contains(permission)
+                    || results[permission] == QtAndroidPrivate::PermissionsResult::Denied)
+                {
+                    qWarning() << "Position update not possible due to missing permission (ACCESS_FINE_LOCATION)";
+                    return QGeoPositionInfoSource::AccessError;
+                }
+            }
+
             int errorCode = env.jniEnv->CallStaticIntMethod(positioningClass, requestUpdateMethodId,
                                              androidClassKey,
                                              positioningMethodToInt(source->preferredPositioningMethods()));
diff --git a/src/plugins/position/android/src/src.pro b/src/plugins/position/android/src/src.pro
index 3a19c85e78be13856db0afab28fd55b78a975d4b..36facc55b87b3be1114917fbc283b6ba31ad1610 100644
--- a/src/plugins/position/android/src/src.pro
+++ b/src/plugins/position/android/src/src.pro
@@ -1,6 +1,6 @@
 TARGET = qtposition_android
 
-QT = core positioning
+QT = core core-private positioning
 
 HEADERS = \
     positionfactory_android.h \