Pull to refresh

Пишем программу для установки рингтонов в Windows Mobile

Reading time 4 min
Views 1.5K
Windows Mobile, что пятая, что шестая, отличается далеко не самой удобной системой установки рингтонов. К слову, нам моём прошлом Palm Treo 650 было ещё кошмарней, но речь не о нём. Мало того, что нам не дают поставить мелодию на группу, так ещё и все рингтоны должны лежать в папке \Windows\Rings. Да, можно поменять через реестр, но это некрасиво, да и проблему с группами не решает.

Что же делать?

Сначала я обратил свой взор на нечто под названием PhotoContactsPro, который даже mobile-review.com в какой-то из статей рекомендовал как хорошую утилиту для установки мелодии на группы. Но вот незадача, утилита эта предоставляет целую оболочку для телефона, что мне, к примеру, даром не надо (а она ещё и денег стоит). При выключении этой оболочки назначение мелодий на группу, разумеется, отключается.

Далее, внезапно нашлась утилитка ToneManager. Утилитка хороша: маленькая, бесплатная, делает ровно то, что нужно — вешает в Pocket Outlook мелодии по группам. Но работает она ровно с одной папкой (\Windows\Rings по умолчанию) и, что самое, неприятное, не умеет сохранять свои настройки. А сохранять настройки для такой программы крайне важно, поскольку всё, что она делает — проставляет мелодии контактам, то бишь новые контакты идут лесом, пока её снова не запустишь. Автор в релизе радостно написал «извините, сохраняться будем в следующих версиях!», но вот следующих версий как-то и нет.

Намучившись с поисками, решил, что проблема эта — отличный повод пощупать-таки Compact Framework и сделать свою утилитку.

Автор статьи wdk, но он, в силу своей кармы, не может опубликовать материал. Если вам понравилась статья, то помогите хорошему автору поправить свою карму и начать писать полезные статьи.


Получилось вот что:


Что оно умеет?
В принципе, всё ясно из скриншота. Можно выбирать мелодию для контакта, для группы, для всех контактов, можно затереть своей мелодией глобальный виндовский рингтон (что в Настроках->Личное->Телефон). Мелодии можно выбирать хоть откуда, в том числе с карты памяти. Мелодии проставляются по списку, приоритет возрастает к низу.

Работает в WM5, WM6, тестировалось на QVGA, VGA. На WM Smartphone работать не хочет из-за пары контролов, есть над чем подумать. На эмуляторе WM2003 программа работать также отказалась.

Собственно программа: werder.nm.ru/wToneManager_Installer.CAB

Как оно работает?
Вытащить контакты оказалось очень просто, если знать про сборку Microsoft.WindowsMobile.PocketOutlook. Создаём сессию Pocket Outlook и, вуаля, там всё, что нужно:

OutlookSession session = new OutlookSession();
ContactCollection contacts = session.Contacts.Items;

//Вытащим контакты
foreach (Contact c in contacts)
{
  cbContacts.Items.Add(GetContactString(c));
}

//Вытащим категории
foreach (Contact c in contacts)
{
  string[] curCats = c.Categories.Split(',');
  foreach (string cat in curCats)
    if (!cbGroups.Items.Contains(cat) && !String.IsNullOrEmpty(cat.Trim()))
      cbGroups.Items.Add(cat);
}

//Обновить рингтон очень просто, но следует помнить,
//что Pocket Oulook меняет коллекцию при сохранении,
//поэтому foreach не подходит
for (int i = 0; i < contacts.Count; i++)
{
  Contact c = contacts[i];
  c.RingTone = item.Tone;
  c.Update();
}


* This source code was highlighted with Source Code Highlighter.


C проигрыванием мелодий всё интересней. Существует масса способов проиграть мелодию (wav, mp3, wma) в WM, и только один из них хороший. Но обо всём по порядку. Способ первый — стандартная функция PlaySound из winmm.dll. Стоит ли говорить, что играть оно умеет только wav? Поэтому смотрим в MSDN и находим отличный способ — библиотечка aygshell.dll! И mp3 играть умеет, и возможность синхронного/асинхронного проигрывания… Но вот незадача, есть она только в WM6, а обладателей устройств на WM5 — масса, и обижать их не хочется. Ищем дальше. В интернетах встречается много советов использовать новый класс SoundPlayer из CF3.5. Я был готов перейти на третий фреймворк ради этого волшебного класса, но вот сюрприз, играть mp3 этот класс отказывается, что весьма странно.

На этом пытаться проиграть мелодию стандартными средствами надоело, и появилась мысль воспользоваться чем-нибудь сторонним. Сначала выбор пал на библиотеку FMOD. Под впечатлением от обилия возможностей был быстренько написан небольшой враппер, с виду всё работало и было замечательно. До тех пор, пока при тестировании случайно не была выбрана мелодия в формате wma. По неизвестным причинам версия FMOD для WinCE решительно отказывается играть wma, хотя разработчик заявляет о возможности.

Что же остаётся? Он всегда скромно стоял неподалёку и ждал, когда же на него обратят внимание. Конечно же, это Windows Media Player!

Подключить его очень просто — в студии жмём Add Reference и находим файлик %windir%\System32\wmp.dll. Не стоит пугаться большого размера этого файла, для нашего проекта будет приложена другая библиотека, Interop.WMPLib.dll, куда меньшего размера.

Проиграть мелодию в WMPLib оказалось куда проще, чем в том же FMOD:
WMPLib.WindowsMediaPlayer wmp = new WMPLib.WindowsMediaPlayer();

//Если у юзера стоял повтор в настройках, у нас мелодия зациклится, чего нам явно не нужно
wmp.settings.setMode("Loop", false);
wmp.settings.volume = 100;

//Выбранная юзером мелодия
wmp.URL = (cbTone.SelectedItem as ListItem).Value;
wmp.controls.play();


* This source code was highlighted with Source Code Highlighter.


Как видите, всё предельно просто! К слову, WMPLib оказалась очень мощной библиотекой, масса событий, плейлисты и много-много прочего, но это тема для отдельной статьи, и не одной.

На этом всё, благодарю за внимание, пробуйте, отписывайтесь!

Progg it
Tags:
Hubs:
+17
Comments 26
Comments Comments 26

Articles