使用非本机工具在 Qt 中检测平板电脑或手机的正确方法

Posted

技术标签:

【中文标题】使用非本机工具在 Qt 中检测平板电脑或手机的正确方法【英文标题】:A proper way to detect Tablet or Mobile in Qt using non-native tools 【发布时间】:2015-07-03 09:18:19 【问题描述】:

我有一个目的是确定我部署应用程序的平板电脑或移动设备。

当我在 iosandroid、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 中检测平板电脑或手机的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

配置adb环境与简单命令

本机应用工具的 Windows 检测分析

本机系统升级的步骤

Qt Quick 2 应用程序中的非本机对话框

在Qt中不同手机上创建文件

在 Symbian/Qt 中检测手机方向变化的问题