Рейтинг
0.00
голосов:
0
avatar

Разработка приложений для Windows Mobile  

работа с OSM картами (QGIS) в среде Compact Framework

Разрабатывая очередное приложение, наткнулся на проблему связанную с открытием карт созданных в системе QGIS на мобильном устройстве с системой Windows Mobile. Проблему решил в течении 2-х недель. Кому это интересно пишете, с радостью отвечу. Почему не пишу сразу? Тема очень обширная, будет вопрос будет ответ. Классы разработанные мной можно переписать и для Phone 7 и для Android.

Ошибка определения местоположения по базовым станциям или ошибка мобильного оператора?

Для своего мобильного приложения я использую определение местоположения по базовым станциям (библиотека cellid.dll, C#, Windows Mobile). Результаты определения местоположения попадают в базу на удаленном сервере. Вчера сделал возможность вывода координат на карты Google на своем сайте и вот что заметил:


А вот база данных:



Получается, что я менее чем за одно минуту из Новороссийска перебрался в Можайский район и обратно!

Хорошо если это ошибка в самой библиотеке (ранее не замечал), а если на самом деле телефон периодически посещает роуминг и совершенно по другой цене?

Есть ли мысли по этому поводу?

Смена настроек GPRS

Проблема: телефон приехал, например в Турцию, вставили карту TurkCell. Автоматических настроек не приходит. Надо программно сменить настройки: точка доступа, пользователь и пароль, DNS.
Определяем смену оператора сотовой связи — есть;
Определяем смену сим-карты — ecть;
Настройки GPRS большинства операторов есть — база Compact Sql Server;
Как сменить автоматически настройки? Где они могут хранится: cfg-файл или ветка реестра?

Обновление ПО на КПК через FTP

Я сделал таблицу в базе данных с одной записью. В ней храню: номер последней версии программы, размер cab-файла, контрольную сумму и путь к cab-файлу.
В программе на устройстве сделал кнопку «Check update». По нажатию на кнопку программа сверяет версию программы установленной и той что лежит на сервере, если они не совпадаю — программа скачивает удаленнй cab по ftp с проверкой размера и контрольной суммы. Теперь пользователь сам может установить обновление в любой точке земного шара. При выпуске новой версии не забудьте увеличивать счетчик версий или включите автомат. Проверить версию программы на устройстве можно так: System.Reflection.Assembly.GetExecutingAssembly().­GetName().Version.Major;

Загрузку осуществляю через ftp.
Вот пример ftp-клиента: FTPClient

Загрузка файла:
public bool GetFileFromServer(string localfn, string remotefn, string papka)
        {
            FtpClient ftp = new FtpClient(ftpServer, ftpUser, ftpPassword);
            try
            {
                ftp.Login();
                ftp.ChangeDir(@"Inbox");
                ftp.ChangeDir(papka);
                ftp.Download(remotefn, localfn, true);
            }
            catch (Exception e)
            {
                WriteLog("Address: GetFileFromServer. Message: " + e.Message + " Parameters: localfn = " + localfn +
                    ", remotefn = " + remotefn + ", papka = " + papka);
                return false;
            }
            finally
            {
                ftp.Close();
            }
            return true;
        }


Пример вызова:
if (!GetFileFromServer(localfn, remotefn, filename)) 
                                {
                                    WriteLog("Address: GetSendingsList. Message: " + " Unable to load file. Options: " + localfn + ", " + remotefn + ", " + filename);
                                    break; 
                                }


Сервер, пользователя и его пароль храню глобально. WriteLog — моя функция для ведения лога ошибок. Ftp в данном примере работает с докачкой.

Для верности я еще проверяю размер загруженного файла и контрольную сумму. Если надо приведу код проверки контрольной суммы. Пишите.

Определение пути к карте памяти телефона

Писал программу для «Gigabyte GSmart S1205», посмотрел что карта памяти в устройстве выглядит как «Storage Card» и начал использовать это имя в своем коде. Все работало отлично. Решил поставить программу на свой Witu Omnia i900. В нем вообще нет карты памяти, там диск на 16ГБ и называется он «Память телефона». Моя программ продолжала работать, но она создавала папку «Storage Card» в памяти устройства! Привожу код который поможет Вам точно определить название Вашего съемного диска в устройстве.

//########## ########## ########## ########## ########## ########## ########## ########## ##########
            public static readonly IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
            public struct WIN32_FIND_DATA
            {
                public int dwFileAttributes;
                public FILETIME ftCreationTime;
                public FILETIME ftLastAccessTime;
                public FILETIME ftLastWriteTime;
                public int nFileSizeHigh;
                public int nFileSizeLow;
                public int dwOID;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
                public string cFileName;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
                public string cAlternateFileName;
            }
            [StructLayout(LayoutKind.Sequential)]
            public struct FILETIME
            {
                public int dwLowDateTime;
                public int dwHighDateTime;
            };
            [DllImport("note_prj", EntryPoint = "FindFirstFlashCard")]
            public extern static IntPtr FindFirstFlashCard(ref WIN32_FIND_DATA findData);
            [DllImport("note_prj", EntryPoint = "FindNextFlashCard")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public extern static bool FindNextFlashCard(IntPtr hFlashCard, ref WIN32_FIND_DATA findData);
            [DllImport("coredll")]
            public static extern bool FindClose(IntPtr hFindFile); 
//########## ########## ########## ########## ########## ########## ########## ########## ##########


public static string GetRemovableStorageDirectory()
            {
                string removableStorageDirectory = null;
                WIN32_FIND_DATA findData = new WIN32_FIND_DATA();
                IntPtr handle = IntPtr.Zero;
                handle = FindFirstFlashCard(ref findData);
                if (handle != INVALID_HANDLE_VALUE)
                {
                    do
                    {
                        if (!string.IsNullOrEmpty(findData.cFileName))
                        {
                            removableStorageDirectory = findData.cFileName;
                            break;
                        }
                    }
                    while (FindNextFlashCard(handle, ref findData));
                    FindClose(handle);
                }
                return removableStorageDirectory;
            }


В том месте где Вам надо узнать точное наименование Вашего съемного устройства пишем примерно следующее:

removableDirectory = GetRemovableStorageDirectory();
if (removableDirectory != null)
{
string path = "\\" + removableDirectory + "\\";
}

Работа с GPS на Windows Mobile

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

1. Открываем проект gps.sln (путь: c:\program files\windows mobile 6 sdk\samples\pocket pc\cs\gps);
2. Строим решение, получаем dll;
3. Подключаем полученую dll как ссылку к своему проекту;
4. Добавляем
using Microsoft.WindowsMobile.Samples.Location;


Объявляю глобальные переменные, что бы в них всегда хранились актуальные данные координат

double Latitude = 0;
        double Longitude = 0;


5. Инициализируем и включаем gps (я это делал в
Form.Load
):

updateDataHandler = new EventHandler(UpdateData);
                gps.DeviceStateChanged += new DeviceStateChangedEventHandler(gps_DeviceStateChanged);
                gps.LocationChanged += new LocationChangedEventHandler(gps_LocationChanged);
                if (!gps.Opened)
                {
                    gps.Open();
                }

6. Добавим функции:

void UpdateData(object sender, System.EventArgs args)
            {
                //получаем обновленные данные с GPS
                if (gps.Opened)
                {
                    if (device != null)
                    {
                        WriteLog(DateTime.Now.ToUniversalTime() + " Can not turn on your GPS device!");  
                    }

                    if (position != null)
                    {

                        if (position.LatitudeValid)
                        {
                            //выводим широту
                            Latitude = position.Latitude;
                        }

                        if (position.LongitudeValid)
                        {
                            //выводим долготу
                            Longitude = position.Longitude;
                        }
                    }
                }
            }

            void gps_DeviceStateChanged(object sender, DeviceStateChangedEventArgs args)
            {
                device = args.DeviceState;
                Invoke(updateDataHandler);
            }

            protected void gps_LocationChanged(object sender, LocationChangedEventArgs args)
            {
                position = args.Position;
                Invoke(updateDataHandler);

            }

Когда мне надо получить координаты я делаю так:

//работает ли GPS
                                    if (!position.LatitudeValid) 
                                    {
                                       //не работает
                                    }
else
{
 double lat = latitude;
 double lon = longitude;
}

Кординаты представленны как тип double, но можно представить как градусы, минуты и секунды для этого надо

position.Latitude
заменить на
position.LatitudeInDegreesMinutesSeconds;


Все отлично работает!

Загрузка почтового сообщения из файла и отправка через smtp - сервер.

Добавьте к проекту ссылки на dll-ки: Interop.ADODB.dll и Interop.CDO.dll

Объявите
CDO.Message msg = null;


Вот пример функции загружающей сообщение из файла (файл содержит сообщение сохраненное в любом почтовом клиенте) и отправляющей его через smtp — сервер:

private bool SendMessage(string filename)
        {
            bool result = false;
            ADODB.Stream stream = null;
            try
            {
                msg = new CDO.MessageClass();
                CDO.IConfiguration iConfg;
                stream = new ADODB.StreamClass();
                stream.Open(Type.Missing, ADODB.ConnectModeEnum.adModeUnknown, ADODB.StreamOpenOptionsEnum.adOpenStreamUnspecified, String.Empty, String.Empty);
                stream.LoadFromFile(filename);
                stream.Flush();
                msg.DataSource.OpenObject(stream, "_Stream");
                msg.DataSource.Save();
                string strSch = "http://schemas.microsoft.com/cdo/configuration/";
                iConfg = msg.Configuration;
                ADODB.Fields oFields;
                oFields = iConfg.Fields;
                ADODB.Field oField = oFields[strSch + "sendusing"];
                oField.Value = CDO.CdoSendUsing.cdoSendUsingPort;
                oField = oFields[strSch + "smtpserver"];
                oField.Value = smtp_server;
                oField = oFields[strSch + "smtpserverport"];
                oField.Value = smtp_port;
                oField = oFields[strSch + "sendusername"];
                oField.Value = smtp_user;
                oField = oFields[strSch + "sendpassword"];
                oField.Value = smtp_password;
                oField = oFields[strSch + "smtpauthenticate"];
                oField.Value = CDO.CdoProtocolsAuthentication.cdoBasic;
                oField = oFields["http://schemas.microsoft.com/exchange/outlookmessageclass"];
                oField.Value = "IPM.Note.MyCustomForm";
                oFields.Update();
                msg.Send();
                result = true;
            }
            catch (Exception e)
            {
               //
            }
            finally
            {
                stream.Close();
            }
            return result;
        }


Очень удобно и для парсинга сообщений полученных с pop3. И правильно на 100%. Например:
string To = msg.To;
  • +1
  • 13 декабря 2010, 13:32
  • admin
  • 4

Не выводятся Exception - ы на Windows Mobile

Вы наверно часто сталкивались с таким сообщение:

Для этого исключения доступно сообщение об ошибке, но его невозможно отобразить, поскольку такие сообщения являются необязательными и в данный момент не установлены на этом устройстве. Установите «NETCFv35.Messages.EN.wm.cab» для Windows Mobile 5.0 и более поздних версий или «NETCFv35.Messages.EN.cab» для других платформ. Перезапустите приложение для отображения сообщения.

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

1. Идете в C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\Wind­owsCE\Diagnostics;
2. Распаковываем файл NETCFv35.Messages.EN.wm.cab, который там лежит;
3. Ищем в распакаваных файлах — SYCCFA~1.001;
4. Переименовываем его в System.SR.dll;
5. Добавляем этот получившийся файл как ссылку к проекту в Visual Studio.

Все. Теперь Exception — ы выводятся.