вторник, 18 ноября 2008 г.

Доступ к функциям телефона из web-страницы

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

Однако, есть выход. Оказывается, существует такая полезная вещь, как Trigger phone call. Суть в том, что можно вставлять прямо в HTML-код гиперссылки со специальным URI, и по нажатию на эти ссылки будут отправляться SMS, MMS, совершаться звонки и т.д.

Примеры

Отправка SMS

Ссылка, открывающая редактор SMS с текстом "Hello" и с указанным адресатом:

<a href="sms:+79021234567?body=Hello">Click to send message</a>

Ссылка, открывающая редактор SMS с текстом "Hello" и с указанным списком номеров:

<a href="sms:+79021234567,+79081234567?body=Hello">Click to send message</a>

Пишут, что в URI вместо sms: можно использовать smsto:, SMS: (для телефонов Siemens) и даже com.nokia.sms: (для телефонов Nokia).

Совершение вызова

Ссылка, совершающая вызов:

<a href="tel:+79021234567">Call</a>

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

Отправка MMS

Ссылка, отправляющая MMS:

<a href="mmsto:+3581234567?subject=Hi?body=Nice%20to%20see?">Send message</a>

Большой минус

Это все, конечно, очень хорошо и полезно. Но проблема в том, что не на всех телефонах работает. У меня были в наличии Nokia 2600 classic (самый обычный телефон) и Nokia же N73 (смартфон). Получилась такая картина:

Nokia 2600 classic (Series 40):

Default browserOpera Mini
SMSРугается на неверный адресМолча не работает
MMSРугается на неверный адресМолча не работает
telРаботаетРаботает

Nokia N73 (Series 60):

Default browserOpera Mini
SMSРаботает, если URI cодержит sms, но не работает с smsto (не заполняется тело сообщения) Работает smsto, но не работает sms (не заполняется тело сообщения)
MMSВроде работаетТоже вроде работает
telРаботаетРаботает

Эмулятор Android

Про него я сначала и забыла, но решила восполнить этот пробел.

Default browser
SMSИ sms, и smsto открывают редактор SMS, но адресат и тело сообщения не заполнены.
MMSОткрывается редактор, но, опять же, ничего не заполнено.
telРаботает

Зато я узнала, что эмулятор можно поворачивать на 90 градусов с помощью сочетания Ctrl+F11

В заключение

Итак, конструкция полезная и удобная, но использовать ее следует осторожно, потому как работать может не везде.

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

Ссылки

четверг, 13 ноября 2008 г.

Программа для отображения состояния коннекта

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

Так что приходилось располагать окошки так, чтобы видеть консоль с ping -t google.ru. А потом мне пришла в голову светлая идея написать программу для отображения состояния пинга в трее. В качестве языка реализации был выбран C#, дабы не заморачиваться.

Сначала создаем проект вида Windows Application. На главную форму можно не кидать никакие элементы управления, все равно не понадобятся. Зато в ресурсы надо добавить два каких-нибудь значка, один из которых будет называться Ping и обозначать коннект, а второй - Noping и отсутствие коннекта. Вот код формы:

namespace Pinger
{
  public partial class PingForm : Form
  {
    /// <summary>Иконка, обозначающая коннект</summary>
    private static NotifyIcon pingIcon;
    /// <summary>Иконка, обозначающая отсутствие коннекта</summary>
    private static NotifyIcon nopingIcon;

    /// <summary>true, если есть коннект, false иначе</summary>
    private static bool pingState;
    public static bool PingState
    {
      get { return pingState; }
      set
      {
        if (pingState != value) // если значение pingState изменилось
        {
          pingState = value;
          
          // переключаем иконки в трее
          NotifyIcon currentIcon = pingState ? pingIcon : nopingIcon;
          pingIcon.Visible = pingState;
          nopingIcon.Visible = !pingState;
          
          // показываем подсказку
          currentIcon.ShowBalloonTip(2000);
        }
      }
    }

    /// <summary>
    /// Функция, отправляющая пинг
    /// </summary>
    private void MakePing()
    {
      Ping pingSender = new Ping();

      // Добавляем обработчик для события окончания пинга
      pingSender.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);
      
      // инициализируем буфер с данными
      string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
      byte[] buffer = Encoding.ASCII.GetBytes(data);

      // куда посылаем пинг
      string who = "google.ru";

      // сколько ждем
      int timeout = 3000;

      AutoResetEvent waiter = new AutoResetEvent(false);
      PingOptions options = new PingOptions(64, true);

      while (true)
      {
        try
        {
          // собственно посыл пинга
          pingSender.SendAsync(who, timeout, buffer, options, waiter);
        }
        catch (Exception e)
        {
        }

        Thread.Sleep(timeout);
      }
    }

    /// <summary>
    /// Конструктор формы
    /// </summary>
    public PingForm()
    {
      InitializeComponent();

      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PingForm));

      // читаем из ресурсов иконки
      pingIcon = new NotifyIcon();
      pingIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("Ping")));
      pingIcon.BalloonTipText = "Ping is OK";
      pingIcon.BalloonTipTitle = "Pinger";
      pingIcon.BalloonTipIcon = ToolTipIcon.Info;

      nopingIcon = new NotifyIcon();
      nopingIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("Noping")));
      nopingIcon.BalloonTipText = "No Ping";
      nopingIcon.BalloonTipTitle = "Pinger";
      nopingIcon.BalloonTipIcon = ToolTipIcon.Warning;

      // значение по умолчанию
      PingState = true;

      // запускаем функцию MakePing в отдельном потоке
      Thread t = new Thread(new ThreadStart(MakePing));
      t.Start();
    }

    /// <summary>
    /// Обработка результата пинга
    /// </summary>
    public static void PingCompletedCallback(object sender, PingCompletedEventArgs e)
    {
      // пинг считается правильным, если не возникло ошибок и пришел ответ Success
      PingState = e.Error == null && e.Reply.Status == IPStatus.Success;
    }
  }
}

Вот, что получилось:

Появился коннект:

Есть коннект

Пропал коннект:

Нет коннекта

Я лично сейчас смотрю и очень радуюсь :) Правда, код для закрытия я поленилась писать, и закрыть программу можно только, отстрелив процесс в Task Manager.

Ссылки

среда, 12 ноября 2008 г.

Mobile Processing

Думала, мой следующий пост (вернее, следующая серия) будет опять про Андроид, ан нет :) Недавно попалась мне одна удивительная штука под названием Mobile Processing. Это инструмент, облегчающий процесс создания мобильных приложений. Обычно, если хочется написать мобильное приложение, надо учить Java, разбираться, как устроен мидлет, какие у него там события, каков жизненный цикл. И, если честно, не могу сказать, что копаться в этом очень приятно.

Другое дело Mobile Processing. Тут вообще необязательно что-либо знать про мидлеты. Есть собственный простой язык, похожий на Java, с помощью которого можно описать логику приложения. Есть IDE, которая выглядит таким образом:

Единственное, что надо настроить в IDE - указать путь к WTK.

После этого мы пишем код, в котором просто определяем функции типа setup(), draw() и т.п., сохраняем все это дело в файл %progname%.PDE потом нажимаем кнопку "Пыщь" - и среда генерит нам jar.

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

int x, y;
int r = 5;

void setup()
{
 x = 100;
 y = 100;
}

void draw()
{
 background(255, 204, 0);
 ellipse(x, y, 2 * r, 2 * r);switch (keyCode){
  case UP: y--; break;
  case DOWN: y++; break;
  case LEFT: x--; break;
  case RIGHT: x++; break;
  default: break;}
}

void keyReleased()
{
 keyCode = 0;
}

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

Полученный jar-файл весил 46 Кб, но с помощью имеющегося оптимизатора-обфускатора ProGuard его удалось ужать до 7 Кб. Программа запросто запустилась на моей Nokia 2600c, а также на Nokia N73.

В общем, данная тулза привела меня в восторг своей простотой (особенно после монстров типа NetBeans или IDEA, которую все хвалят, но в которой мне так и не удалось создать Mobility-проект). Позиционируется она как средство быстрого создания прототипов приложений, но, честно говоря, возможности у нее не такие уж и слабые. Есть библиотеки для работы с Bluetooth, с камерой и другими возможностями телефона. И самое интересное - оно работает. Единственное, что меня удивляет, так это практически отсутствие упоминаний о данном продукте в рунете. Вроде, и проект не совсем мертвый (последний релиз в июле 2008). Интересно, почему бы это?

Но я в ней еще поковыряюсь, дабы узнать, что там плохо или хорошо. Пока что все обнаруженные минусы относятся к редактору: отсутствие отладчика и IntelliSense, неидеальный keymapping (я люблю, чтобы работали Ctrl+Ins и Shift+Ins, а там только Ctrl+C и Ctrl+V. Хотя, возможно, это настраивается в конфиге, который там далеко спрятан).

Ссылки по теме