LG Viewty Phone Wins Heart of Europe

LG Electronics is excited about European consumers' initial response to its latest strategic product, the Viewty phone.The company said Thursday that the first 200,000 units sold out in only three weeks in 14 European countries.The Viewty is a high-end five million pixel camera phone with a 3-inch wide screen. Most camera phones in the market have a picture resolution between 0.5 million and

LG Viewty Phone Wins Heart of Europe

LG Electronics is excited about European consumers' initial response to its latest strategic product, the Viewty phone.The company said Thursday that the first 200,000 units sold out in only three weeks in 14 European countries.The Viewty is a high-end five million pixel camera phone with a 3-inch wide screen. Most camera phones in the market have a picture resolution between 0.5 million and

SAMSUNG Anycall J208

New device fuses full Web-browsing with simplicity and ingenuity(Hong Kong, 21 November, 2007) – Samsung Electronics today introduced its latest 3G handset – the stylish candy bar SAMSUNG Anycall J208 – bringing novice 3G users supreme connectivity and video quality, putting the world within reach no matter where one travels.The J208 is equipped with a 262K TFT color display, a dual camera with

SAMSUNG Anycall J208

New device fuses full Web-browsing with simplicity and ingenuity(Hong Kong, 21 November, 2007) – Samsung Electronics today introduced its latest 3G handset – the stylish candy bar SAMSUNG Anycall J208 – bringing novice 3G users supreme connectivity and video quality, putting the world within reach no matter where one travels.The J208 is equipped with a 262K TFT color display, a dual camera with

Unlocked iPhone for 999€ - T-Mobile Germany

In a move to combat Vodaphone's legal challenge, Germany's Deutsche Telekom (T-Mobile) will sell a unlocked iPhone for 999 euros (Roughly $1,500 USD). This will make the first official unlocked version of an iPhone. Looks like this game is getting interesting. The big bad Apple has to give in on its stance of a locked device. What does this mean moving forward? Will people be willing to pay for this unlocked iPhone just to avoid a lengthy contract? Will Apple frown upon folks who imported the legitimate unlocked iPhone to the US or worst yet, other countries where Apple has not reached? Will Apple enforce the same stupid two-phone limit AND must be purchased on a Credit Card rule towards these outrageously priced unlocked phones?

Source: Reuter, Engadget

FORENSIC RECRUITMENT

FORENSIC RECRUITMENTI get alot of enquiries asking about computer and mobile telephone recruitment. I try and answer as many queries as I can but I can't deal with all enquiries for those seeking employment. Moreover, it seems to me, at any rate, that alot of enquiries I get would be better directed to a recruitment consultant who specialises in this area and is more able to deal with the

A Stitch in Time



Background: While developing my first useful (though small) application for Android, which was a port of an existing utility I use when podcasting, I needed a way of updating a clock displayed on the UI at regular intervals, but in a lightweight and CPU efficient way.



Problem: In the original application I used java.util.Timer to update the clock, but that class is not such a good choice on Android. Using a Timer introduces a new thread into the application for a relatively minor reason. Thinking in terms of mobile applications often means re-considering choices that you might make differently for a desktop application with relatively richer resources at its disposal. We would like to find a more efficient way of updating that clock.



The Application: The rest of the story of porting the application will be detailed in future blog entries, but if you are interested in the application in question and the construction of it, you can read about it in a not-so-recent Developer.com article about using Matisse (a GUI builder for Swing). The original application is a Java Swing and SE application. It is like a stopwatch with a lap timer that we use when recording podcasts; when you start the recording, you start the stopwatch. Then for every mistake that someone makes, you hit the flub button. At the end you can save out the bookmarked mistakes which can be loaded into the wonderful Audacity audio editor as a labels track. You can then see where all of the mistakes are in the recording and edit them out.



The article describing it is: http://www.developer.com/java/ent/print.php/3589961



In the original version, the timer code looked like this:



class UpdateTimeTask extends TimerTask {
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;

timeLabel.setText(String.format("%d:%02d", minutes, seconds));
}
}

And in the event listener to start this update, the following Timer() instance is used:

if(startTime == 0L) {
startTime = evt.getWhen();
timer = new Timer();
timer.schedule(new UpdateTimeTask(), 100, 200);
}


In particular, note the 100, 200 parameters. The first parameter means wait 100 ms before running the clock update task the first time. The second means repeat every 200ms after that, until stopped. 200 ms should not be too noticeable if the second resolution happens to fall close to or on the update. If the resolution was a second, you could find the clock sometimes not updating for close to 2 seconds, or possibly skipping a second in the counting, it would look odd).



When I ported the application to use the Android SDKs, this code actually compiled in Eclipse, but failed with a runtime error because the Timer() class was not available at runtime (fortunately, this was easy to figure out from the error messages). On a related note, the String.format method was also not available, so the eventual solution uses a quick hack to format the seconds nicely as you will see.



Fortunately, the role of Timer can be replaced by the android.os.Handler class, with a few tweaks. To set it up from an event listener:



private Handler mHandler = new Handler();

...

OnClickListener mStartListener = new OnClickListener() {
public void onClick(View v) {
if (mStartTime == 0L) {
mStartTime = System.currentTimeMillis();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 100);
}
}
};


A couple of things to take note of here. First, the event doesn't have a .getWhen() method on it, which we handily used to set the start time for the timer. Instead, we grab the System.currentTimeMillis(). Also, the Handler.postDelayed() method only takes one time parameter, it doesn't have a "repeating" field. In this case we are saying to the Handler "call mUpdateTimeTask() after 100ms", a sort of fire and forget one time shot. We also remove any existing callbacks to the handler before adding the new handler, to make absolutely sure we don't get more callback events than we want.



But we want it to repeat, until we tell it to stop. To do this, just put another postDelayed at the tail of the mUpdateTimeTask run() method. Note also that Handler requires an implementation of Runnable, so we change mUpdateTimeTask to implement that rather than extending TimerTask. The new clock updater, with all these changes, looks like this:



private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
final long start = mStartTime;
long millis = SystemClock.uptimeMillis() - start;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;

if (seconds < 10) {
mTimeLabel.setText("" + minutes + ":0" + seconds);
} else {
mTimeLabel.setText("" + minutes + ":" + seconds);
}

mHandler.postAtTime(this,
start + (((minutes * 60) + seconds + 1) * 1000));
}
};


and can be defined as a class member field.



The if statement is just a way to make sure the label is set to 10:06 instead of 10:6 when the seconds modulo 60 are less than 10 (hopefully String.format() will eventually be available). At the end of the clock update, the task sets up another call to itself from the Handler, but instead of a hand-wavy 200ms before the update, we can schedule it to happen at a particular wall-clock time — the line: start + (((minutes * 60) + seconds + 1) * 1000) does this.



All we need now is a way to stop the timer when the stop button is pressed. Another button listener defined like this:



OnClickListener mStopListener = new OnClickListener() {
public void onClick(View v) {
mHandler.removeCallbacks(mUpdateTimeTask);
}
};


will make sure that the next callback is removed when the stop button is pressed, thus interrupting the tail iteration.



Handler is actually a better choice than Timer for another reason too. The Handler runs the update code as a part of your main thread, avoiding the overhead of a second thread and also making for easy access to the View hierarchy used for the user interface. Just remember to keep such tasks small and light to avoid slowing down the user experience.



So that's it for the first of what will be a series of Android tips. Hopefully this will save you a little head scratching on what will probably be a fairly common thing to want to do (i.e. make something happen or update at regular intervals in a lightweight way in your application). There is plenty of more material from my experience of porting this very simple application which will be covered in some of the future "tips" articles. There are some other great tips being discussed as well as an opportunity ask questions at the Android Developers Discussion Group.