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

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
_________
Текст подготовлен в ХабраРедакторе
+17
26 февраля 2009, 08:03
14
XaocCPS 352,0

комментарии (26)

+1
elisium #
Если в корне карты памяти создать папку «My Documents/Мои документы», в зависимости от наличия русификации, и положить туда mp3 файлы, то их можно поставить на рингтон не прибегая к Windows\Rings. Мне этого оказалось вполне достаточно, но программу опробую. Спасибо.
0
kvf77 #
В последней версии Witu винда находит mp3 и в других папках, во всяком случае они появляются в родном селекте выбора.
0
Fr3nzy #
Только при этом копировал рингтон в папку Windows/Rings, если вы его выбирали в качестве рингтона. Во всяком случае моя WM 5-6.5 поступает именно так.
0
kvf77 #
Тут врать не буду — понятия не имею :-)
0
darked #
Такая же ситуация, где бы не нашла mp3, после указания как рингтон, копирует себе на телефон с карты.
0
wdk #
Главной целью было всё же на группы назначать.
0
Fr3nzy #
Сейчас попробую запустить на WM 6.5
0
Fr3nzy #
Установил, протестил :) полет нормальный. Правда, список контактов немного неудобный.
+1
wdk #
Да, вероятно со списком в 1000 контактов будет тяжко.
0
Fr3nzy #
Но, тем не менее, спасибо вам за хорошую прогу) в свое время не мог найти ничего, что содержало бы только эти функции )
0
tkf #
А сырцы можно? )
0
wdk #
Можно, но только вечером. Сейчас сырцы и я разделены километрами без каких-либо каналов связи.
Хотел же весь проект залить и ссылку добавить, но как-то забылось.
0
wdk #
Обещанный исходник: werder.nm.ru/wToneManager_Src.zip
0
Nitrogen #
если не сложно, добавь в программу возможность выбора *.mid файлов. у меня все рингтоны в этом формате…
windows media player без проблем с ними справляется.
я понимаю что есть исходники, но у меня из скомпилить нечем
0
wdk #
Без проблем, скачай заново cab, ссылка та же.
Всякие мелодии на смс и будильник делать пока лень из-за задалбывающей работы, но сделаю обязательно.
–4
Fr3nzy #
Думаю, можно было написать вместо
Windows Mobile, что пятая, что шестая, отличается далеко не самой удобной системой установки рингтонов.


Windows Mobile, что пятая, что шестая, что десятая, отличается далеко не самой удобной системой установки рингтонов.

0
tkf #
Ну почему же, может у них когда нибудь руки дойдут это у кого то слизать )
+2
wdk #
Печально, но в переходе «телефон->смартфон->коммуникатор» внимание разработчиков к простым телефонным радостям вроде «мелодия на группу» уменьшается.
+2
megavolt #
«Я Пастернака не читал, но осуждаю»
0
alucky #
мне не хватает только вибро режима
0
mlurker #
Раз уж о недостатках wm)
wmp не умеет рекурсивно сканировать музыкальные папки на наличие музыки, берёт только файлы из корневой. (По крайней мере на моём x500+ с wm6, wm6.1)
0
pr0head #
Спасибо!
Мелодий для групп давно не хватало.
0
pr0head #
С хорошим управлением и реализацией, имеется в виду.
0
SuperNatural #
Все работает, всё классно.

Предлагаю в программе еще сделать вкладку по установке мелодии на будильник. Там тоже все не так просто и понятно, поставить mp3 с sd-карты сходу не получится.
0
wdk #
Хорошая мысль, спасибо.
Улучшения скорее всего будут, и для смс, и для будильника. Для смс была идея добавить функционал, но сходу разобраться не удалось, с WM5 возникли проблемы. Да и WM не позволяет задавать отдельные мелодии для смс от разных контактов, скучно.
Жаль, что вкладки уменьшат и без того мелкую рабочую область.
0
Nitrogen #
альтернатива: ArchiGroupRings версия 1.1, живет тут: 4pda.ru/forum/index.php?showtopic=61431
не знаю хуже или лучше Вашей.

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