МОБИЛЬНОЕ ЗРЕНИЕ РОБОТОВ

Пример спецификации телефона: Siemens CX75 | [все модели] | Nokia, см. примеры.

ВВЕДЕНИЕ В J2ME

MIDlet – это разновидность MIDP (Mobile Information Device Profile) Java приложения, предназначенное для работы на мобильных устройствах. Программирование ведется на урезанной версии Java: J2ME | [2] | [Nokia]

РАБОЧАЯ СРЕДА J2ME

Прежде всего необходимо установить Java Developer's Kit, текущую версию можно скачать из зоны downloads отсюда: J2SE SDK. JDK создает Java платформу, позволяющую работать с J2ME Wireless Toolkit. По умолчанию установка производится в папку c:\WTK..., инсталлятор создаст ярлык на рабочем столе.

ПЕРВЫЙ ПРОЕКТ

Переходим к J2ME. Нажмите кнопку New Project. J2ME спросит его имя, а также имя MIDlet класса. Введите HelloSuite (будет создана папка) и HelloMIDlet (так именуется файл, который следует создавать далее и редактировать текстовым редактором), здесь и далее примеры взяты из MobiLab.ru.

В папке с WTK будет создан новый каталог apps\HelloSuite (или аналогичный, но в каталоге пользователя), проект содержит стандартный набор подкаталогов: в bin содержатся откомпилированные файлы .jar c дескриптором .jad, в папке lib - все дополнительные jar файлы, в res - файлы ресурсов (рисунки или текстовые файлы), в scr - исходные тексты проекта. Наберите текстовым редактором первый пример и сохраните его как HelloMIDlet.java в папке scr. Наименование HelloMIDlet встречается в тексте примера дважды.

 

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class HelloMIDlet extends MIDlet implements CommandListener {

 private Form mMainForm;
  
 public HelloMIDlet() {
  mMainForm = new Form( "HelloMIDlet" );
  mMainForm.append( new StringItem( null, "Hello, MIDP!" ) );
  mMainForm.addCommand( new Command( "Exit", Command.EXIT, 0 ) );
  mMainForm.setCommandListener( this );
 }

 public void startApp() {
  Display.getDisplay( this ).setCurrent( mMainForm );
 }

 public void pauseApp() {}

 public void destroyApp( boolean unconditional ) {}

 public void commandAction( Command c, Displayable s ) {  
  notifyDestroyed();
 }
}

// РАЗНОВИДНОСТЬ (ВТОРОЙ МИДЛЕТ)

import javax.microedition.midlet.*; 
import javax.microedition.lcdui.*; 

public class HelloMIDlet extends MIDlet 

private Form form; 
private Display display; 

public HelloMIDlet() 

super(); 


public void destroyApp(boolean destroy) 

form = null; 
notifyDestroyed(); 


public void pauseApp() 



public void startApp() 

form = new Form("Заголовок программы"); 
String msg = "Моя первая программа!"; 
form.append(msg); 
display = Display.getDisplay(this); 
display.setCurrent(form); 

}

Нажмите кнопку Build, потом Run. Вы должны увидеть окно эмулятора "стандартного" телефона. Эмулятор показывает список доступных MIDlet-ов. Виден HelloSuite, при его выборе будет запущен класс HelloMIDlet. Для старта нажмите на изображение клавиши "Select" на телефоне. Будет показан экран с указанной надписью Hello, MIDP!

Программа. Чтобы завершить компоновку, выберите Project | Package из меню. В результате в папке bin будут созданы файлы .jad и .jar (и манифест).

Упрощенный и более полный каркасы мидлета показаны ниже. Последний включает initApp() - метод для первой инициализации и exitApp() - метод для централизованного освобождения ресурсов. Пакет javax.microedition.midlet - служит для создания самого MIDP приложения, lcdui - служит для создания интерфейса пользователя, rms - служит для долговременного хранения какой-либо информации в постоянной памяти мобильного устройства.

 

import javax.microedition.midlet.*;

public class HelloMIDlet extends MIDlet {

    public HelloMIDlet(){
 // Конструктор
    }

    protected void destroyApp( boolean unconditional )
       throws MIDletStateChangeException {
 // Вызывается когда система уничтожает MIDlet
    }

    protected void pauseApp(){
 // Вызывается при переводе приложения в режим паузы.
    }

    protected void startApp()
       throws MIDletStateChangeException {
 // Вызывается, когда приложение переводится в активный режим.
    }
}

//БОЛЕЕ ПОЛНАЯ ВЕРСИЯ

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class BetterMIDlet extends MIDlet {

    private Display display;

    public BetterMIDlet(){
    }

    protected void destroyApp( boolean unconditional )
       throws MIDletStateChangeException {
       exitApp(); // вызывает уборщик мусора
    }

    protected void pauseApp(){
    // Сюда следует добавить код, который надо выполнять
    // перед переводом приложения в режим паузы.
    }

    protected void startApp()
    throws MIDletStateChangeException {
    if( display == null ){
     initApp(); // Определяет первоначальную инициализацию
    }
    // Сюда следует добавить код, который надо выполнять
    // перед переводом приложения в активный режим.
    }

    private void initApp(){
    display = Display.getDisplay( this );
    // Сюда добавляется код инициализации приложения
    }

    public void exitApp(){
    // добавит код "уборки мусора"
     notifyDestroyed(); // уничтожение MIDlet-а
    }
}

Логика работы. Приложениями телефоном управляет Application-Management Software (AMS). Первоначально MIDlet находится в соостоянии paused. AMS активизирует его и вызывает метод startApp(), который создает и выводит на экран пользовательский интерфейс приложения. MIDlet переходит из состояния paused в active. Поскольку телефон обслуживает приложения приоритетно, AMS может остановить или закрыть MIDlet с вызовом методов pauseApp() или destroyApp(). Например, если при запуске возникли какие-нибудь ошибки, AMS переключает MIDlet в состояние destroyed. Метод имеет необязательный параметр типа boolean, который определяет, является ли уничтожение безусловным или необязательным. Если MIDlet останавливает или уничтожает сам себя, pauseApp() и destroyApp() не вызывается.

Остальные методы прямо затрагивают жизненый цикл MIDlet-а. Переведенный в режим паузы MIDlet вызывает метод resumeRequest() для реактивации. ASM решает надо ли это делать и если надо, то когда. Реактивация вызывает метод startApp(). Активный MIDlet вызывает notifyPaused(), чтобы деактивироваться. Активный или находящийся в состоянии паузы MIDlet вызывает метод notifyDestroyed() для самоуничтожения. При этом ни pauseApp() ни destroyApp не вызываются.

Интерфейс. Оконный интерфейс фактически отсутствует. Нет никаких объектов Window, Dialog, Frame. Каждый мидлет имеет дисплей, на котором одновременно может показываться только один Displayable объект. Метод Display.getDisplay() возвращает объект Display. Главным методом этого класса являеться метод setCurrent (Displayable next), который позволяет менять различные объекты на экране. Есть способ добавить команду и установить 'слушателя' для команды.

Существует пять классов, которые расширяют интерфейс: List позволяет выбрать пользователю элементы из списка. Каждый элемент в списке представляется строчкой и может иметь Image. TextBox позволяет пользователю вводить и редактировать текст. Alert можно сравнить с диалоговым окном, оповещающим о какой-то произошедшей ситуации. Form может содержать комбинацию элементов, которые могут представлять строчки, изображения, поля ввода, списки. Canvas позволяет приложению самому обеспечивать отрисовку, переопределив метод paint (Graphics g). Graphics - позволяет нарисовать изображение, строчку, элипс, прямоугольник, линию. Вот почти и все.

Font - можно получить только тот шрифт который предоставит телефон. Для этого есть статический метод Font.getFont (int face, int style, int size). Все многообразие шрифтов, предоставляемое мидлету, заключено в параметрах этого метода (метод setFont (Font f) есть только у Graphics, а Graphics только у Canvas). java.lang.Math - элементарен до безобразия. Те, кто знаком с технологией Java, знают, что данный класс содержит методы, совершающие основные числовые операции, такие как экспонента, логарифм, тригонометрические операции. Так вот, в мидлете они не доступны. java.lang.Math имеет только 3 метода: abs(int a), max(int a, int b), min(int a, int b).

AMS API позволяет сохранять небольшие небольшие порции данных в постоянное место хранения. Эти данные хранятся до тех пор, пока не будет удален мидлет. Но другим мидлетам, данная информация не будет доступна. (MIDP 2.0 позволяет другому мидлету, иметь доступ к этим данным, при условии, если тот, имеет необходимые привелегии.) Но не пытайтесь думать, что это какие-то файлы. Понятие File для MIDP не существует.

Подсветка экрана и вибратор, звук. В MIDP 1.0 отсутсвуют, появились только в MIDP 2.0.

Дескрипторы. На старте возникает иногда потребность в дескрипторе приложения (application descriptor - текстовый файл с расширением jad) или его манифесте (файл Manifest.MF). Метод getAppProperty() позволяет получить доступ к этой информации, причем сначала опрашивается дескриптор, и если информация не найдена, просматривается манифест (MIDP 2.0 использует концепцию доверенных (trusted) приложений, согласно которой метод getAppProparty() ищет только манифест).

Зависания. AMS информирует мидлет о новых событиях (events) и посылает уведомления (notifications), напрямую вызывая его методы. Например, когда по каким-то причинам AMS хочет обновить экран, он обращается к методу paint() объекта Canvas. При этом AMS фактически теряет контроль над системным потоком. Чтобы гарантировать работоспособность, такие методы должны как можно быстрее завершать свою работу. J2ME Wireless Toolkit выдает сообщение, если в исходном коде кроется риск зависания.

СТРУКТУРА J2ME

J2ME не является отдельной спецификацией или программой. Это целый набор теxнологий и спецификаций, разработанныx для различныx областей рынка небольшиx устройств. Ядро J2ME составляют две различные конфигурации: Connected Device Configuration (CDC) и Connected Limited Device Configuration (CLDC). Конфигурации определяют центральные Java-библиотеки и возможности виртуальной Java-машины. CDC предназначена для высокотеxнологичныx портативныx устройств типа коммуникаторов Nokia, а CLDC — для недорогиx портативныx устройств типа массовыx мобильныx телефонов. Помимо конфигураций существуют профили, которые определяют функциональность для конкретного класса устройств. Mobile Information Device Profile (MIDP) — профиль для основанныx на CLDC портативныx устройств с коммуникационными возможностями. MIDP определяет использование пользовательского интерфейса, постоянной памяти и работу с сетями. Ядро реализованной в продуктаx Nokia J2ME основано на CLDC и MIDP.

Для стандартизации многочисленных устройств у производителей появилось такое понятие, как платформа. Преимущество такого подхода очевидно: характеристики всех телефонов определенной платформы совершенно одинаковы, и пользователю достаточно знать, на какую платформу рассчитано приложение. Наиболее популярна связка CLDC 1.0 и MIDP 2.0. Разделением на платформы славятся Nokia и Sony Ericsson. У Sony Ericsson платформы просто имеют порядковые номера, от JP-1 до JP-8 (JP расшифровывается как Java Platform). У Nokia разделение чуть сложнее: указывается принадлежность к телефонам (S40) или к смартфонам (как правило, S60), затем редакция платформы, и потом набор возможностей платформы (к примеру, S40 3rd Edition Feature Pack 2). Таким образом, вместо длинного списка поддерживаемых телефонов достаточно писать что-нибудь вроде: требуется JP-5 и выше. Примерно так же решили и проблему с экранами: сделали несколько стандартных разрешений, под которые можно написать универсальную программу.

КОНФИГУРАЦИИ УСТРОЙСТВ

Конфигурация CLDC (Connected Limited Device Configuration) предназначена для устройств с ограниченным объемом памяти и вычислительной мощностью. Содержит только базовые пакеты java.lang.*, java.io.*, java.util.*, javax.microedition.io.* и добавленный в версии 1.1 пакет java.lang.ref.*. Пакеты, совпадающие с J2SE, содержат минимальный набор классов, необходимых для создания приложений. По реализации пересекающихся с J2SE классов, версии байт-кода CLDC 1.0 соответствует JDK 1.1, CLDC 1.1 – JDK 1.3.

Иногда к названию конфигурации добавляют HI, что означает HotSpot Implementation (виртуальная машина с улучшенными алгоритмами оптимизации выполняемого кода в целом и часто выполняемых кусков кода в частности, для J2SE она стала виртуальной машиной по умолчанию с версии 1.3).

CDC (Connected Device Configuration) предназначена для устройств с достаточным объемом памяти и производительностью. В дополнение к пакетам CLDC содержит классы для работы с архивами zip и jar, более развита рефлексия, работа с сетью, коллекциями, текстом, и определен класс BigInteger для операций с большими числами.

ПРОГРАММНЫЕ ПРОФИЛИ

MIDP (Mobile Information Device Profile) – профиль для конфигурации CLDC. Он содержит пакеты для работы с графикой, звуком, взаимодействия с консолью (клавиатура и экран), базовый набор классов для отображения стандартных экранов и control-ов. Существуют две основные версии API – 1.0 и 2.0 (самих версий MIDP несколько больше, но в них изменения касаются безопасности и не затрагивают само API). IMP (Information Module Profile) – подкласс профиля MIDP для встраиваемых устройств, где не предполагается взаимодействие с пользователем. В этом профиле отсутствуют возможности работы с экраном. Foundation Profile – профиль для конфигурации CDC, не имеющий функциональности для работы с GUI. Предназначен для встраиваемых устройств. Personal Basis Profile – профиль для конфигурации CDC, содержащий основные элементы GUI. Является надстройкой над Foundation Profile. Personal Profile – профиль для конфигурации CDC, содержащий графический интерфейс пользователя, основанный на AWT. Является надстройкой над Personal Basis Profile. Дальнейшие возможности устройств обуславливаются поддержкой дополнительных пакетов, например, работа с мультимедиа – MMAPI (JSR-135).

Возможности API MIDP 1.0 были настолько ограниченны, что программировать даже простенькую игру — уже целая проблема. Проблемы MIDP понимали не только разработчики, но и производители телефонов, отчего стали массово плодиться проприетарные API, которые восполняли то, чего не хватало в MIDP 1.0. В основном это были графические и звуковые средства. Конечно, это лучше, чем ничего, но у такого подхода есть большой недостаток: приложения начинали целиком зависеть от наличия конкретного API в модели. А раз все компании делают API по принципу «кто во что горазд», то в итоге получалось, что либо приложение пишется под какие-то определенные телефоны одной фирмы, либо под куцый MIDP 1.0.

MIDP 2.0 свел на нет необходимость проприетарных API, но все старые программы и телефоны никуда не делись. Разработчики оказались перед нелегким выбором: либо писать под новые телефоны, забросив поддержку старых, либо опять химичить с MIDP 1.0 и специфическими API, чтобы не обижать владельцев старых телефонов. Многие разработчики так и продолжали писать мидлеты по старинке, плюнув на новый стандарт. Свою порцию неудобств прибавляли разные размеры экранов (тут дело даже не в разрешении, а в соотношении сторон) — это сильно затрудняло написание мидлетов.

Все это привело к полной неразберихе. Ситуация начала выправляться только к 2004-2005 годам. Свою роль сыграл JSR 75 с доступом к файловой системе — его разработчикам не хватало больше всего. Теперь аппараты поголовно выпускаются с MIDP 2.0 или JTWI - Technology for the Wireless Industry (JSR 185), и о поддержке MIDP 1.0 можно не беспокоиться.

PATH. WTK автоматически настраивает рабочую среду. Ранние версии требовали прописать путь к JDK в системной переменной PATH выходом через панель управления к установкам Система->Дополнительно. Кнопка "Переменные среды". Ставим точку с запятой после последнего прописанного пути, если ее там нет, и вводим путь к JDK к папке bin. После этого перегружаем компьютер.

СПЕЦИФИКАЦИИ БИБЛИОТЕК

JSR (Java Specification Request) – официальная спецификация какой-либо Java технологии или библиотеки, созданное сообществом JCP (Java Community Process).

Первой ласточкой JCP стал JSR 135: Java Technologies for Wireless Industry (JTWI). Вышел он вскоре после MIDP 2.0 и решил проблемы с проприетарными API. JSR 135 и JSR 120 отвечали соответственно за воспроизведение звука и пересылку сообщений. Новые устройства далее не будут MIDP 2.0 устройствами; JTWI (JSR 185) вытеснит их, см. также технологию подписывания. Время не стоит на месте, возможностей базовых API стало не хватать. Ну а раз JTWI поощряет ставить дополнительные стандартные API, в конце концов разномастных программных платформ стало слишком много. Да, во всех стоят только стандартные API, но вот как определить, пойдет ли приложение или нет, не сверяя списки требуемых и поддерживаемых API?

Тогда разработали новый стандарт, называемый JSR 248: Mobile Service Architecture (MSA). Он вышел в самом конце 2006 года и борется с самой главной проблемой предшественника: немощностью базового набора API. Есть два набора, урезанный и полный. В неполный набор входят: JSR 75 (File & PIM), JSR 82 (Bluetooth), JSR 135 (Mobile Media), JSR 184 (3D Graphics), JSR 205 (Messaging), JSR 226 (Vector Graphics). Это уже дает достаточно неплохие возможности, а полный набор добавляет еще следующие API: JSR 172 (Web Services), JSR 177 (Security & Trust), JSR 179 (Location), JSR 180 (SIP), JSR 211 (Content Handler), JSR 229 (Payment), JSR 234 (Multimedia Supplements), JSR 238 (Internationalization).

JSR 75: PDA Optional Packages. Под этим невнятным названием скрываются два пакета: Personal Information Management (PIM) и FileConnection API. Последний является одним из самых важных API в принципе. Почему? Потому что именно он дает доступ приложениям к файловой системе телефона и используется в самых разных приложениях. Если его нет — ни архиватор, ни плеер, ни редактор изображений на J2ME не запустятся. Функция второго пакета, PIM, — доступ к телефонной книге и календарю, но она практически не востребована, потому что как правило встроенные телефонные книги и календари неплохо справляются со своими функциями и замены не требуют, а других программ, которым понадобились бы такие данные, очень немного.

JSR 135: Mobile Media API (MMAPI). Он отвечает за базовые мультимедийные функции, например воспроизведение видео или запись звука. От него зависит, можно ли сделать под конкретную модель, например, диктофон. API построен очень гибко. Есть какой-то источник звука одного из трех типов: ресурс на мобильнике, файл в интернете, запись с камеры или с микрофона. Для источника создается плеер, который им управляет, а для плеера можно получить разные виды контроля. Например, можно контролировать скорость, темп или звук. В итоге на каждом отдельном мобильнике есть возможность реализовать какой-то набор контролей, какие именно — решает производитель. Иногда ограничивается число плееров, общее или какого-то отдельного типа. Иногда в играх во время воспроизведения звуковых эффектов останавливается фоновая музыка или в настройках нельзя одновременно включить музыку и эффекты. Это происходит именно из-за ограничения на количество плееров. При получении изображения функцией getSnapshot() - его разрешение равно разрешению, с которым телефон снимает видео. При этом оно сопровождается запросом: "Разрешить приложению фотосъемку?". Вопрос снимается опционно, в настройках телефона, или следует подписать мидлет каким-нибудь сертификатом, который распознается телефоном как "trusted". Тогда приложение будет установлено в trusted protection domain, и оно сможет делать многое без разрешения (скажем, фотографировать, открывать соединения и пр...), см. форум.

JSR 234: Advanced Multimedia Supplements API. JSR 135 создан уже достаточно давно, и в какой-то момент его возможностей стало не хватать. Для этого и предназначен этот API: дополнить мультимедийные возможности мобильной Java. Их список впечатляет: есть виды контроля над эффектами изображений, аудиоэффектами (например, эквалайзер, которого многим не хватало в JSR 135), над сохранением в различные форматы, есть управление камерой, FM-тюнером и даже поддержка трехмерного звука. Как и в случае с JSR 135, каждый производитель решает, какие виды контроля встраивать, а какие — нет. Управлять разрешением снимков можно используя класс javax.microedition.amms.control.camera.CameraControl предназначенными для этого методами getStillResolution(), getSupportedStillResolutions(), setStillResolution(int). Работать с видео можно используя класс CameraControl методами getSupportedVideoResolutions(), getVideoResolution(), setVideoResolution(int).

JSR 172: J2ME Web Services Specification. Этот API тоже делится на два пакета, хотя здесь они друг с другом связаны более тесно. Первый пакет — Remote Procedure Call (RPC) Package, который фактически позволяет послать на сервер какие-то данные в специальном протоколе и получить некий результат их обработки. А вот второй пакет, XML Parser Package, имеет очень широкое применение для документов в формате XML.

JSR 82: Java APIs for Bluetooth. С этим API все ясно уже из названия: если он есть, можно будет соединять два телефона по Bluetooth. Обычно это используется для совместной игры — соревноваться вдвоем куда интереснее.

JSR 120 и 205: Wireless Messaging API 2.0. Эти API дают возможность посылать и принимать сообщения. Первая версия давала возможность посылать только SMS или бинарные данные, а во второй можно посылать MMS.

Очень часто в характеристиках телефона пишут, что поддерживается Java 3D. Это тоже отдельный API, под которым обычно подразумевают JSR 184 — Mobile 3D Graphics API (сокращенно M3G). Это — стандарт де-факто для трехмерных приложений: большинство 3D-игр разработаны именно с его использованием. Этот API поддерживают аппараты Nokia, и Motorola, и Sony Ericsson... Еще есть относительно недавно созданный JSR 239: Java Binding for the OpenGL ES API. Этот интерфейс представляет собой поднабор OpenGL, используемого на компьютерах. В принципе, все то, что он может, можно реализовать и через JSR 184.

J2ME: Что к чему? | Дескрипторы | Обзор



Rambler's Top100