Capabilities.screenDPI: правильно на эмуляторе, неправильно на устройстве
Я делаю свое приложение мультиэкранным (flex mobile). В основном я хочу знать, когда я имею дело с планшетом или смартфоном. Поэтому я хочу знать размер экрана в дюймах. Я тестирую это на Desire HD (4, 3 дюйма). Моя проблема: когда я использую Capabilities.screenDPI, эмулятор показывает правильное значение (217), однако, когда я запускаю его на моем устройстве, он дает мне неправильное значение DPI (240), ширина и высота правильные. Исходя из этого dpi я получаю неправильный размер экрана в дюймах (3.887"!= 4.3"). Опять на эмуляторе все работает нормально. Эмулятор устройства настроен с правильными значениями, только когда я запускаю его на реальном устройстве (без эмулятора), я получаю неправильное значение DPI.
Я рассчитываю это с помощью следующего фрагмента кода:
var screenX:Number = stage.stageWidth;
var screenY:Number = stage.stageHeight;
var pixels:Number = (screenX*screenX) + (screenY*screenY);
var screenSize:Number = Math.sqrt(pixels)/Capabilities.screenDPI;
return (screenSize >= 6) ? "tablet" : "phone"
Чтобы сэкономить немного времени, я приведу значения Desire HD:
480 x 800 пикселей, 4, 3 дюйма (плотность пикселей ~217 ppi)
Используемая формула проста: ~ Пифагор: a2 + b2 = c2 -> sqrt(c)/dpi = размер экрана в дюймах.
На основе Adobe, значение DPI или PPI может использоваться "взаимозаменяемо". ( Adobe, Справка). Я не нашел никакой информации, где значение dpi отличается от значения ppi или где есть возможность использовать свойство ppi в flex.
Итак, на моем реальном устройстве я получаю:
480 x 800 пикселей, 3,89" (~240 точек на дюйм).
Еще одно замечание: я видел, что в flex mobile есть 3 константы по умолчанию. Может ли быть так, что его прямо бросают в один из них? (Я не подозреваю, так как я вызываю Capabilities.screenDPI напрямую).
DPIClassification.DPI_160
DPIClassification.DPI_240
DPIClassification.DPI_320
Что я имею в виду: Как я могу определить, планшет это или телефон (чтобы переключиться на другую раскладку)? Вы не можете следовать applicationDPI
дорога, так как все это перепутано с новыми устройствами, такими как Samsung Galaxy S3 (1280x720, 319 PPI) или Apple iPad 3 (2048×1536, 264 PPI).
4 ответа
Для определения размера экрана в режиме эмулятора вы можете использовать объект SystemManager следующим образом:
var root:DisplayObject = SystemManager.getSWFRoot(this); // this is any object of the application not only display object
screenX = root.stage.fullScreenWidth;
screenY = root.stage.fullScreenHeight;
Я знаю, что это старая ветка, но я подумал, что вы, ребята, захотите узнать, как я справился с этим - наконец-то я исправил это с моей стороны.
protected function resizeHandler(event:ResizeEvent):void
{
var screenX:Number = Capabilities.screenResolutionX;
var screenY:Number = Capabilities.screenResolutionY;
var osType:String = Capabilities.os;
var limitNumber:Number = 960;
var pixelCheck:Number = screenX * screenY;
var pixels:Number = (screenX*screenX) + (screenY*screenY);
var screenSize:Number = Math.sqrt(pixels)/Capabilities.screenDPI;
isPortrait = height > width;
//isTablet = screenX > limitNumber || screenY > limitNumber;
isTablet = screenSize >= 6;
var isDesktop:Boolean = height > limitNumber || width > limitNumber;
if (osType.toUpperCase() == "WINDOWS 7"){
this.currentState = (isPortrait ? "portrait" : "landscape") + (isDesktop ? "Tablet" : "Phone");
}else {
this.currentState = (isPortrait ? "portrait" : "landscape") + (isTablet ? "Tablet" : "Phone");
}
//DEBUGGING CODE BELOW
debugger.text = "screen X: " + screenX.toString() + " screen Y: " + screenY.toString() + "\n pixels: " + pixels.toString() + "\n screenSize: " + screenSize.toString() + "\n capabilities.screenDPI: " + Capabilities.screenDPI.toString() + "\n current state: " + this.currentState + /*"\n IsDesktop: " + isDesktop.toString() + */ " IsTablet: " + isTablet.toString() + "\n OS Type" + osType;
//currentState = (isPortrait ? "portrait" : "landscape") + (isTablet ? "Tablet" : "Phone");
}
Как видно из приведенного выше кода, я работаю в двух разных ситуациях. 1 - когда я использую эмулятор на своем локальном ПК, система всегда думает, что я в режиме планшета (потому что он возвращает очень большие значения для экранов моего монитора X и значений Y экрана). Поэтому я справляюсь с этим с помощью флага isDesktop.
Затем я использую значение размера экрана, чтобы дать мне планшет против телефона. В настоящее время (февраль 2013 г.) нет планшетов в возрасте до 6 лет по размеру экрана и нет телефонов выше него.
Вы можете попробовать что-то вроде
var isItATablet:Boolean = screenHeight > 960 || screenWidth > 960;
var isItReallyATablet:Boolean = isTablet && screenDPI >= 240; // I think this doesn't work as is, but you get the idea..
Таким образом, вы получите, если высота или ширина экрана больше 960 пикселей, а DPI низок, вероятно, вы находитесь на планшете.
Это не на 100% точно, я не проверял его, но на 2 устройствах, это просто вопрос попробовать разные устройства и посмотреть, угадывает ли тип устройства в большинстве случаев
Свойство Flex applicationDPI вернет либо 160 (для большинства планшетов), 240 (для большинства смартфонов) и 320 для iPhone 4/4S.
Это то, что происходит под капотом, чтобы облегчить жизнь разработчикам. Все, что построено для определенного DPI устройства, может быть не очень расширяемым для других устройств / платформ. Я думал, что applicationDPI в одном из этих трех значений - это вещь Flex, но вполне возможно, что Flex просто наследует его от AIR.
В конце концов, я не думаю, что вы можете использовать значение DPI, чтобы определить, работает ли ваше приложение на планшете или телефоне. Потому что указанные выше значения не являются универсальными. Это всего лишь игра в догадки.
Я удивлен, что это работает вообще в эмуляторе, где я ожидаю, что возвращаемые значения будут такими же, как на мониторе вашего компьютера, а не эквивалентны тому, каким должен быть смартфон.