Monday, September 14, 2009

Tutorial : how to use the LED with Android phone

Some android phones have a nice LED ( but not all of them: I don't think the Galaxy has one ).

This LED can show lots of different colors, and adding this feature in your application is a nice little "plus" !
And it's really easy...


So how to do it ?

You just have to get the notification manager, and use it to send a flash Light notification.
The notification contains the color light, the duration with the LED On, and the duration with the LED off.

Here's the code :

private void RedFlashLight()
{
NotificationManager nm = ( NotificationManager ) getSystemService( NOTIFICATION_SERVICE );
Notification notif = new Notification();
notif.ledARGB = 0xFFff0000;
notif.flags = Notification.FLAG_SHOW_LIGHTS;
notif.ledOnMS = 100;
notif.ledOffMS = 100;
nm.notify(LED_NOTIFICATION_ID, notif);
}

LED_NOTIFICATION_ID is just a value to register this allocation. In my case, it is just 0.
Here, the LED will flash with the color given by the parameter ledARGB, in this case 0xFFff0000 (red ). It will be ON for 100 milliseconds, then OFF for 100 milliseconds, and then loop back ON, etc...

This is nice, but wait... How do I STOP it ?
This code will let the LED flash for ever !

To stop it, we have two solutions :
1) decide to only have the LED flash once, so in this case, you have to add the FLAG_ONLY_ALERT_ONCE flag :
notif.flags = Notification.FLAG_SHOW_LIGHTS | Notification.FLAG_ONLY_ALERT_ONCE;
2) Let the LED flash for as long as you want, then cancel the notification. In my case, I stop it after a certain amount of time by posting a message with a delay.
Here is the full code for this :

private void ClearLED()
{
NotificationManager nm = ( NotificationManager ) getSystemService( NOTIFICATION_SERVICE );
nm.cancel( LED_NOTIFICATION_ID );
}
private Runnable mClearLED_Task = new Runnable()
{
public void run()
{
synchronized( LetterGame.this)
{
ClearLED();
}
}
};

private void RedFlashLight()
{
NotificationManager nm = ( NotificationManager ) getSystemService( NOTIFICATION_SERVICE );
Notification notif = new Notification();
notif.ledARGB = 0xFFff0000;
notif.flags = Notification.FLAG_SHOW_LIGHTS;
notif.ledOnMS = 100;
notif.ledOffMS = 100;
nm.notify(LED_NOTIFICATION_ID, notif);
// Program the end of the light :
mCleanLedHandler.postDelayed(mClearLED_Task, LED_TIME_ON );
}


With mCleanLedHandler being just a handler, and LED_TIME_ON the flash duration.

Some notes :
1) Don't let a handler alive when changing activity ! On the OnPause of your activity, clear the handler :
mCleanLedHandler.removeCallbacks( mClearLED_Task );
2) programming the LED suffers one issue : the emulator does not emulate the LED at all... So you have to use a real device to see what it looks like ( but anyway, you always use real device at some point, don't you ? :) )
3) programming the LED then suffers a Second issue : when the real device is connected to your PC in order for you to develop / test / debug, the device is also charging the battery. And in this case, the LED is orange. Whatever notification you send ! So you have to test without your device plugged !


That's all !
With all that, you can code some nice LED flashes !!!

Thursday, August 20, 2009

Cupcake finally in France with Orange !


At last, it arrived !!

As you may already know from my previous article ( here ), here in France, the HTC Dream ( G1 ) was still running with a 1.1 version of Android.

And now an update to cupcake has finally been released by Orange !

So now, I have access to video recording, to the widgets, ... and above all, to all the applications that used the Cupcake API, and that we couldn't use till now ! ( it also means I will be able to try Python on my phone ! ).
That's not all !
This is a version coming from HTC, and in the package, we could also find :
* a PDF viewer ( it's nice to have a PDF viewer ! It's far from being uber performant, but, still it's here, and that a good point !!
* QuickOffice ( a office document reader : I tried it on several Word files, and it was OK, but for a big one - big being about 600 ko in my case, so not THAT big. Once again the performances are far from being stellar, but at least we can read some docs ! )
* A microsoft exchange mail reader and synchronization tool. Actually, I didn't tried it, but I'm sure a lot of people out there will be very happy with this !



But still I can't understand all that about this version :
* The installation is done via a PC, and we lose all of our data... That's not nice...
* We don't have any virtual keyboard ! That's a strange one... We still have the physical one, and I'm sure it is better. But in some cases, it's painful to open the physical keyboard just to type one word. And there are a lot of applications that don't deal that nicely with opening the keyboard...
* The last point is, in my opinion the worst of all : a lot of application are missing from the Android market.
To be sure to really understand what was happening, I created two void applications, one called OrangeTry, and the second called OrangeTry2.
I protected only the first one, and I released them ( for 5 minutes only )...
And guess what : only the second one appeared :

So this new version filters the protected applications !

I can't understand why they decided that ( actually, what I really think is that it is just a mistake ).
From what I understood from Google deal with the carriers, carriers are getting some money from the sell of Android applications !
As most paid applications are protected, this configuration will make Orange make less money than with the previous version ! How strange !

And I'm missing some free applications that were, for some reasons, protected ( this is a mistake : a protected version is about twice as big as the unprotected one ! ).
I'm particularly missing Dizzler !


A little question to finish this post :
Is there any carrier / country left where Cupcake has not been released ?

Tuesday, August 11, 2009

Tutorial : How to have two buttons on each side of the screen


Sometimes, things are quite confusing in the Android World.

I wanted to have one two buttons, on each side of the screen ( the famous next and previous buttons ).
I though it would be really easy to do.
I was wrong...

I had already done something quite similar for multiple column list view ( here ), but the trick I actually used for the multiple column view was not applicable here.
For the multiple column view, I could use a text view with a left aligned text, and another big text view taking all the remaining space with right aligned text.
As the textviews are invisibles ( only the text inside was visible ), the trick was unnoticable.


So now, my first try was to put my buttons in a linear layout, and have one with a right gravity, and another with a left gravity.
But it just failed : the two buttons were on the right, or the two buttons were on the left, but I couldn't obtain the result I wanted.

Finally, after some hours struggling with the documentations, some blogs, and the samples from the 1.1 SDK ( and my cat, but that is another story ), I found a way :


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/button_previous"
android:layout_height="wrap_content"
android:layout_width="110px"
android:layout_alignParentLeft="true"
android:textSize="15sp"
android:typeface="monospace"
android:textColor="#ffFFffFF"
android:background="@drawable/textview"
android:text="@string/PreviousButton"
>
</Button>
<Button
android:id="@+id/button_next"
android:layout_height="wrap_content"
android:layout_width="110px"
android:layout_alignParentRight="true"
android:textSize="15sp"
android:typeface="monospace"
android:textColor="#ffFFffFF"
android:background="@drawable/textview"
android:text="@string/NextButton"
>
</Button>
</RelativeLayout>

So I discovered the alignParentRight / alignParentLeft tags !

What are the lessons learned :
* Android GUI is not always as easy as planned
* The linear Layout, that is often the first choice, is often the wrong choice. Relative Layout is much more flexible.
* Where are the API Demos samples in the 1.5 SDK ?

Sunday, August 2, 2009

Cupcake finally coming for orange in France ?

Here, in France, Orange have sold the HTC Dream ( the G1 ) for several months.

But the Android version that came with the Phone was the 1.1...
And no update came since google had released Cupcake.

So I was quite surprised when Google send developers a mail to explain that "deployment of Android 1.5 is nearly complete"...

It looks like my phone is one of the last without Cupcake.
But now it looks like an update is finally coming 'in early august'...

I really hope so !

Monday, June 29, 2009

A C programmer in Android world : discovering Java allocations

I'm mainly, in my day world, a C / C++ programmer.
So I'm used with this language and sometimes, I feel like I would prefer to use another, more modern language !

So I was quite happy to try Java. I saw Java as a kind of modern, cleaner C++, with some nice features, and a more improved object model.

But for the 'WordProspector' game, in the process of taking the database out, and replacing it with 'something' else, more lighter (see here ), I found a serious limitation of this Java object model...


The issue :
As 'WordProspector' is a word game, it is shipped with a word dictionary.
At first, I stored the dictionary as a SQL database, as it was simpler for me at that time.
but when I found how memory costly it is, I decided to switch to another way to store it.

So I came up with a kind of tree with a letter for each node.
In my effort to compress the dictionary as much as possible, I found a way to store each node as a 8 bits integer plus a 16 bits integer, so it was 3 bytes.
So I had a Node class, with simply a byte and a short.
But I had a big number of node instances in my tree : something like 300 000 nodes.

So when I loaded the tree, I started by allocating all the nodes.
Allocating the nodes with java was something like :




NodeArray = new Node[nbNodes];

for ( int i = 0; i <>
NodeArray[i] = new Node();




When I tried it on the emulator... It took several minutes... Then the program crashed...
Too much allocations of this size !

I was amazed that I just couldn't easily create this really simple array !!

Then I discovered that allocations of simple type arrays didn't demand to allocate each element !

So finally, I get rid of my nice Node class, save the whole thing as a byte array, and interpret, on the fly, the byte array as a byte plus a short.
With that, the allocation is as fast as it could be :


NodeArray = new byte[nbNodes * 3];



Conclusion:
With this allocation issue, I had to get rid of my Node class, I just have a big array of bytes.
Acces to member are much more complicated, the code that was once so simple is now much more complex.
Add on this issue the fact that what I really wanted was an unsigned short, and not a short.
My code is now full of bits manipulation to create and interpret some bytes as unsigned short, or as bytes, depending of the situation.


With C/C++, I would never have this problem, and I would have a clean object code !