Блог Сергея Байдачного

Мой блог о технологиях

Archive for Январь 2012

Imagine Cup 2012: Как принять участие в Windows 8 номинации

with one comment

Получаю слишком много вопросов по регистрации на сайте http://imaginecup.com, особенно в Metro-style app номинации.

Поскольку сегодня первый из 6-ти квизов, позволяющих выйти Вашей команде во второй раунд, решил пройти весь процесс самостоятельно и написать об этом статью.

Итак, первое, что необходимо сделать, это пойти на сайт конкурса http://imaginecup.com и нажать кнопку регистрации:

clip_image001

Тут все достаточно просто. Вам нужно выбрать имя пользователя, ввести email, язык и другую информацию. Вопрос, который возникает у студентов, что вводить в поле Attending School. Вводить нужно YES! Под школой понимаются и университетыJ No нужно выбирать только для менторов. Если Вам кто-то рассказал про конкурс, то можете ввести его имя и фамилию в поле Referral Code, но это актуально только в том случае, если рекомендацию Вам дал студент-партнер:

clip_image003

Завершаем заполнять формочку, соглашаясь с условиями и нажимаем кнопку Register:

clip_image005

Если Вы уже принимали участие в Imagine Cup (в предыдущие годы), то получите сообщение, похожее на это:

clip_image007

Это означает, что Ваш аккаунт уже существует. Поэтому нужно пойти в свой почтовый ящик, и посмотреть письмо, которое приходит сразу же после попытки зарегистрироваться. В письме есть специальная ссылка, которая позволяет задать Вам новый пароль для своего старого аккаунта.

Если Вы регистрируетесь впервые, то тут же попадаете на страницу со своим профилем.

Тут нужно заполнить все обязательные поля, включая номинации, в которых Вы хотите участвовать. Отметив все галочки и введя персональную информацию, нажимаем Update Profile:

clip_image008

Переходим к странице номинации непосредственно:

clip_image009

Если, по каким-то причинам, Вы не выбрали нужную номинацию, то на правой панели сможете нажать кнопку Sign Up, которая снова переведет Вас на Профиль:

clip_image010

В случае успешной регистрации, Вы можете приступать к участию в конкурсе.

Обращаю Ваше внимание на то, что конкурс командный. В команде может быть от одного до 4-х человек. Также может присутствовать ментор (наставник), которого обцычно выбирают из числа преподавателей ВУЗа. Поэтому нажимаем на панели справа (на странице номинации) кнопку Create a Team:

clip_image011

На странице, позволяющей создать команду, Вы вводите название команды, а также высылаете приглашение потенциальным участникам Вашей команды. Команду создает один из участников, а остальные лишь принимают приглашение.

Наставник (ментор) не может создавать команду. Его задача зарегистрироваться и принять приглашение.

Для поиска участников, Вы можете воспользоваться кнопкой поиска, расположенной рядом с полем ввода. Обращаю внимание на то, что поиск будет происходить лишь среди участников, которые отметили соответствующую номинацию в своем профиле:

clip_image013

Создав команду, Вы можете перейти на страницу номинации и нажать кнопку Compete для прохождения первого опросника:

clip_image014

Данная кнопка активна только во время одного из 6-ти опросников, которые проходят 31 января, 7 февраля, 14 февраля, 21 февраля, 28 февраля и 8 марта.

Обращаю Ваше внимание, что на вопросы можно отвечать как всей команде вместе, так и каждому участнику отдельно. Если используется второй вариант, то выбирается максимальный балл, как балл команды.

Чтобы пройти во второй раунд, нужно ответить на 15 и более вопросов из 30. На ответы дается час времени.

Written by Sergiy Baydachnyy

31.01.2012 at 11:49

Опубликовано в Imagine Cup

Tagged with

Windows 8 уже на Imagine Cup

2 комментария

Сегодня были анонсированы две новые номинации в рамках международного IT конкурса для студентов Imagine Cup 2012, это Kinect Fun Labs и Windows Metro Style App.

Особый интерес представляет вторая номинация, которая связана с Windows 8 и легко может быть освоена украинскими студентами. Номинация состоит из двух раундов и позволяет принимать участие как одному студенту, так и команде, вплоть до 4-х человек. При этом в команду может быть приглашен и ментор.

Номинация состоит из двух раундов.

В раунде 1 студенты (команда) должны пройти опрос, состоящий из 30 вопросов, который позволяет протестировать базовые знания команды в области создания Metro приложений. При этом, опрос может проходить как вся команда вместе, так и каждый член команды отдельно. Во втором случае, балл команды вычисляется как максимальный бал среди всех участников команды. Обращаю Ваше внимание на то, что даты опросов фиксированные и команда может попробовать улучшить свой результат в любом из раундов (если в предыдущем не добрала баллов). Даты опросов: 31 января, 7 февраля, 14 февраля, 21 февраля, 28 февраля и 8 марта. Рекомендую попробовать свои силы в одном из ближайших опросов.

Все, кто прошел в раунд 2, начинают работать над собственным приложением для Windows 8 в стиле Metro. Чтобы успешно пройти раунд 2, необходимо на сайт конкурса загрузить описание Вашего приложения и видеоролик работающего приложения.

Победители (три команды) будут приглашены в Сидней для демонстрации своих приложений и получат денежные призы.

Обращаю Ваше внимание на то, что команды финалисты будут приглашены в Сидней вместе с их ментором (естественно, за деньги Microsoft).

Written by Sergiy Baydachnyy

20.01.2012 at 09:17

Опубликовано в Imagine Cup, Windows 8

Tagged with ,

Бесплатная публикация приложений под Windows Phone для студентов

2 комментария

Компания SoftKey, являющаяся официальным паблишером приложений под Windows Phone для украинских разработчиков, поделилась замечательной новостью: все студенты, желающие опубликовать свои приложения в Windows Phone Marketplace, смогут сделать это совершенно бесплатно. При этом речь идет как о платных (такая возможность уже была), так и о бесплатных приложениях. Для осуществления публикации необходимо зарегистрироваться на сайте http://winphone.softkey.ru/ и выслать копию студенческого. Обращаю Ваше внимание на то, что заполнять контракты на десятки листов и отправлять их в Москву почтой, больше не нужно!

Благодаря упрощенной процедуре (лишь регистрация и копия студенческого), Ваше приложение может быть отправлено на сертификацию в течении 1-2 дней после регистрации на сайте SoftKey.

Данное предложение действует лишь для украинских разработчиков и на сайте еще не отражено, но публиковать можно уже сегодня. Просто следуйте моим инструкциям. Хотя официальное подтверждение уже есть тут: http://www.softkey.ua/news_detail.php?ID=12964.

Напоминаю, что если Вы хотите разблокировать телефон для разработки, то можно воспользоваться следующей процедурой.

Written by Sergiy Baydachnyy

18.01.2012 at 09:37

Опубликовано в Windows Phone

Tagged with

Контакты и календарь в Windows Phone 7.5

2 комментария

Продолжаю рассказывать про возможности интеграции приложений с Windows Phone 7.5. На этот раз поговорим о календаре и контактах, а именно, о чтении информации из списка контактов и календаря. Если Вы решили сохранить контакт, то тут можно использовать класс SaveContactTask, который позволит инициировать вызов стандартного приложения.

Итак, как я писал ранее, чтобы получить доступ к данным пользователя, необходимо явно запросить это разрешение либо в начале приложения, либо перед самим доступом к данным. При этом должен быть механизм, позволяющий пользователю запретить доступ. В дополнении к этому, манифест приложения должен декларировать следующие возможности: ID_CAP_CONTACTS – для контактов, ID_CAP_APPOINTMENTS – для календаря.

Прописав все возможности и получив доступ со стороны пользователя можно перейти к работе с контактами и календарем. Все необходимые классы содержаться в пространстве имен Microsoft.Phone.UserData. По большому счету тут два основных класса, это Contacts и Appointments. Именно с них начинается работа. Так, необходимо создать объекты необходимых классов, определить обработчики события SearchCompleted и запустить процедуру выбора контактов с помощью метода SearchAsync. С помощью последнего, запускается механизм поиска, заложенный внутри платформы, и разработчик получает доступ к результирующим данным.

Если говорить о параметрах метода SearchAsync, то в случае календаря, это параметры типа DateTime, которые задают промежуток времени, за который нужно выбрать записи. Третий параметр позволяет передать произвольный объект, который будет переброшен обработчику события SearchCompleted. Этот объект можно использовать на свое усмотрение, например, идентифицировать результат запроса по имени (если у Вас много запросов).

В случае контактов, метод SearchAsync также принимает три параметра. Третий параметр также представляет собой произвольный объект, а вот первый и второй – позволяют задать критерии поиска в списке контактов. Так, первый параметр задает строку для поиска (если она не нужна, то можно указать String.Empty), а второй – тип поиска. Тип поиска представляет собой объект перечислимого типа, принимающего одно из значений:

· None – возвращает все контакты;

· PinnedToStart – возвращает все контакты, привязанные к основному окну телефона;

· EmailAddresses – позволяет выполнять фильтрацию по Email адресам;

· PhoneNumber – позволяет выполнять фильтрацию по номерам телефонов;

· DisplayName – позволяет выполнять фильтрацию по имени контакта.

Естественно, что полученные результаты (в виде списка объектов Contact или Appointment) можно обрабатывать дополнительно, используя LINQ или простой перебор.

Таким образом, работа с контактами и календарем не представляет сложности. Вот пример кода, который может выбирать контакты и записи из календаря, задавая фильтры:

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    Microsoft.Phone.UserData.Contacts conts = 
         new Microsoft.Phone.UserData.Contacts();
    Appointments apps = new Appointments();

    conts.SearchCompleted += 
         new EventHandler<ContactsSearchEventArgs>(conts_SearchCompleted);
    conts.SearchAsync("B", FilterKind.DisplayName, "My Search 1");

    apps.SearchCompleted += 
         new EventHandler<AppointmentsSearchEventArgs>(apps_SearchCompleted);
    apps.SearchAsync(DateTime.Now, DateTime.Now.AddDays(7), "My Search 2");

}

void apps_SearchCompleted(object sender, AppointmentsSearchEventArgs e)
{
    try
    {
        appsList.ItemsSource = e.Results;
    }
    catch
    {

    }
}

void conts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
    try
    {
        contsList.ItemsSource = e.Results;
    }
    catch
    {

    }
}

 

В заключении отмечу, что классы Contacts и Appointments имеют свойство Accounts, позволяющее определить доступные источники данных (напомню, что WP 7 может объединять данные из таких источников как Exchange, Facebook, Live и др). Выбирая конкретный контакт или запись в календаре, разработчик получает доступ к аналогичному свойству, позволяющему определить источник данных для конкретного контакта или записи в календаре (кстати, источников может быть несколько).

Written by Sergiy Baydachnyy

08.01.2012 at 10:40

Опубликовано в Windows Phone

Tagged with

Соблюдение политики конфиденциальности при публикации WP 7 приложений

2 комментария

Логично, что при попытке использовать камеру, микрофон, Location API и механизмы по доступу к контактам, разработчик должен запросить разрешение у пользователя. При этом, многие политики (например, для приложений, использующих Location API), отображаются еще на этапе установки приложения. Но независимо от того, что отобразил Marketplace, функционал, запрашивающий у пользователя информацию, должен быть реализован внутри приложения.

В зависимости от типа приложения, запросить права на доступ к тем или иным данным можно по-разному. Например, если пользователь создает запись, к которой могут быть привязаны текущие GPS координаты пользователя, то в форме создания записи достаточно поставить галочку «Добавить к записи мое местоположение» (или как-то так). В этом случае разрешение, которое дает пользователь, тесно интегрировано в интерфейс приложения и не отвлекает внимание пользователя всякими всплывающими окнами.

Но если GPS данные используются в главном окне приложения и в зависимости от них формируется интерфейс, то запросить разрешение у пользователя нужно с помощью отдельного окна, которое отобразиться перед формированием основного окна приложения. При этом, если пользователь согласился на определение своего местоположения, то в настройках приложения должен быть функционал, отключающий это разрешение. В противном случае приложение не будет сертифицировано.

Обращаю Ваше внимание на то, что «индусы», проверяющие приложения, не всегда понимают, используется ли местоположение на том или другом экране. Например, мы публиковали приложение, которое отображает записи на карте, сделанные в привязке к GPS. При этом в главном окне отображалась карта, которая использовала уже сохраненные пользователем данные (на что было получено разрешение при создании соответствующих записей) и никоем образом не требовала определения новых GPS данных на основном экране. «Индусы» не разобрались и вернули приложение. В этом случае нужно отправить приложение на повторную сертификацию, «разжевав» работу Вашего приложения в специальном поле Developer’s Notes, присутствующем при публикации приложения в интерфейсе Marketplace. Ведь тестируется интерфейс, а не код вашего приложения и информации не всегда достаточно.

Но описанная мной выше ситуация понятна и предсказуема. Но существует еще одна причина, по которой Ваше приложение может не пройти сертификацию. Дословно это может звучать так: Your application failed the Marketplace prohibited application policy check. При этом комментариев к подобной ошибке всегда минимум. Оказывается, чтобы решить это проблему с сертификацией, достаточно внутри Вашего приложения разместить произвольный текст (абсолютно авторский), который будет доступно рассказывать пользователю, чего будет происходить с его контактами, GPS положением и т .д. Текст может располагаться в том же окне, где пользователь дает свое разрешение или Вы можете разместить ссылку на другую страницу или даже адрес в Интернет, где будет опубликован Ваш текст. Вот этот текст и будет являться необходимой политикой конфиденциальности.

Быстрой публикации Вам.

Written by Sergiy Baydachnyy

07.01.2012 at 17:30

Опубликовано в Windows Phone

Tagged with

Сохранение рингтонов из приложения в WP 7.5

leave a comment »

 

Один из популярных способов заработать деньги на пользователях устройств, это продавать уникальные мелодии звонков для их телефонов. Этот бизнес настолько развит в Украине, что реклама соответствующих служб присутствует и на центральных каналах телевидения. Правда, чтобы заниматься подобным бизнесом, необходимо договориться с мобильным оператором, получить короткий номер и решить много других вопросов.

Но если мы говорим о Windows Phone 7.5, то реализовать подобный бизнес тут значительно проще, так как в обновлении платформы появилась возможность устанавливать мелодию звонка из приложения. Это делается с помощью класса SaveRingtoneTask, который инициирует вызов стандартного Windows Phone приложения, позволяющего как сохранить мелодию в общем списке, так и установить мелодию конкретному контакту.

Прежде чем переходить к реализации примера, следует отметить, что в Windows Phone 7.5 присутствуют следующие ограничения на мелодии звонка:

· Мелодия должна быть сохранена в виде mp3 или wma формата;

· Размер файла должен быть менее 1 Мб;

· Продолжительность аудио должна быть менее 40 секунд;

· Файл не должен быть защищен DRM.

Если все эти условия выполнены, то мелодия может быть установлена.

Посмотрим на то, что должен обычный пользователь сделать, чтобы сохранить мелодию звонка на свой телефон. Итак, если Вы обычный пользователь и у Вас есть mp3 (кстати, его нужно еще найти), который Вы хотите загрузить в телефон, то нужно выполнить следующие действия:

1). Преобразовать mp3 файл таким образом, чтобы он удовлетворял критериям выше. Это можно сделать с помощью Expression Encoder или другого аналогичного приложения. Естественно, пользователь ничего о подобных приложениях не знает (как и об ограничениях);

2). Как только у пользователя есть готовый mp3 или wma, то его необходимо синхронизировать с телефоном. Для этого файл добавляется в коллекцию с музыкой, доступной через Zune, после чего необходимо перейти к редактированию файла и установить свойство Genre в значение ringtone (если файл не удовлетворяет критериям, то его тип поменять нельзя).

image

3). Подключить телефон к компьютеру и синхронизировать созданную мелодию с телефоном.

Как видите, задача не тривиальная и вряд ли под силу простому пользователю. Но это означает, что приложения по установке мелодий будут не только популярны, но и позволят заработатьJ

А вот теперь приведем код примера. Начнем с интерфейса:

 

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
        <TextBlock x:Name="ApplicationTitle" Text="Ringtone Sample" 
             Style="{StaticResource PhoneTextNormalStyle}"/>
        <TextBlock x:Name="PageTitle" Text="Ringtones" Margin="9,-7,0,0" 
             Style="{StaticResource PhoneTextTitle1Style}"/>
        <MediaElement Name="mp"></MediaElement>
    </StackPanel>

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <ListBox Name="ringList">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock FontSize="32" Text="{Binding RingtoneName}"></TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Grid>

<phone:PhoneApplicationPage.ApplicationBar>
    <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
        <shell:ApplicationBarIconButton IconUri="/Images/appbar.check.rest.png" 
             Text="Ringtone" Click="ApplicationBarIconButton_SetRing_Click"/>
        <shell:ApplicationBarIconButton IconUri="/Images/appbar.transport.play.rest.png" 
             Text="Play" Click="ApplicationBarIconButton_Ringtone_Click"/>
    </shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>

 

Тут мы добавили список, который будет отображать доступные мелодии. Тут можно ввести такие поля, как описание, автор категория и др., но это Вы сделаете сами. Далее в приложении присутствует ApplicationBar, который содержит две кнопки. Первая кнопка позволяет установить выделенную мелодию в качестве звонка телефона, а вторая – проиграть мелодию прямо в приложении. Чтобы иметь возможность проиграть мелодию, мы также разместили MediaElement. В нашем случае он не имеет визуального отображения.

Определим класс, который будет хранить информацию о мелодиях:

 

public class RingtoneItem
{
    public string RingtoneName { get; set; }
    public string RingtonePath { get; set; }
}

 

А теперь перейдем к коду.

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

Во второй части приложения мы обрабатываем событие нажатия на кнопки в Application Bar и проигрываем мелодию, либо вызываем метод Show объекта типа SaveRingtoneTask. Обратите внимание, что при передаче параметра этому объекту, правило формирования Uri отличается от принятого внутри приложения. Чтобы Uri смог быть разобран внешним приложением, его необходимо формировать с помощью приставки appdata: или isostore:, в зависимости от того, где находится Ваш файл с мелодией (внутри приложения или загружен в IsolatedStorage).

Вот полный код основной страницы:

SaveRingtoneTask saveRing;
List<RingtoneItem> list = new List<RingtoneItem>();

public MainPage()
{
    InitializeComponent();

    saveRing = new SaveRingtoneTask();
    saveRing.Completed += 
         new EventHandler<TaskEventArgs>(saveRing_Completed);

    list.Add(new RingtoneItem() { 
         RingtoneName="Mission Impossible",
         RingtonePath="/Ringtones/mission.wma"});
    list.Add(new RingtoneItem() { 
         RingtoneName = "Va Bank", 
         RingtonePath ="/Ringtones/vabank.wma" });

    ringList.ItemsSource = list;

}

void saveRing_Completed(object sender, TaskEventArgs e)
{
    string statusText="";
    if (e.TaskResult == TaskResult.OK)
    {
        statusText = "Save completed.";
    }
    else if (e.TaskResult == TaskResult.Cancel)
    {
        statusText = "Save cancelled.";
    }
    MessageBox.Show(statusText);
}

private void ApplicationBarIconButton_Ringtone_Click(object sender, EventArgs e)
{
    if (ringList.SelectedIndex >= 0)
    {
        mp.Source = 
           new Uri(((RingtoneItem)ringList.SelectedItem).RingtonePath, 
                     UriKind.Relative);
        mp.Play();
    }
}


private void ApplicationBarIconButton_SetRing_Click(object sender, EventArgs e)
{
    if (ringList.SelectedIndex >= 0)
    {
        saveRing.Source = new Uri(
             "appdata:"+((RingtoneItem)ringList.SelectedItem).RingtonePath);
        saveRing.Show();
    }
}

Written by Sergiy Baydachnyy

05.01.2012 at 15:10

Опубликовано в Windows Phone

Tagged with

Информация об устройстве и сети в Windows Phone 7.5

with one comment

Еще одно нововведение в Windows Phone 7.5, это возможность определить информацию о возможном подключении к сети, а также параметры самого устройства. Тут можно выделить два класса с большим количеством статических методов и свойств.

Первый класс DeviceNetworkInformation, который находится в пространстве имен Microsoft.Phone.Net.NetworkInformation, поддерживает следующие свойства:

· CelluralMobileOperator – позволяет вернуть имя мобильного оператора (только строку);

· IsCelluralDataEnabled – возвращает true, если активирована передача данных через сеть оператора;

· IsNetworkAvailable – возвращает true, если имеется хоть какой-то доступ к сети;

· IsWiFiEnabled – возвращает true, если на телефоне активирована возможность подключения к WiFi;

· IsCelluralDataRoumingEnabled – позволяет проверить, включен ли на телефоне роуминг для передачи данных через сеть мобильного оператора.

Как видно, методы выше достаточно примитивны и не отвечают на вопрос, есть ли доступ в данный момент через WiFi или передача ведется через мобильного оператора. Ведь включение на телефоне WiFi не гарантирует его наличие. Иными словами, назначение этих свойств исключительно информационное, позволяющее сделать интерфейс приложения более дружественным для пользователя.

Если Вы все же хотите получать информацию об изменениях в соединении и определять тип соединения, то Вам поможет статическое событие класса DeviceNetworkInformation. Это событие NetworkAvailabilityChanged, передающее обработчику в качестве параметров объект типа NetworkInterfaceInfo, который содержит всю возможную информацию о текущем подключении. Кстати, чтобы получить информацию о всех возможных подключениях, можно воспользоваться классом NetworkInterfaceList, а текущее подключение можно получить через класс NetworkInterface. Но, в отличии от класса DeviceNetworkInformation, перечисленные выше классы были и в версии 7.0.

Второй класс, из рассматриваемых нами, это DeviceStatus, позволяющий определить множество интересных параметров, связанных с устройством. Тут присутствуют следующие статические свойства:

· ApplicationCurrentMemoryUsage – позволяет определить, сколько памяти использует приложение в данный момент;

· ApplicationMemoryUsageLimit – возвращает количество памяти, которое может быть (всего) использовано приложением;

· ApplicationPeakMemoryUsage – позволяет вернуть пиковое значение памяти, которая была использована в ходе работы приложения;

· DeviceFirmwareVersion – определяет версию прошивки;

· DeviceHardwareVersion – определяет версию аппаратного обеспечения (устройства);

· DeviceManufacturer – возвращает имя производителя устройства;

· DeviceName – возвращает имя устройства;

· DeviceTotalMemory – возвращает общее количество памяти;

· IsKeyboardDeployed – позволяет проверить, готово ли клавиатура к использованию (например, выдвинута из телефона);

· IsKeyboardPresent – определяет наличие клавиатуры;

· PowerSource – определяет, использует ли устройство батарею или подключено к сети.

Как видно, тут можно получить много полезной информации, которую использовать не только во время работы пользователя с приложением, но и во время тестирования.

Кроме перечисленных статических свойств, класс DeviceStatus содержит два статических события, позволяющих определять изменения, связанные с клавиатурой и источником энергии. Первое событие KeyboardDeployedChanged, а второе – PowerSourceChanged.

Written by Sergiy Baydachnyy

03.01.2012 at 09:26

Опубликовано в Windows Phone

Tagged with

Интеграция с камерой

leave a comment »

 

В первой версии Windows Phone (7) разработчик имел очень ограниченный доступ к камере. Фактически вся работа сводилась к вызову стандартного приложения по работе с камерой с помощью класса CameraCaptureTask. Объекты этого класса обладают методом Show, способным инициировать стандартное приложение по работе с камерой (и деактивировать Ваше), а с помощью обработчика события Completed можно было получить отснятое изображение. Подобный подход хорош, если Вам не нужна тесная интеграция с камерой и не хочется делать дополнительную работу.

А вот в Windows Phone 7.5 разработчик получил значительно больше возможностей. При этом слово «больше» явно преуменьшает тот набор функциональности, который можно использовать сегодня. По большому счету Вы можете без труда написать собственное приложение по работе с камерой, позволяя пользователю устанавливать различные настройки. При этом речь идет как о создании фотографий, так и о полном доступе к данным, поступающим на камеру. Давайте рассмотрим новые механизмы более детально.

Начнем с того, что для использования камеры в своем приложении необходимо обязательно задекларировать такую возможность. Это делается с помощью Capability элемента с именем ID_CAP_ISV_CAMERA, который прописывается в манифесте приложения (WMAppManifest.xml). При этом данная декларация позволяет использовать как стандартную, так и фронтальную (лицевую) камеру (по выбору пользователя через интерфейс приложения). Декларация прописана по умолчанию в шаблоне проекта Visual Studio, поэтому Вам вряд ли нужно будет выполнять этот шаг. Но если Вы решили использовать именно фронтальную камеру, так как именно с помощью нее можно выполнить некоторые функции Вашего приложения, то необходимо задекларировать еще одну возможность, с именем ID_HW_FRONTCAMERA. При этом нужно помнить, что не все телефоны оснащены лицевой камерой. Последняя возможность не декларируется по умолчанию, поэтому ее потребуется прописать явно.

Теперь необходимо определиться, какое приложение Вы хотите реализовать. Дело в том, что в Windows Phone 7.5 появилось сразу два API по работе с камерой. Первое API является частью платформы Windows Phone и позволяет реализовать приложение по съемке фотографий. Второе API является частью SilverLight 4 и позволяет обрабатывать весь аудио и видео поток, поступающий на камеру. Преимущество первого API – возможность обрабатывать события, связанные с фокусом, вспышкой и другими элементами телефона. Преимущество Silverlight API – его универсальность. В любом случае оба API можно комбинировать.

Начнем наш обзор с Windows Phone API. Тут выделяют три основных класса: PhotoCamera, PictureDecoder, Extentions. Основную работу выполняет первый класс. А вот два других являются вспомогательными и позволяют преобразовать объект типа WriteableBitmap в JPEG и наоборот. Фактически второй и третий классы реализуют мостик между Silverlight и объектом типа PhotoCamera. При этом, Silverlight 4 не поддерживал стандартных механизмов преобразования BMP изображений в JPEG, что затрудняло работу разработчиков при создании веб-приложений. Но телефон ведь не только позволяет снимать изображение с камеры, но и преобразовывать его в JPEG. Именно поэтому такая возможность стала доступна и разработчику, как открытый API уже существующих в устройстве возможностей.

Не буду детально останавливаться на PictureDecoder и Extensions, а лишь отмечу, что первый класс обладает двумя статическими методами, позволяющими получить готовый WriteableBitmap, получив в качестве параметров ссылку на поток с файлом JPEG. А вот второй класс является расширителем класса WriteableBitmap и позволяет добавить в интерфейс последнего два метода (LoadJpeg и SaveJpeg). Иными словами Вы можете использовать эти методы, как методы экземпляров типа WriteableBitmap.

Теперь перейдем к основному классу – PhotoCamera. Тут есть два небольших правила-рекомендации. Объект типа PhotoCamera правильно создавать и инициализировать внутри перегруженного метода OnNavigatedTo. Уничтожать данный объект следует внутри метода OnNavigatingFrom. Это позволит гарантировать, что все ресурсы будут освобождены своевременно, если приложение поддерживает навигацию на другие страницы. Создание самого объекта типа PhotoCamera не вызывает затруднений – тут присутствует конструктор без параметров, а также конструктор, который принимает тип камеры (обычная или фронтальная).

Я не смог найти ни одного устройства с фронтальной камерой в своих запасниках, поэтому не смог проверить, можно ли получать изображение с обеих камер одновременно. Но если можно, то это позволит создать много интересных приложений. Фронтальную камеру сегодня поддерживает HTC Titan, HTC Radar и Samsung I8350. Если у Вас одно из этих устройств, попробуйте проверить и написать.

Итак, создав объект типа PhotoCamera, следует определить необходимые в приложении события, ассоциированные с этим объектом и задать свойства. Я не буду перечислять основные свойства и события, а просто приведу небольшой пример.

В шаблонный xaml, внутрь элемента Grid с именем ContentPanel, добавим код:

 

   1:   <StackPanel>
   2:       <Rectangle Height="400" Width="400" Margin="12,17,0,0" Name="videoRect" />
   3:   </StackPanel>

 

В файл с кодом добавим следующий текст:

 

   1:  PhotoCamera camera;
   2:  MediaLibrary library;
   3:   
   4:  protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
   5:  {
   6:      if (PhotoCamera.IsCameraTypeSupported(CameraType.Primary))
   7:      {
   8:          camera = new PhotoCamera(CameraType.Primary);
   9:   
  10:          videoRect.Fill = new VideoBrush();
  11:          ((VideoBrush)videoRect.Fill).SetSource(camera);
  12:          library = new MediaLibrary();
  13:   
  14:          CameraButtons.ShutterKeyHalfPressed += 
  15:  new EventHandler(CameraButtons_ShutterKeyHalfPressed);
  16:          CameraButtons.ShutterKeyPressed += 
  17:  new EventHandler(CameraButtons_ShutterKeyPressed);
  18:          camera.CaptureImageAvailable += 
  19:  new EventHandler<ContentReadyEventArgs>(camera_CaptureImageAvailable);
  20:      }
  21:  }
  22:   
  23:  void camera_CaptureImageAvailable(object sender, ContentReadyEventArgs e)
  24:  {
  25:      string fileName = Guid.NewGuid().ToString() + ".jpg";
  26:      library.SavePictureToCameraRoll(fileName, e.ImageStream);
  27:      Deployment.Current.Dispatcher.BeginInvoke(delegate()
  28:      {
  29:          MessageBox.Show("Image saved");
  30:      });
  31:  }
  32:   
  33:  void CameraButtons_ShutterKeyPressed(object sender, EventArgs e)
  34:  {
  35:      camera.CaptureImage();
  36:  }
  37:   
  38:  void CameraButtons_ShutterKeyHalfPressed(object sender, EventArgs e)
  39:  {
  40:      camera.Focus();
  41:  }
  42:   
  43:  protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
  44:  {
  45:      if (camera != null)
  46:      {
  47:          camera.Dispose();
  48:          camera.CaptureImageAvailable -= camera_CaptureImageAvailable;
  49:      }
  50:  }

 

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

 

image

 

На картинке я специально повернул телефон так, как он расположен во время съемки. Как видно, чтобы изображение на экране, соответствовало изображению с камеры, нужно элемент, куда мы выводим изображение, повернуть на 90 градусов.

Итак, что мы увидели в данном примере:

1). Изображение можно снимать, используя стандартную клавишу камеры в телефоне. Для этого используется класс CameraButtons, содержащий несколько статических событий, позволяющих нам подключить наш код. Тут и возможность провести фокус (относительно центра или какой-то точки), тут и возможность обработать поток, который связан со сформированным изображением, доступным после завершения съемки.

2). Для работы с камерой есть ряд простых методов, такие как Focus или CaptureImage. Эти методы инициируют некоторый процесс в параллельном потоке, и передают свои результаты в параметрах таких событий как CaptureImageAvailable или AutoFocusCompleted. Поэтому, если Вы хотите изъять фотографию, то нужно определить обработчик первого события. Но изменение интерфейса нужно выполнять, передав управление в интерфейсный поток.

3). PhotoCamera позволяет сохранить изображение в виде потокового объекта, который уже преобразован к формату JPEG. Поэтому, если Вы хотите предварительно обработать изображение, то поток можно преобразовать во WritableBitmap с помощью классов, упоминавшийся выше, обработать и снова преобразовать в JPEG.

Сценарий выше работает если Вы хотите снять обычное изображение с камеры. Но если приложение немного более сложное, например, накладывает дополнительные элементы (например, усы на лица людей в кадре), то необходимо привлечь несколько дополнительных методов объекта типа PhotoCamera. Одним из таких методов является GetPreviewBufferArgb32, позволяющий вернуть текущий фрейм для дальнейших манипуляций. Получив массив данных, разработчик может выполнить их предварительную обработку, преобразовать во WritableBitmap и выдать на экран. В этом случае VideoBrush не используется совсем, а используется объект Image, в который и выводиться очередной WriteableBitmap. Естественно, что обработка каждого следующего фрейма проводиться в методе, который запускают в параллельном потоке. А частота выдачи изображений на экран, зависит от сложности алгоритма, обрабатывающего изображение.

Если говорить про Silverlight 4 API, то тут ничего не поменялось. Работа начинается с классов AudioCaptureDevice, VideoCaptureDevice и CaptureDeviceConfiguration. Эти классы используются для получения ссылок на доступные аудио и видео устройства. Если устройств несколько, то Вы можете предоставить пользователю выбор, с каким устройством работать.

Основным классом является CaptureSource, который позволяет начать запись. Внутри этого класса описаны ссылки на аудио и видео устройства, а также присутствуют такие методы как Start и Stop, позволяющие запустить или остановить работу камеры. Кроме того, объект данного класса может служить источником данных для VideoBrush.

Отличие классов Silverlight API состоит в том, что с помощью них можно выполнять запись изображения в видео-файл (MP4). Для этого используется класс FileSink, который имеет свойства CaptureSource и IsolatedStorageFileName – все, что необходимо для начала записи. При установке свойства CaptureSource соответствующий объект должен быть остановлен. Если Вы хотите написать собственный декодер, то можно использовать такие классы как VideoSink и AudioSink. Последние можно использовать и для передачи аудио и видео в различных системах видео чата.

Written by Sergiy Baydachnyy

01.01.2012 at 22:41

Опубликовано в Windows Phone

Tagged with