使用非本机工具在 Qt 中检测平板电脑或手机的正确方法
A proper way to detect Tablet or Mobile in Qt using non-native tools
我的目的是确定我在其上部署应用程序的是平板电脑还是移动设备。
当我部署 iOS、Android、Linux 桌面和 Windows 应用程序时,最好使用非本机工具。
但作为实验的一部分,我为 android 尝试了以下技巧(java class 的方法):
实验#1
public class JniUtilities {
public static boolean isTablet(Context context) {
Log.d("INDENTIFICATOR >> ", "HEJJ, I AM CALLED!");
return ((context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE);
}
}
结果: 似乎工作正常,但不适用于其他操作系统:(
实验#2
让我们试试Qt Framework 工具。在这里,我可以了解具有 QScreen class
个实例的设备物理尺寸。作为 isTablet
的标准,我将使用 diagonal > 7.0 inches
.
的条件
qreal Utils::getDiagInch() {
QScreen *srn = qApp->screens().at(0);
qreal w = srn->physicalSize().width();
qreal h = srn->physicalSize().height();
qreal inches = qSqrt(w * w + h * h) / 25.4; // millimeters to inches
qDebug() << "physical diagonal >> " << inches;
return inches;
}
对于实验,我使用了 HTC ONE X
phone。
(qreal Utils::getDiagInch()): physical width >> 3.38583
(qreal Utils::getDiagInch()): physical height >> 6.02362
(qreal Utils::getDiagInch()): physical diagonal >> 6.90998
正如我们从官方制造商的属性中看到的那样,phone 有
width of 2.3 inches,
height of 4.1 inches and
diagonal of 4.7 inches
好的。有了不正确的值,我们无论如何得到了正确的结果:
HTC ONE X is PHONE as it has diagonal less than 7.0 inches.
结果: 该方法不可靠。
好的。另一个实验:
实验 #3
建议问题出在 Qt Framework 实现中,returning 值不正确。然后,如果我们询问 Android 显示物理尺寸的本机工具,它应该 return 不同的结果:
java-class:
public class MyActivityJo extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
double physWidth = metrics.widthPixels / metrics.xdpi;
Log.d("ph width >> ", Double.toString(physWidth));
double physHeight = metrics.heightPixels / metrics.ydpi;
Log.d("ph height >> ", Double.toString(physHeight));
double physDiag = Math.sqrt(physWidth * physWidth + physHeight * physHeight);
Log.d("ph diagonal >> ", Double.toString(physDiag));
}
}
输出:
D/ph width >> (27948): 3.380281686782837
D/ph height >> (27948): 6.009389877319336
D/ph diagonal >> (27948): 6.894858300184821
结果: DisplayMetrics return 的值也不正确。
总体
我试过很多 playmarket 应用程序。他们知道如何准确回答这个问题:没有一个应用检测错误 tablet/phone。他们是怎么做到的?他们使用本地工具吗?还是Qt Framework有通用的、非原生的方法明确解决问题??
如果一定要获取屏幕的dpi值,可以按照这个方法:
在.pro
android{
QT += androidextras
}
包括
#if defined(Q_OS_ANDROID)
#include <QAndroidJniObject>
#endif
代码:
qreal m_dpi;
qreal m_pixelRatio;
#if defined(Q_OS_ANDROID)
QAndroidJniObject qtActivity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
QAndroidJniObject resources = qtActivity.callObjectMethod("getResources","()Landroid/content/res/Resources;");
QAndroidJniObject displayMetrics = resources.callObjectMethod("getDisplayMetrics","()Landroid/util/DisplayMetrics;");
int density = displayMetrics.getField<int>("densityDpi");
m_dpi = density;
m_pixelRatio = 1;
#else
m_dpi = qApp->primaryScreen()->physicalDotsPerInch();
m_pixelRatio = qApp->primaryScreen()->devicePixelRatio();
#endif
获得 dpi 后,如果必须找到相对于参考设备的比例因子。
qreal m_dpiRef = 132; //reference device dpi (ipad);
double scalingFactor = 1;
if(m_dpi>0&&m_dpiRef >0)
scalingFactor=m_dpi/m_dpiRef;
物理尺寸:
width/m_dpi //should give the physical width of screen in inches.
要在 android 设备中检查设备是平板电脑还是移动设备,最小宽度为 600dp 的 mdpi(160 dpi) android 设备可被视为平板电脑(可能会因您的要求而异) ).
width*160/m_dpi >= 600 //to check if the screen size is large enough(tablet).
我已经验证了 Android 和 iOS 的代码。
您可能需要为 windows 使用以下代码。 (请验证)。
m_dpi = qApp->primaryScreen()->logicalDotsPerInch()*qApp->primaryScreen()->devicePixelRatio();
我的目的是确定我在其上部署应用程序的是平板电脑还是移动设备。
当我部署 iOS、Android、Linux 桌面和 Windows 应用程序时,最好使用非本机工具。
但作为实验的一部分,我为 android 尝试了以下技巧(java class 的方法):
实验#1
public class JniUtilities {
public static boolean isTablet(Context context) {
Log.d("INDENTIFICATOR >> ", "HEJJ, I AM CALLED!");
return ((context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE);
}
}
结果: 似乎工作正常,但不适用于其他操作系统:(
实验#2
让我们试试Qt Framework 工具。在这里,我可以了解具有 QScreen class
个实例的设备物理尺寸。作为 isTablet
的标准,我将使用 diagonal > 7.0 inches
.
qreal Utils::getDiagInch() {
QScreen *srn = qApp->screens().at(0);
qreal w = srn->physicalSize().width();
qreal h = srn->physicalSize().height();
qreal inches = qSqrt(w * w + h * h) / 25.4; // millimeters to inches
qDebug() << "physical diagonal >> " << inches;
return inches;
}
对于实验,我使用了 HTC ONE X
phone。
(qreal Utils::getDiagInch()): physical width >> 3.38583
(qreal Utils::getDiagInch()): physical height >> 6.02362
(qreal Utils::getDiagInch()): physical diagonal >> 6.90998
正如我们从官方制造商的属性中看到的那样,phone 有
width of 2.3 inches,
height of 4.1 inches and
diagonal of 4.7 inches
好的。有了不正确的值,我们无论如何得到了正确的结果:
HTC ONE X is PHONE as it has diagonal less than 7.0 inches.
结果: 该方法不可靠。
好的。另一个实验:
实验 #3
建议问题出在 Qt Framework 实现中,returning 值不正确。然后,如果我们询问 Android 显示物理尺寸的本机工具,它应该 return 不同的结果:
java-class:
public class MyActivityJo extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
double physWidth = metrics.widthPixels / metrics.xdpi;
Log.d("ph width >> ", Double.toString(physWidth));
double physHeight = metrics.heightPixels / metrics.ydpi;
Log.d("ph height >> ", Double.toString(physHeight));
double physDiag = Math.sqrt(physWidth * physWidth + physHeight * physHeight);
Log.d("ph diagonal >> ", Double.toString(physDiag));
}
}
输出:
D/ph width >> (27948): 3.380281686782837
D/ph height >> (27948): 6.009389877319336
D/ph diagonal >> (27948): 6.894858300184821
结果: DisplayMetrics return 的值也不正确。
总体
我试过很多 playmarket 应用程序。他们知道如何准确回答这个问题:没有一个应用检测错误 tablet/phone。他们是怎么做到的?他们使用本地工具吗?还是Qt Framework有通用的、非原生的方法明确解决问题??
如果一定要获取屏幕的dpi值,可以按照这个方法:
在.pro
android{
QT += androidextras
}
包括
#if defined(Q_OS_ANDROID)
#include <QAndroidJniObject>
#endif
代码:
qreal m_dpi;
qreal m_pixelRatio;
#if defined(Q_OS_ANDROID)
QAndroidJniObject qtActivity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
QAndroidJniObject resources = qtActivity.callObjectMethod("getResources","()Landroid/content/res/Resources;");
QAndroidJniObject displayMetrics = resources.callObjectMethod("getDisplayMetrics","()Landroid/util/DisplayMetrics;");
int density = displayMetrics.getField<int>("densityDpi");
m_dpi = density;
m_pixelRatio = 1;
#else
m_dpi = qApp->primaryScreen()->physicalDotsPerInch();
m_pixelRatio = qApp->primaryScreen()->devicePixelRatio();
#endif
获得 dpi 后,如果必须找到相对于参考设备的比例因子。
qreal m_dpiRef = 132; //reference device dpi (ipad);
double scalingFactor = 1;
if(m_dpi>0&&m_dpiRef >0)
scalingFactor=m_dpi/m_dpiRef;
物理尺寸:
width/m_dpi //should give the physical width of screen in inches.
要在 android 设备中检查设备是平板电脑还是移动设备,最小宽度为 600dp 的 mdpi(160 dpi) android 设备可被视为平板电脑(可能会因您的要求而异) ).
width*160/m_dpi >= 600 //to check if the screen size is large enough(tablet).
我已经验证了 Android 和 iOS 的代码。 您可能需要为 windows 使用以下代码。 (请验证)。
m_dpi = qApp->primaryScreen()->logicalDotsPerInch()*qApp->primaryScreen()->devicePixelRatio();