April 10, 2011

 

WTK 2.5.? key FIRE repeat bug and workaround proposed

WTK2.5 emulator has an annoying bug of repeating FIRE key in some circumstances.
Bug: in Canvas after first FIRE press/release method keyRepeat(FIRE) is called after each other key press (for example, after DOWN). Seems it's bug in WTK, cause in WTK 2.3 there's no such effect.
Workaround: test in your canvas constructor or in static init for
boolean wtk = System.getProperty(microedition.platform).toLowerCase().indexOf("wtk") != -1
After that return from keyRepeat() if wtk = true.

Labels: , , , ,

November 3, 2010

 

Pointer events bounce on clicks

Yesterday made simple experiment: recorded in log coordinates (x,y) of pointer press, drags and release events at real devices. During experiment I only clicked (not scroll!) at screen using finger. Devices are: Nokia 5230 and Samsung S5230.
Results impressed me a lot: bounce is up to 23 pixels (for y up to 15, possibly because of finger shape)!
This mean that if you need to differentiate scroll from click, you have to implement some kind of filter that takes into account time and type of movements of pointer.

Labels: , , , , , , , , , ,

June 23, 2010

 

Notes on Clipping and translation in MIDP

To make less mistakes in MIDP graphics it's important to know how is it work. Actually, MIDP docs and books I've read describes clipping and translation very superficially.
The notes 1 and 3 described below was some a surprise for me.
1. Graphics calculates and stores clipping: a) on each clipRect() call; b) in absolute (screen) coords.
Example:
clipRect(0,0,50,25)
translate(0,-25)
fillRect(0,0,50,50)
rect is painted with height 25
you could expect nothing on screen, but it's wrong.
2. (obvious) Graphics' clipRect() offset is expected in current translated coords. (see example below in (3))
3. Graphics always have clipping enabled (by default is's equal to the whole paintable area size, different depending on fullscreen mode).
Example:

translate(0,-25)
clipRect(0,25)
translate(0,25)
fillRect(0,0,50,50)
you get nothing painted, because on clipRect() call clipping was intersected with default clipping -> become (w=0,h=0) which is stored. On second translate call clipping area is not recalculated.

Labels: , , , ,

January 21, 2010

 

Battery level in J2ME

NOKIA:
System.getProperty("com.nokia.mid.batterylevel");

SONYERICSSON (via Sensor API, starting from JP-8.3):
SensorInfo[] batteryInfo = SensorManager.findSensors("battery_charge", null);
SensorConnection sensor = (SensorConnection)Connector.open(batteryInfo[0].getUrl());
Data data[] = sensor.getData(1);
String batteryLevel = "Current charge level: "+data[0].getIntValues()[0];

(from http://developer.sonyericsson.com/community/docs/DOC-2956)

Labels: , , , , ,

 

How to retrieve IMEI

Nokia
System.getProperty("phone.imei");
System.getProperty("com.nokia.IMEI");

Note ; Requires signed midlet. S60 3rd edition device does not requires signing for this to work.

Sony-Ericsson
System.getProperty("com.sonyericsson.imei");

Note ; might not work on all model.

Motorola
System.getProperty("IMEI");
System.getProperty("com.motorola.IMEI");


Samsung
System.getProperty("com.samsung.imei");


Siemens
System.getProperty("com.siemens.imei");

(from mobilepit.com)

Labels: , , ,

December 28, 2009

 

tele2 gprs: real ip! and some interesting udp stuff

The Tele2 cell operator provides a real (not from the private network) ip for phone, so it's possible to exchange UDP (just tested it) to WAN. The problem is that each time the phone enables GPRS it has different ip, even from different B class networks ;-)
By the way, I used the simple java udp echo server and simple midlet to test udp interconnection and latency.

Labels: , , ,

December 5, 2009

 

J2ME: Workaround for "Class NoClassDefFoundError not found"

When you compile for CDLC 1.0 if you use SomeClass.class, you could get this error: "class file for java.lang.NoClassDefFoundError not found".
There're two ways of workaround: compile for CLDC 1.1 or use this style:
Class class = Class.forName("package.SomeClass");
instead of:
Class class = package.SomeClass.class;, although it has the right syntax.

Labels: , , ,

July 24, 2009

 

[J2ME] deadlock in canvas.paint, lcdui

If you need to have a critical section in Canvas.paint() override, double-check that you do not lock in same monitor when calling myCanvas.repaint(). Problem exists in this some specific configuration, when you have 2 threads. In [1, main for example] you do:
display.setCurrent(myCanvas); and in [2, newly created] you call:
myCanvas.repaint() in same critical section as in your paint() impl.
I had deadlock in this case, at least in some LCDUI implementations. The reason is that MIDP usually have its own critical section in setCurrent() (when calling paint() for the first time) and in repaint() (when adding repaint event into queue), so it cannot both add repaint request into queue and enter your paint()'s your critical section. Deadlock. So be careful ;-)

Labels: , , , , , , , , ,

March 9, 2009

 

Поиск ошибок в программе

Все слышали выражение "проще переписать заново, чем исправить". Это придумали те, кто не может исправлять ошибки в программах. В чем же заключается исправление ошибки в сложном и незнакомом коде?
Я не буду рассматривать все пути (которых разумеется бесконечность, возможно, правда, счетная), а расскажу один из путей на основе своего опыта недавнего исправления ошибки. Это не будет ссылкой на формальную верефикацию программ, которая в чистом виде слишком дорога для применения по причине необходимости полной формализации системного окружения.
Первый этап - локализация ошибки. Зачастую, при сложных алгоритмах и/или при неграмотной архитектуре это самый трудоемкий этап. Что такое локализация? Это значит найти, какой код работает не так, как надо. Логичен вопрос: а как надо? Поэтому надо осознать, как должен был по задумке работать алгоритм. Это самая сложная часть, если не приходится разбираться в незнакомом и недокументированном куске программы. В этом случае приходится рисовать диаграммы и декомпозицией от большего к меньшему находить смысл всех условий и вызовов. Результатом для алгоритма будет блок-схема в терминах смысла действий (для невычислительных алгоритмов желательно описание на естественном языке, что на первой итерации упрощает анализ хода выполнения; если ошибка не будет найдена, скорее всего придется анализировать все блоки алгоритма более формально, см ниже.)
Поскольку мы рассматриваем случай, что не тот, кто написал, ищет ошибку, то можно предположить, что код работал некоторое время, а значит, появился набор данных, на котором он перестал работать так, как надо ("контрпример").
Для локализации можно сравнивать работу кода с рабочим примером по сравнению с контрпримером. Рабочий пример должен иметь минимальное отличие (неформально; чтобы ход работы алгоритма отличался минимально) от контрпримера для того, чтобы найти локализовать ошибку как можно более точно. Иногда можно локализовать ошибку просто сравнивая, какие куски кода срабатывают в каких ситуациях (ошибка в условном переходе или ошибка в самом коде).
Анализ хода выполнения выглядит так: достаточно нарисовать ход выполнения для рабочего и контрпримера в терминах построенной ранее блок-схемы (желательно на естественном языке) и сравнить полученные описания. Разница ходов выполнения и будет локализовывать с определенной детализацией ошибку.
В случае, если в обоих вариантах выполняется один и тот же код, значит ошибка носит "вычислительный характер". В этом случае анализ должен носить более формальный характер. Для этого можно разбивать алгоритм на блоки (функции) и проверять такие характеристики, как область определения и область значений каждого блока; граничные значения и поведение на них, устойчивость и другие. Для локализации ошибки нужно иметь означивания переменных для каждого стыка выделенных блоков, сравнить их с найденными значениями и это может локализовать блок (для которого уже можно повторить процедуру).
Исправление ошибки, в особенности в модуле, от которого зависят другие модули, всегда является отдельной непростой задачей, поскольку требуется обеспечить работоспособность этих модулей. Проблема обостряется, когда нет возможности легко (читай: дешево) внести изменения в зависящие модули. Но об этом позже.

Labels: , , ,

January 17, 2009

 

Comparing strings in Java - benchmark results

I've made benchmark for 2 different .equals() calls VS hashCode() comparing. Here are the variants:
1) constS.equals(variableS)
2) varS.equals(constS)
3) varHash (computed on each iteration) == constHash
4) varHash (computed before) == constHash (this is actually just int comparision!)
Note: my timer resulution seems to be 10ms.

The results on 1024000 iterations (run in interpreter mode) are:
Time: 170 ms.
Time: 180 ms.
Time: 461 ms.
Time: 40 ms.

With HotSpot, 1024000 its.:
Time: 20 ms.
Time: 20 ms.
Time: 60 ms.
Time: 10 ms.

So, it seems that the idea with preparing hashcodes to compare them with searched one later is very good idea. Also, it does not matter which one to compare to which one: var to const or vice versa.

Labels: , , , , ,

This page is powered by Blogger. Isn't yours?