diff --git a/src/android/jar/src/org/qtproject/qt/android/QtNative.java b/src/android/jar/src/org/qtproject/qt/android/QtNative.java index 93bc6d80439..f9afa8ae38a 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtNative.java @@ -51,6 +51,12 @@ import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; +import android.util.Size; +import android.util.DisplayMetrics; +import android.view.WindowManager; +import android.view.WindowMetrics; +import android.graphics.Rect; + public class QtNative { private static Activity m_activity = null; @@ -412,6 +418,23 @@ public class QtNative return new ArrayList(); } + public static Size getDisplaySize(Context displayContext, Display display) + { + if (Build.VERSION.SDK_INT < 31) { + DisplayMetrics realMetrics = new DisplayMetrics(); + display.getRealMetrics(realMetrics); + return new Size(realMetrics.widthPixels, realMetrics.heightPixels); + } + + Context windowsContext = displayContext.createWindowContext( + WindowManager.LayoutParams.TYPE_APPLICATION, null); + WindowManager displayMgr = + (WindowManager) windowsContext.getSystemService(Context.WINDOW_SERVICE); + WindowMetrics windowsMetrics = displayMgr.getCurrentWindowMetrics(); + Rect bounds = windowsMetrics.getBounds(); + return new Size(bounds.width(), bounds.height()); + } + public static boolean startApplication(String params, String mainLib) throws Exception { if (params == null) diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index 4d046685ff6..54c7a34efec 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -54,6 +54,9 @@ private: Q_DECLARE_JNI_CLASS(Display, "android/view/Display") Q_DECLARE_JNI_CLASS(DisplayMetrics, "android/util/DisplayMetrics") +Q_DECLARE_JNI_CLASS(Resources, "android/content/res/Resources") +Q_DECLARE_JNI_CLASS(Size, "android/util/Size") +Q_DECLARE_JNI_CLASS(QtNative, "org/qtproject/qt/android/QtNative") Q_DECLARE_JNI_TYPE(DisplayMode, "Landroid/view/Display$Mode;") @@ -84,19 +87,31 @@ QAndroidPlatformScreen::QAndroidPlatformScreen(const QJniObject &displayObject) m_refreshRate = displayObject.callMethod("getRefreshRate"); m_displayId = displayObject.callMethod("getDisplayId"); - QJniObject displayMetricsObj(QtJniTypes::className()); - displayObject.callMethod("getRealMetrics", displayMetricsObj.object()); + const QJniObject context = QNativeInterface::QAndroidApplication::context(); + const auto displayContext = context.callMethod("createDisplayContext", + displayObject.object()); - const int widthPixels = displayMetricsObj.getField("widthPixels"); - const int heightPixels = displayMetricsObj.getField("heightPixels"); - m_size = QSize(widthPixels, heightPixels); + const auto sizeObj = QJniObject::callStaticMethod( + QtJniTypes::className(), + "getDisplaySize", + displayContext.object(), + displayObject.object()); + m_size = QSize(sizeObj.callMethod("getWidth"), sizeObj.callMethod("getHeight")); + + const auto resources = displayContext.callMethod("getResources"); + const auto metrics = resources.callMethod("getDisplayMetrics"); + const float xdpi = metrics.getField("xdpi"); + const float ydpi = metrics.getField("ydpi"); + + // Potentially densityDpi could be used instead of xpdi/ydpi to do the calculation, + // but the results are not consistent with devices specs. + // (https://issuetracker.google.com/issues/194120500) + m_physicalSize.setWidth(qRound(m_size.width() / xdpi * 25.4)); + m_physicalSize.setHeight(qRound(m_size.height() / ydpi * 25.4)); if (QNativeInterface::QAndroidApplication::sdkVersion() >= 23) { - const qreal xdpi = displayMetricsObj.getField("xdpi"); - const qreal ydpi = displayMetricsObj.getField("ydpi"); - const QJniObject currentMode = displayObject.callObjectMethod("getMode"); - const jint currentModeId = currentMode.callMethod("getModeId"); + m_currentMode = currentMode.callMethod("getModeId"); const QJniObject supportedModes = displayObject.callObjectMethod( "getSupportedModes"); @@ -106,20 +121,9 @@ QAndroidPlatformScreen::QAndroidPlatformScreen(const QJniObject &displayObject) const auto size = env->GetArrayLength(modeArray); for (jsize i = 0; i < size; ++i) { const auto mode = QJniObject::fromLocalRef(env->GetObjectArrayElement(modeArray, i)); - // Physical sizes in millimeters - const int physicalWidth = qRound(mode.callMethod("getPhysicalWidth") / xdpi * 25.4); - const int physicalHeight = qRound(mode.callMethod("getPhysicalHeight") / ydpi * 25.4); - - if (currentModeId == mode.callMethod("getModeId")) { - m_currentMode = i; - m_physicalSize = QSize { - physicalWidth, - physicalHeight - }; - } - m_modes << QPlatformScreen::Mode { - .size = QSize { physicalWidth, physicalHeight }, + .size = QSize { mode.callMethod("getPhysicalWidth"), + mode.callMethod("getPhysicalHeight") }, .refreshRate = mode.callMethod("getRefreshRate") }; }