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, чтобы определить, работает ли ваше приложение на планшете или телефоне. Потому что указанные выше значения не являются универсальными. Это всего лишь игра в догадки.

Я удивлен, что это работает вообще в эмуляторе, где я ожидаю, что возвращаемые значения будут такими же, как на мониторе вашего компьютера, а не эквивалентны тому, каким должен быть смартфон.

Другие вопросы по тегам