Обнаружение текущего устройства в универсальном приложении Windows

Я пробую выпущенное VS 2013 Update 2 и создаю образец универсального приложения.

Я создал пользовательский элемент управления и на обоих основных страницах добавил GridViews (в Windows Phone и Windows 8).

Я хочу изменить некоторые вещи с помощью кода, когда приложение работает на Windows Phone.

Есть ли способ сделать что-то вроде:

if(<deviceType> == "WindowsPhone")
{
}
else
{
}

person Cheese    schedule 24.04.2014    source источник


Ответы (6)


Обычно при создании приложения вы можете использовать директивы препроцессора. При создании приложения для Windows Phone VS по умолчанию определяет WINDOWS_PHONE_APP (посмотрите Свойства проекта -> Сборка -> Символы условной компиляции). Поэтому в любом месте вашего кода вы можете разместить такой оператор:

#if WINDOWS_PHONE_APP
    // do when this is compiled as Windows Phone App
#else
    // not for windows phoen
#endif

Дополнительную информацию вы можете получить в MSDN.

Я бы посоветовал использовать этот подход, поэтому в большинстве случаев вы точно знаете, когда будете использовать конкретный код для телефона (ARM) или другой платформы. Конечно, если вам нужно, вы можете определить больше символов для конкретных конфигураций/платформ сборки.

Примечания. Начиная с версии W10, где вам нужно проверять платформу в Run-Time, вы можете использовать класс ApiInformation и проверьте, существует ли определенный тип в API. Например вот так:

if (ApiInformation.IsApiContractPresent("Windows.Phone.PhoneContract", 1))
   // do code for mobile
else 
   // do code for other
person Romasz    schedule 24.04.2014
comment
Спасибо, это как раз то, что я искал! - person Cheese; 24.04.2014
comment
У вас есть пример использования этого класса ApiInformation? Таких пока не нашел... - person Spartacus Rocha; 06.04.2016
comment
@SpartacusRocha Взгляните другой ответ здесь, хотя лично я использую проверку для другого контракта. Тем не менее, поскольку пакеты создаются для конкретной платформы - я использую условные символы везде, где могу, тогда нет необходимости определять платформу во время выполнения. - person Romasz; 06.04.2016
comment
Обратите внимание, что наличие PhoneContract не доказывает, что это телефон — это просто доказывает, что API из этого контракта доступны. К счастью, никто не поставлял нетелефонные устройства с телефонным контрактом, но в целом это плохой способ проверить ситуацию. - person Peter Torr - MSFT; 26.09.2017
comment
@PeterTorr-MSFT Вы правы. Я бы все равно просто сделал другой пакет для конкретного устройства, контракт API в основном используется в некоторых редких случаях и только там, где мне нужен API, а не тип устройства. Знаете ли вы более простой/лучший способ получить тип устройства? - person Romasz; 26.09.2017
comment
Проблема в том, что вы имеете в виду под типом устройства? Телефон может работать как рабочий стол (Continuum). Рабочий стол может работать как планшет или как HoloLens (смешанная реальность). К сожалению, сейчас у нас нет хороших инструментов для обработки всех этих случаев :/. AnalyticsInfo — это лучшее приближение, которое у нас есть на сегодняшний день для мобильных устройств и ПК, но обычно вы хотите посмотреть на другие вещи, такие как размер экрана, подключена ли клавиатура и так далее. - person Peter Torr - MSFT; 26.09.2017
comment
@PeterTorr-MSFT Да, верно, в наши дни тип устройства, кажется, теряет значение. - person Romasz; 26.09.2017

Это то, что сработало для меня в проекте Universal Windows (Windows 10)

public static Platform DetectPlatform()
{
    bool isHardwareButtonsAPIPresent =
        ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons");

    if (isHardwareButtonsAPIPresent)
    {
        return Platform.WindowsPhone;
    }
    else
    {
        return Platform.Windows;
    }
}
person duo    schedule 02.09.2015
comment
идеальное решение для UWP - person Keval Langalia; 07.02.2016
comment
Обратите внимание, что наличие типа HardwareButtons не доказывает, что это телефон, а лишь доказывает, что тип HardwareButtons существует. До сих пор никто не поставлял устройства, не являющиеся телефонами, с этим API, но в целом это плохой способ проверки. - person Peter Torr - MSFT; 26.09.2017

Если вам нужен метод определения текущего устройства в коде, вы можете попробовать следующее:

public Windows.Foundation.Metadata.Platform DetectPlatform()
{
    try
    {
        //Calls an unsupported API.
        Windows.Networking.BackgroundTransfer.BackgroundDownloader.RequestUncontrainedDownloadsAsync(null);
    }
    catch (NotImplementedException)
    {
        //The API isn't supported on Windows Phone. Thus, the current platform is Windows Phone.
        return Windows.Foundation.Metadata.Platform.WindowsPhone;
    }
    catch(Exception)
    {
       //Otherwise, this is Windows (desktop/RT).
       return Windows.Foundation.Metadata.Platform.Windows;
    }
}

Источник: https://gist.github.com/Amrykid/2fd65ae1815a928fe753

person Amrykid    schedule 02.06.2014
comment
Использование исключений для управления потоком — плохая идея; есть лучшие способы сделать это. - person Peter Torr - MSFT; 26.09.2017

ИЛИ вы можете сделать это

Добавьте это в

App.Xaml.Cs

public static bool IsMobile
{
    get
    {
        var qualifiers = Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().QualifierValues;
        return (qualifiers.ContainsKey("DeviceFamily") && qualifiers["DeviceFamily"] == "Mobile");
    }
}
person Apoorv    schedule 05.04.2016
comment
Семейство устройств — хорошее приближение (не идеальное, но, как правило, лучшее, что вы можете сделать, если действительно хотите обнаружить мобильный телефон). Однако проще получить значение из AnalyticsInfo. - person Peter Torr - MSFT; 26.09.2017

Из GitHub

public static class DeviceTypeHelper
{
    public static DeviceFormFactorType GetDeviceFormFactorType()
    {
        switch (AnalyticsInfo.VersionInfo.DeviceFamily)
        {
            case "Windows.Mobile":
                return DeviceFormFactorType.Phone;
            case "Windows.Desktop":
                return UIViewSettings.GetForCurrentView().UserInteractionMode == UserInteractionMode.Mouse
                    ? DeviceFormFactorType.Desktop
                    : DeviceFormFactorType.Tablet;
            case "Windows.Universal":
                return DeviceFormFactorType.IoT;
            case "Windows.Team":
                return DeviceFormFactorType.SurfaceHub;
            default:
                return DeviceFormFactorType.Other;
        }
    }
}

public enum DeviceFormFactorType
{
    Phone,
    Desktop,
    Tablet,
    IoT,
    SurfaceHub,
    Other
}

https://gist.githubusercontent.com/wagonli/40d8a31bd0d6f0dd7a5d/raw/f6175de5fcad40cc257edc3748c0e349495d17f6/DeviceTypeHelper.cs

person Minute V    schedule 28.06.2018

Это обходной путь

       //PC customization
                if(ApiInformation.IsTypePresent("Windows.UI.ViewManagement.ApplicationView"))
                {
                }

                //Mobile customization
                if(ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
                {
                }
person Joe    schedule 12.04.2016
comment
Это очень плохой способ проверки, и он содержит ошибки — начиная с Windows 10, Класс ApplicationView доступен на всех платформах. Учитывая, что это тот же выпуск ОС, что и ApiInformation, этот код никогда не должен был работать. - person Peter Torr - MSFT; 26.09.2017