Reputation: 83
I have a purpose to determine tablet or mobile I deploy the application on.
As I deploy the app both iOS, Android, Linux Desktop and Windows, it is desirable to use non-native tools.
But as a part of experiment I tried the following trick for android (method of java class):
Experiment #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);
}
}
Result: It seems to work fine, but not applicable for other operating systems :(
Experiment #2
Let's try Qt Framework tools. Here I can learn device physical size having QScreen class
instance. As criteria of isTablet
I shall use condition of 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;
}
For experiment I used 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
As we can see from official manufacturer's properties, the phone has
width of 2.3 inches,
height of 4.1 inches and
diagonal of 4.7 inches
Okay. Having incorrect values, we, anyway, obtained the correct result:
HTC ONE X is PHONE as it has diagonal less than 7.0 inches.
Result: the METHOD is UNRELIABLE.
Okay. Another one experiment:
Experiment #3
Suggest that problem is in Qt Framework implementation, returning incorrect values. Then if we ask Android native tools for Display physical size, it should return a different result:
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));
}
}
output:
D/ph width >> (27948): 3.380281686782837
D/ph height >> (27948): 6.009389877319336
D/ph diagonal >> (27948): 6.894858300184821
Result: DisplayMetrics returns incorrect values, too.
OVERALL
I've tried many of playmarket apps. They know how to exactly answer the question: no one app was wrong detecting tablet/phone. How do they do that? Do they use native tools? Or there is universal, non-native method by Qt Framework to solve the issue unambiguously??
Upvotes: 2
Views: 1644
Reputation: 131
If you have to get dpi value of a screen, you can follow this method:
in .pro
android{
QT += androidextras
}
include
#if defined(Q_OS_ANDROID)
#include <QAndroidJniObject>
#endif
code:
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
once you get the dpi, if you have to find the scaling factor with respect to your reference device.
qreal m_dpiRef = 132; //reference device dpi (ipad);
double scalingFactor = 1;
if(m_dpi>0&&m_dpiRef >0)
scalingFactor=m_dpi/m_dpiRef;
physical size:
width/m_dpi //should give the physical width of screen in inches.
To check if the device is tablet or mobile in android devices, a mdpi(160 dpi) android device with 600dp minimum width can be considered a tablet (may vary depending upon your requirements).
width*160/m_dpi >= 600 //to check if the screen size is large enough(tablet).
I have verified the code for Android and iOS. You may have to use following code for windows. (Please verify).
m_dpi = qApp->primaryScreen()->logicalDotsPerInch()*qApp->primaryScreen()->devicePixelRatio();
Upvotes: 1