使用非本机工具在 Qt 中检测平板电脑或手机的正确方法
Posted
技术标签:
【中文标题】使用非本机工具在 Qt 中检测平板电脑或手机的正确方法【英文标题】:A proper way to detect Tablet or Mobile in Qt using non-native tools 【发布时间】:2015-07-03 09:18:19 【问题描述】:我有一个目的是确定我部署应用程序的平板电脑或移动设备。
当我在 ios、android、Linux 桌面和 Windows 上部署应用程序时,最好使用非本地工具。
但作为实验的一部分,我为 android 尝试了以下技巧(java 类的方法):
实验#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 框架工具。在这里,我可以了解具有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
电话。
(qreal Utils::getDiagInch()): physical width >> 3.38583
(qreal Utils::getDiagInch()): physical height >> 6.02362
(qreal Utils::getDiagInch()): physical diagonal >> 6.90998
从官方厂商的属性可以看出,这款手机有
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 实现中,返回不正确的值。那么如果我们向 Android 原生工具询问 Display physical size,它应该会返回不同的结果:
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 也会返回不正确的值。
总体
我尝试了许多 Playmarket 应用。他们知道如何准确回答这个问题:没有一个应用程序错误地检测平板电脑/手机。他们是怎么做到的?他们使用原生工具吗?还是 Qt 框架有通用的、非本地的方法来明确地解决这个问题??
【问题讨论】:
【参考方案1】:如果要获取屏幕的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.
要检查设备是平板电脑还是安卓设备中的移动设备,可以将最小宽度为 600dp 的 mdpi(160 dpi) 安卓设备视为平板电脑(可能会因您的要求而异)。
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();
【讨论】:
谢谢! 问题是: QScreen 评估 physicalSize() 不正确,因为 QScreen::physicalDotsPerInch() 返回错误值,但 DisplayMetrics:: densityDpi 返回正确的值。 HTC ONE X 的测试结果: QScreen::physicalDotsPerInch() : 212.574 ppi DisplayMetrics::densityDpi : 320 ppi 来自文档 : ~ 312 ppi以上是关于使用非本机工具在 Qt 中检测平板电脑或手机的正确方法的主要内容,如果未能解决你的问题,请参考以下文章