Thursday, December 10, 2009

How to improve your application : a crash reporter to improve stability !

What is a crash reporter :
One condition for success, when shipping an application is that it should be as stable as possible !
And to achieve this, you have to test as deeply as possible your application. But :
1) If you are alone, it is a time consuming task,
2) It's still easy to miss some bugs, some special cases.

On the other hand, if you have a lot of users, the application will be launched a lot of times, a lot of special cases will be experimented by users, so they will suffer from unexpected crashes.

So we have to collect informations on the crashes that occurs on the end user device !
This is what a crash reporter is doing : whenever your application crash (and don't be over confident, it WILL happen ), it sends you informations on the conditions of the crash...
Don't get me wrong : the end users should not be your testers. If your application is full of bugs, they won't use it anymore, and you're just loosing your time ! But if you estimate your application is safe enough, and that you can't find any more bugs, publish your application with a crash reporter : you'll see all the 'other' bugs. The ones that result from situation you didn't imagine, and that really happen on your customer mobiles !

So what is in the crash reporter :
A crash is made of two different parts : the first one that collects information, and the second one that sends this information to you.

Note that there are already some packaged solutions for this, like this one :
http://code.google.com/p/android-remote-stacktrace/

But I preferred to create my own one (is it a good solution ? )

What to report ?

For each report, I chose to report as much information as possible. That includes :

  • The callstack
  • The information about the system that android provides me ( like the device type, the OS version, the application version, ...)
  • The avalaible memory ( memory is one of the most common issue in small mobile world ).


How to report ?
Most of the crash reporters I saw or heard about are using a Http connection silently opended to send the information to a Php wbe server that will store the issues in a database.

But I prefered to simply use mail :
Pro :

  • Simple to implement,
  • No server side code to make / test / debug,
  • gmail will automatic dealed with cases where there is no internet connection, 
  • Let the customer know that his problem is taken care of,
  • Let the customer know exactly what informations he sends you,
  • Involve the customer in the quality of your program ( if he didn't send a report, he can hardly complain the application is still bugged, so he 'should' be more tolerant).


Cons

  • All customer won't send the report !
  • Some customer could fake it ? That would be strange, but we definitively live in a strange world... So better be prepared to it !!
  • If you have a lot of bugs / a lot of customers, you can finally have a lot of mail to treat !
  • A Web/database solution is way easier to use for creating analysing tools ( like counting the occurences of each bugs, linking it to a version, etc ... )


So as you can see, each solution has some advantages. I would say if your application is big, go for a web/database solution.
In my case, I knew ( actually I hoped ) I hadn't a lot of bugs, so I chose the mail solution BECAUSE IT IS WAY SIMPLER TO DO !!

So here is the code :

Monday, December 7, 2009

Introducing the X Phone




Sorry...
Couldn't help...

(note that it is in German, but you don't need to understand what is said to fully appreciate this video )
- thanks Dom for this link !!

Monday, November 9, 2009

Google To Acquire AdMob

It is official : AdMob is now part of Google !

This is kind of funny :
Google is the giant Leader of virtual ads.
But on its own OS, its ads solution is still not ready ( it is still in beta state for the moment, and only avalaible for people with 100 000 pages views / day -sic- )...

So it just bough the current leader on mobiles !

Wednesday, October 28, 2009

Tutorial : How to customize your toasts !

Toast, despite their strange name that an average french developer like me doesn't understand, are really usefull in Android world ! Specially for developers !

The Standard Toast with butter :
It is obviously a easy and quick way to send text feedback to the user and the developer ( as it is a nice tool to give feedback ).
Toast.makeText(mCurActivity, text, Toast.LENGTH_SHORT).show();

This line has been used such a number of times in my programs, and in many others !


The Toast with orange jam :
But the standard 'look and feel' of your toast does not necessarily fit your application's look. And the default position can be a issue too.
In Word Prospector, I give feedback on whether the word is correct with a toast. But at first this toast was over my game board, preventing the player to click on some letters !

Then enters the toast customisation !!



Here's I changed the position of my toast, in order to have it in the right - bottom corner, and its background, so it's like the others gui element of the page !

To change the toast position, you have to use the setGravity Toast method. You have to provide the gravity of your toast ( this strange Android beast that indicates where your gui element will end up being ), and you can refine this position by some offsets.

To change the style of the toast is also easy :
The default toast is made of a textView.
You can actually access this textView, and change anything you want inside ( in my case, the background image, but you can imagine changing the font, or the text color / size, ... )

Here's my code to change the pos and the background :
protected void ToastMessage( CharSequence text, int ToastPos )
{
Toast toast = Toast.makeText(mCurActivity, text, Toast.LENGTH_SHORT);
View textView = toast.getView();
switch ( ToastPos )
{
case TOAST_LEFT_POS:
toast.setGravity( android.view.Gravity.BOTTOM | android.view.Gravity.LEFT, 00, 0);
break;
case TOAST_CENTER_POS:
toast.setGravity( android.view.Gravity.BOTTOM | android.view.Gravity.CENTER, 00, 0);
break;
case TOAST_RIGHT_POS:
toast.setGravity( android.view.Gravity.BOTTOM | android.view.Gravity.RIGHT, 00, 0);
break;
}
textView.setBackgroundResource( R.drawable.textview);
toast.show();
}


The toast with butter, and orange jam, ... and some chocolate...
Do you want more customisation ?
You can actually change the textView inside the toast by any view you want... Any view.... Including a custom view declared in a Xml file, and that you can inflate inside your toast...
In this case, you can easily add several lines, or images, or whatever you want !

No Toast with orange jam and chicken wings allowed !!
Despite being a really nice to tool to master, the toast is limited in two ways :
* You don't have control on the toast duration. Actually there are only two states LENGTH_LONG and LENGTH_SHORT. Note that I imagine you can force the closure of a toast with the cancel method ( I didn't test it )
* More important : you can't have several toasts at a time ! So if you need to display a new toast and old one is already present, the new one will be queued by the system, and wait for the old one to disappear. At some times, it can be a important limitation, as it means you can't control the feedback your giving will apppear at the correct moment !
You can try to close the first one in order to display the new one ( with the cancel method... Remember ? The one I didn't test ), but in some cases the two toasts should be at different places, and you want the user to see and have time to read both of them !

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 !

Saturday, June 20, 2009

Tutorial : How to access a Android database by using a command line.

When your start dealing with a database in your program, it is really important and useful to be able to access it directly, outside your program, to check what the program has just done, and to debug.

And it is important also on Android.

Here is how to do that :

1) Launch the emulator (or connect your real device to your PC ). I usually launch one of my program from Eclipse for this.
2) Launch a command prompt in the android tools directory.
3) type adb shell.
This will launch an unix shell on your emulator / connected device.
4) go to the directory where your database is :
cd data/data
here you have the list of all the applications on your device
Go in your application directory ( beware, Unix is case sensitive !! )
cd com.alocaly.LetterGame
and descend in your databases directory :
cd databases
Here you can find all your databases. In my case, there is only one ( now ) : SCORE_DB
5) Launch sqlite on the database you want to check / change :
sqlite3 SCORE_DB
From here, you can check what tables are present :
.tables
6) enter any SQL instruction you want :
select * from Score;

This is quite simple, but every time I need it, I don't know where to find it.

Tuesday, June 9, 2009

Developing with Python on Android : a dream comes true ?

Google still innovates and offers as many tools as they can to us developers !

I'm a big fan of Python, and several times, I wanted to try things on my phone, but without having a development PC around me.
Now they combines both of my implicit wishes, and we can develop in python (and LUA, BeanShell, and other langages to come ) from the mobile !!
I'm really excited about that.

Next question is :
Could I embed my python script that I developed on my phone in a real Java application ?
That would be awesome : it would mean I really could develop parts of my application from my phone, or even have a scripted part of my application that could evolve without a PC !!!

Waaaa...

Thank you, Mr google !!!


Google Open Source Blog: Introducing Android Scripting Environment

Edit :
Sadly, this application is for Cupcake only, so I can't use it...
I will have to wait for Cupcake to be avalaible on my phone.
That makes me wonder how many phone are still stuck with the 1.1 OS ?
From what I've read, in the US, the update is finished, so there should be no 1.1 left.
But outside US ???

Wednesday, May 27, 2009

How to ship an application with a pre baked database...

And why you should probably not doing it !


1) Why did I tried that
When I first started to program 'Word Prospector', my word game on Android, I already had a Pc game of this kind, written with my Python / C++ 2D engine.
The dictionary part, in particular, was in C. It was brute force : I just compared the input string with every word in my dictionary ( with 300 000 words ! ), and it was just Ok !

When I tried to do the same thing on the Android emulator ( the real device hadn't shipped yet here in France ), it was horribly slow ! Actually the worst part was loading a big array of words. Launching the game, on the emulator, was something like 20 minutes !!! Even if the real device could do better, I couldn't take the risk !
So my first though was to try to use native code for the dictionary. And the SQL database was native code.
I tried it, and the results were good : no loading time, no sensitive time to check if a word was in the dictionary...

So how to do that ?

2) Create the database on the device ( with the emulator )
The first thing to do, in order to have a pre baked database, is to create it !
So that is what I did.
I launch the game, loading all my dictionary, and inserting every word in my database. It took something like 20 minutes or more, but after that, I had a complete database, somewhere on my emulator.

3) Get the database from the device to the Pc
That step is quite trivial, but only once you know how to do it !
The simpler to do it is through Eclipse :
* launch the emulator from within eclipse,
* Open the DDMS perspective ( Windows / Open Perspective / Others... / DDMS )
* Look for the database file : its located in the data/data/YourApplicationPackageName/Databases/ directory, and its named with the name you give the database.
* Click on this file, then click on the little icon on the upper right of the DDMS window called 'Pull a file from the device' ( see the screen shot below ).
* Give the directory on your PC you want to copy the file to.
* Wait till its done. As my file was really big, sometime, this step fired a timeout beofre it could properly finish. But doing it again was enough to have it.

DDMS Get a File From Device

Note that the purist can also do it with a command line.
Something like 'adb pull NameOnDevice NameOnPC'


4) Splitting the file
NOTE : THIS STEP IS NOT MANDATORY !!!
See the "Edit2" point at the end of the post for an explanation !!!!!
This file was pretty big, about 5 Mo.
A prebaked database will be a raw file in the resources.
But in the resources, files are limited to 1 Mo, so in order to provide a prebaked database, I had to split my database.
Here is the Pc side java method that did it :


private static void CutFilesInSizeParts(String InputFileName, String OutputFileName, int MaxPartSize)
{
try
{
File f = new File(InputFileName);
FileInputStream fis = new FileInputStream(f);
int TotalLength = fis.available();
byte[] buffer = new byte[ TotalLength + 1 ];
int len = fis.read( buffer );
int nbPart = len / MaxPartSize + 1;
int CurPos = 0;
for ( int i = 0; i < nbPart; i++ )
{
int PartLen = MaxPartSize;
if ( CurPos + PartLen >= len )
PartLen = len - CurPos;
String outRealFileName = OutputFileName + (i+1);
FileOutputStream fos = new FileOutputStream(outRealFileName);
fos.write(buffer, CurPos, PartLen);
CurPos += PartLen;
}
}
catch( IOException e)
{
System.out.println("issue");
}
}



I then could copy this generated parts of my database in the res/raw directory of my Word Prospector project.

5) Last step : creating the database file in your program
Some notes :
* We need to know the directory where to create the database. The getDatabasePath method is our friend here, but need a database as an argument ! So we will always start by using a SQLHelper that will create the database if it's not already present.
* We only need to recreate the database the first time the application is launched. After that, the file is created, everything is OK. So we can put a request on the database to see whether or not it is populated, and only copy the files if it is not populated.
* Creating the whole database file, is just appending all the database in the the file !

So here the code :


public void CreateFromRawDbFiles()
{
// Creation of an empty database if needed, with SQL Helper :
CreateMinimum();
// check for emptyness ( try a request on the database ) :
if ( !bIsDatabaseInstallationNeeded( ))
return;
// if empty, overwrite the file from ressources :
// Get file dir :
String DBFileName = mOwner.getDatabasePath( MY_DATABASE_NAME ).toString();
ConstructNewFileFromressources( DBFileName );
}

public void ConstructNewFileFromressources( String DBFile )
{
//Log.v("DataBase Installation", "Before creating files");
int ResourceList[] = new int[] {
R.raw.my_dico_db1,
R.raw.my_dico_db2,
R.raw.my_dico_db3,
R.raw.my_dico_db4,
R.raw.my_dico_db5,
R.raw.my_dico_db6
};
try
{
FileOutputStream Fos = new FileOutputStream( DBFile );
for ( int FileId : ResourceList )
{
InputStream inputFile = mOwner.getResources().openRawResource(FileId);
int TotalLength = 0;
try
{
TotalLength = inputFile.available();
}
catch ( IOException e)
{
Toast.makeText( mOwner,"Error Reading File",Toast.LENGTH_SHORT).show();
}

// Reading and writing the file Method 1 :
byte[] buffer = new byte[TotalLength];
int len = 0;
try
{
len = inputFile.read(buffer);
}
catch ( IOException e)
{
Toast.makeText( mOwner,"Error Reading File",Toast.LENGTH_SHORT).show();
}
Fos.write( buffer );
inputFile.close();
}
Fos.close();
}
catch( IOException e)
{
Toast.makeText( mOwner,"IO Error Reading/writing File",Toast.LENGTH_SHORT).show();
}
//Log.v("DataBase Installation", "End of creating files");
}






And that's all !!
Creating the database file was really fast, and only happens on the first launch, so everything was quite perfect...

BUT...

6) Conclusion : was it really a good idea ?
The first issue with this technique is : how solid it is ?
It looks like a hack and I felt a little unsecured with this.

But the real, terrible issue was somewhere else : the application size !
The database is really present twice with this technique : once in the .apk ( hopefully in a compressed form ), and the second time, as the real database file.

In the Word Prospector case, I finally had a game that weighted 2 Mo on the market, but once fully installed was 7 Mo !!! ( and for the french version it was even worse : the installed version was 9 Mo ) !

People are not used yet to check the size of your application, so it took some time before some one complained on the market, but it finally happened ! And even I, now that I have the device, was feeling it was really unpleasant !

Finally, I developed a algorithm to store my dictionary as a compact letter - tree, and got rid of this database !
Word Prospector is now about 700 ko !
And the french version, 'Chasseur de mots' is about 500 ko ( for some reasons, the french dictionary is much more compression friendly ).
It took me two evenings to create and implement this tree, I really should have done this in the first version !!

The real conclusion is : if you want to ship your application with a prebaked database, you can still do it. But beware the weight of your application. If your database is big, think about it twice, and try another way...

As an android user, my experience is : the bigger the application, the sooner I will get rid of it !!


EDIT : Read somewhere a good practise to avoid to have twice the database in your installed program : don't include it in your .apk, but post it somewhere on a website.
This way, the program will start by downloading it ( with a nice dialog box to explain it is only for the first time ), and it will then be only present in the database folder, so everything will be OK !

EDIT2 :
Actually, the point concerning the split of the database ( and the construction with several resource files ) is not necessary :
I was putting the database file in the resouces / Raw folder, and there is a 1 Mo by file limitation for every files in the ressources.
But you can also put this file in the asset folder, where no more size limitation exists !!!

Monday, May 18, 2009

Bouygues Telecom confirms the Samsung I7500 launch in France

I suspected it  ( here ), but it is now official :
Bouygues telecom will launch the Samsung i7500 in France.

Named 'Galaxy', the next Android phone should be launched in France in early July.
So now, every French carier will have its own Android Phone :
Orange was the first, launching the G1 ( called HTC Dream )
SFR then launched the HTC Magic a couple of weeks ago
And now Bouygues Telecom will have the Galaxy !

Here is the official announce

Tuesday, May 12, 2009

Priced appli for some european developers !

Coupled with the access to priced application for users from France, Italy, Spain, and the Netherlands, developers from Germany, France, Spain, the Netherlands, and Austria can now submit priced applications !

Here is an extract from the mail we received :

"I'm writing to let you know that priced applications are now available in
Android Market for users in France, Italy, Spain, and the Netherlands.
You can target one or more of these countries in the publisher website at
http://market.android.com/publish by selecting the individual checkboxes
or by choosing "All Current and Future Locations," which will make your
priced apps appear to users in all countries where priced apps are
available. Priced applications are now available to users in eight
countries: United States, UK, Germany, France, Italy, Spain, the
Netherlands, and Austria.

We have also added seller support for developers from Germany, France,
Spain, the Netherlands, and Austria. Developers from these countries can
now go to the publisher website to publish their priced applications.
Google Checkout serves as the payment and billing mechanism for Android
Market in all countries. Developers who do not already have a Google
Checkout merchant account can easily sign up for one via the publisher
website. Developers can find more information about priced applications
in Android Market at http://market.android.com/support/."

We can now buy priced applications from France !

We, Android developers, received a mail last week to inform us Google will add buyer support for priced apps in France, Italy, Spain, and Netherlands, in 'a couple weeks'...

But it looks like it took them less time, as we can see priced application now from France ( and I imagine it's the same in Italy, Spain and Netherlands ) !

It means the market is expanding !!

Now I have to wait the possibility for us, non-US non-UK developers, to offer priced applications !

Monday, April 27, 2009

Will Bouygues Telecom be the first one to launch the Samsung I7500 in France ?

Today, the first live photos of the Samsung I7500 were found on Mobile-Review ( here ).







And tada....

What do we see in this screen ?

The Bouygues Telecom logo !!
Bouygues Telecom is one of the three telecom operators in France.
Orange has already launched the HTC Dream earlier this month,
SFR should launch the HTC Magic in May.

And we were missing any announce from Bouygues Telecom for the android market.

Looks like we have something like an answer here !

Saturday, April 25, 2009

French Descriptions avalaible in the market !

I made a french version of my game "Word Prospector".
It's another entry in the Android Market, and it's called "Chasseurs de mots".

And I think it's one of the first French independant game, and the first French Word Game !

As it is a French game, it made sense to put a french description. 
But some people couldn't understand this description and gave me a bad rating just because of this !

But since yesterday, the Android Market has added 6 new languages, and French is one of them.

So I could put a french description, in French, and a english description that says it is a French game ( and that there is a english version ! ) !

Android Market with French language

Thanks Google !


Ps : I would like to thanks, even if I really doubt they will ever read this, the users that gave me some good ratings just to counter the ones that gave me bad rating for a poor reason !

Sunday, April 19, 2009

Word Prospector is out now !

Hi all,


I've been quiet for so long time, because I finished and published my first Android game : Word Prospector...

The game is out for 15 days now, has been downloaded about 1800 times, and has generated 10 000 ad requests ( from admob )...

As anybody who published a application, I learned a lot from the whole process, and there are plenty of enhancements that I want to add...



Wednesday, February 25, 2009

Multi columns in listView

Hi all,

I read some articles on multicolumn in a list view with android.
As I worked on this subject, I can show you where I could get.

I tried to work on resolution independant list view, so I tried to place the columns relativelyto the screen, rather than relying on absolute coordinates. This way, the result should be correct, whatever the phone ( /notebook ? ) resolution, or whether you are on landscape or portrait mode.

The difficult part is to find the correct layout to pass to your adapter.
My first try was to have a column on the left side and a column on the right side.
Sound easy, but my first tries couldn't make it.

That was my first try for an line layout :



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent">
<TextView
        android:id="@+id/PlayerName"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Nom"
        />
<TextView
        android:id="@+id/PlayerScore"
android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:gravity="right"
        android:text="score"
        />
</LinearLayout>



But it failed... Both entries were stacked on the left of the screen...

I tried both to set the gravity and the layout_gravity to 'right', but it didn't change anything.

The solution was with the width of my second text view. 
I imagine that I couldn't have the two textview width set to 'wrap content', because it couldn't fill a whole line.

So the trick was to have one textView width set to fill parent, the second one to wrap _content, and to have the text placed on the right of the second textView, using the gravity parameter.
But, for some reason, you can't set the first textview width to 'fill_parent'.
I imagine that in this case, the first textview will take all the parent width, and won't let any place for the second one. And when the second textView width is set to 'fill_parent', it will take all the place, but taking into account the space taken but by the first, already initialised, textview.

Here's the working code anyway :


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent">
<TextView
        android:id="@+id/PlayerName"
        android:textColor="#ffFFffFF"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Nom"
        />
<TextView
        android:id="@+id/PlayerScore"
android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:gravity="right"
        android:layout_marginRight="25dip"
        android:textColor="#ffFFffFF"
        android:text="score"
        />
</LinearLayout>



Just a note : I add a right margin for the second text view, to reserve some space for the listview scrollbar ( without it, the text was behind the scrollbar ) !

Then I tried to have a three columns layout, with one column on the left, one column in the middle, and the last one on the right.
To be honest, I tried anything I could think of in tweaking the precedent code, with no success !

Until I tried to use a relative layout instead of a linear layout !

With a relative layout, the first try was the good one :


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" 
                android:layout_height="wrap_content"
 >
<TextView
        android:id="@+id/Center"
android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_centerHorizontal="true" 
        android:textColor="#ffFFffFF"
        android:text="Center"
        />
<TextView
        android:id="@+id/PlayerName"
        android:textColor="#ffFFffFF"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_toLeftOf="@+id/Center"
        android:text="Nom"
        />
<TextView
        android:id="@+id/PlayerScore"
android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_toRightOf="@+id/Center"
        android:layout_marginRight="25dip"
        android:textColor="#ffFFffFF"
        android:gravity="right"
        android:text="score"
        />
</RelativeLayout>




Now I still have a question in the back of my mind. 
This reminds me my early web development, where I tried to tweak HTML code to have resoution independant pages. HTML was designed for that !
And some years after that, every serious website is designed to be view in a fixed resolution.

So my question : is it worth it ?
For the moment, only one android device exist, so resolution independance is not a question.
And I feel like all the upcoming phones will have the same resolutions, and that every layout will be design with absolute pixel values... Wait and see ?


Wednesday, February 4, 2009

Tutorial : how to emulate an SD card with the Android emulator

It's important to know how to emulate an SD Card if you're into Android development.
Whether it be because your application actually use it, or to use it for your development, for instance for profiling.

Here are the required step to use an SDCard :

1) Create the emulated SDCard on your real computer :

Google provides a tool just for that, in their SDK/tools directory called mksdcard.
just give it the size of the SdCard you want to create ( in kilobytes or megabytes ) , the name of the resulting file, and you're done :
Open a command prompt, go to your SDK/tool directory, and type :
mksdcard 64M MyNewSdCard

and that's it !

2) Using the emulated SDCard with the emulator

To use the emulated SDCard in the emulator, simply launch the emulator with the '-sdcard EmulatedCard_File_Path' parameter :
So, from the command prompt in the SDK/Tool directory, type :
emulator -sdcard MyNewSdCard

3) Using the emulated SDCard with the emulator from Eclipse :

From eclipse, open the menu entry :
Run / RunConfigurations...

Then on the right panel, choose 'target'
And in the Additionnal Emulator Command Line Options, add
'-sdcard fullPath_to_your_SdCard_File'



And that'all !

4) How to explore the emulated SdCard content and push / pull files from your computer :

Within Eclipse :

Open the DDMS perspective :
Window / Open Perspective / Other... / DDMS

Now select the file explorer tab ( in the right panel ), and you have acces to a classic explorer of your emulated phone, including the sdcard !

Now to push a file from your computer, or pull a file from the emulated device, you have two discrete icons in the upper right corner :


Just use them to to browse and select on your computer the file to pull or push !

Without Eclipse :

Just launch DDMS from the command prompt in the SDK / tools directory.
The file explorer is in the device menu...

Monday, February 2, 2009

How I improved my android application responsiveness in the emulator... without doing anything !

It's been a long time since I found the Android application I'm developping ( a word game ) was not as responsive as I would like.
As I don't have any kind of Android phone, all of my testing happen in the emulator, and I'm not sure how well it fits the phone reality ( and actually, I'm aware that this does not mean anything, as there may be a lot of different phones out there... ).
But still, I expected the emulator to be in scope with reality, and to give me a good start to measure responsiveness ( and actually, I have no other choices ).

So the responsiveness of my application was below my expectations, and I had planned a optimization phase to fix it as much as I could.

And yesterday, I found myself manipulating my game, and finding it was responsive enough for me !
It took me a little time to understand what had changed, as I never tried to optimize it, and my last developments were GUI / cosmetic changes !

Actually, I had disconnected the debugger !
When my application is running with eclipse connected to it, it is way slower than it is without it !

Although it is a simple optimization, and quite reassuring for my game, it is the second time that having eclipse connected to the emulator gets in my way ( the first time being with the profiler : here ).

And that is more perturbing...

Thursday, January 29, 2009

How to have a tiled background ( cont.)

Thanks to Romain Guy, I finally could add a repeating background in my Android application !

I'm still using in my layout definition the same way to define the background, with a androidbackground parameter, with the path to your repeating background ( actually that was the point : having a consistent way for background, let them be tiled or not )

xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/MainLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="@drawable/backrepeat"
>
...

in my drawable directory, I have a back.png file (  the background I want to tile ), and I create this new backrepeat.xml file :
 <?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/back" 
    android:tileMode="repeat" />


Some points :
* I think my first tries failed because I forgot the 'xmlns:android' parameter.
* I tried without the xml version line, and it still works, but I think I will let it be there... Just in case !
* The tilemode can be repeat, mirror, or clamp.
* Although in Java, I could set a different repeat mode for X and Y, I don't think it is possible in the Xml file. Not that I really care for the moment :)

That's all !
Thanks again Romain ! 
I know it is your job, as a Android engineer, to evangelise and help us, but several times you really helped me, you were quick to answer, with concise and most useful answers...

Saturday, January 24, 2009

How to have a tiled background

Today, I wanted to have a tiled background in my activity.
Until now, my android application only had a stretched image, so I though it was a good time for a change !

Having a background pattern that repeat itself seems like a very common idea, in particular on mobile development where you do not want to spend too much memory on a big image !



But actually it took much more time that I would have think to find this one !
I finally came up with this code :



public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_menu);
View MainLayoutView = (View) findViewById(R.id.MainLayout);
BitmapDrawable MyTiledBG = new BitmapDrawable( BitmapFactory.decodeResource(getResources(), R.drawable.background) );
MyTiledBG.setTileModeXY( Shader.TileMode.REPEAT , Shader.TileMode.REPEAT );
MainLayoutView.setBackgroundDrawable( MyTiledBG );
<...>
}
(note that you can use also Shader.TileMode.MIRROR to have a different repeatition pattern )

This code works fine, but I would have prefered a XML way to do this.

I've seen the BitmapDrawable attribute defined in the SDK, but couldn't come with anything working...

Tuesday, January 20, 2009

Sliding drawer, again

The sliding drawer developped by pskink has gone quite a long way from where it came from, and is now a really nice and, I think, usable widget, much like the google home page one !

This kind of widget is fun to use, and fits really well for mobile applications, where there is an obvious lack of place. And, on google phone, users are used with this widget, as there is one on the home page !

Here are some screen of this widget in action :



Enjoy !
[Edit ] :
Ooooppss...
I forget to add the link to the source :
You can find it here !
[/Edit]

Friday, January 16, 2009

Sliding Drawer

Interested in the Home Page sliding drawer ?

pskink has created a new widget like the google one.
Nice job, and easy to use...

Here it is :

Enjoy !

Wednesday, January 14, 2009

To accelerate or to decelerate ?

As many developers discovering a new development environment, I use and abuse of copy and paste.
Starting a new feature process is : 
  • finding in the documentation, or on the internet a similar feature, or something as close as possible, 
  • try to find the parameter/line / bit of code to change to have something like what I had in mind in the first time,
  • Be happy :)
  • ( if I have some time : fully understanding what I've just written... )

And most of the time, I don't have that much have time !

For my tries with animations, I find a sample that moved a view, copied this sample for making my high score list view slide out and in. And that's all.

Only now, I discover that in the sample animation I copied, there was this parameter :
android:interpolator="@android:anim/accelerate_interpolator"

And only now, I discover my mistake. The accelerator interpolator makes the speed of the moving view increase with the time.
So when my high score listview is sliding out of the screen, it has a slow speed at first, when one can see it in its integrality, and a fast speed at the end of the animation, when only a little part of it is visible.

But on the contrary, when it is sliding in in the screen, it has its greatest speed at the end of the animation, when one can see it in its integrality !
This just makes a awful animation !

Now that I discovered that my animation can decelerate for slides in, it is way better !


Wednesday, January 7, 2009

Chaining two animations, or how to repeat animationset...

Yesterday I tried to chain two animations !

Actually, what I wanted was, on my high-score list view : translate the listview out of the screen, change the listview content ( for a different type of game ), and retranslate the new listview in the screen.
But, reading the Android-dev mailing list, I realized that it could also interest people using an animationSet.
Apparently, a bug prevent them from handling the repeat flag correctly( see here )
(Note that in my case, I couldn't use an animationSet, because I want to have an operation between the two animations ).

So I first use a AnimationListener to detect the end of the first animation, and launch there the second animation, and...
Kaboum... it ... failed !!
I had discovered a second bug related to animation ( or at least an undocumented constraint ) : you can't launch an animation in the OnAnimationEnd method of the AnimationListener.
I guess after the OnAnimationEnd, there is something like a ClearAnimation done on the view, that remove both the old and the new ones !

So the solution here is to post a message to launch the second animation on the next trame.
So here's my solution :

public class ScorePage extends ListActivity
{
class LocalAnimationListener implements AnimationListener
{
public void onAnimationEnd(Animation animation)
{
//LaunchInAnimation( ); // FAIL:the animation is not launched
//runOnUiThread( mLaunchSecondAnimation ); // FAIL : the runnable is launched immediatly, so like previous method !
//Handler curHandler = new Handler(); // OK, BUT :
//curHandler.post( mLaunchSecondAnimation); // create an unnecessary object !
getListView().post(mLaunchSecondAnimation); // OK : GOOD method !
}
public void onAnimationRepeat(Animation animation)
{
}
public void onAnimationStart(Animation animation)
{
}
};
private Runnable mLaunchSecondAnimation = new Runnable()
{
public void run()
{
LaunchInAnimation();
}
};
LocalAnimationListener MyAnimationListener = new LocalAnimationListener();

public void LaunchInAnimation()
{
// Change the listView Content :
mCurrentHiScore -=1;
if ( mCurrentHiScore < 0 )
mCurrentHiScore = 2;
ListAdapter curAdapter = mScore.GetScoreListAdapter(ScorePage.this, R.layout.score_entry, mCurrentHiScore);
if ( curAdapter != null )
setListAdapter( curAdapter );

// Launch the second animation :
Animation SlideAnim;
SlideAnim = AnimationUtils.loadAnimation(this, R.anim.slide_in_left);
ListView lv = getListView();
lv.startAnimation(SlideAnim);
}

public void LaunchOutAnimation()
{
Animation SlideAnim;
SlideAnim = AnimationUtils.loadAnimation(this, R.anim.slide_out_left);
SlideAnim.setAnimationListener( MyAnimationListener );
ListView lv = getListView();
lv.startAnimation(SlideAnim);
}
(... )


Now it's just fine !

Sunday, January 4, 2009

A flashy widget: the sliding drawer

I recently found where the code for the sliding drawer was in the Android code.

So what is that sliding drawer ?
It is the panel containing your applications in Android Home page.
You know, the panel that you can drag up or down, and that was the first thing you played with when first testing Android emulator or the G1 !

Here's the code :
Sliding Drawer Code

I would like to have time to experiment with it ( ie copy/paste it, and use it in my own application ), but just reading the code is quite an inspiring experience ! I will try that as soon as possible...

This widget is nice and fun to use, give a good feeling to the user, make your application more profunssional, and is a very efficient way to spare space in the screen !

Just one thing : why on earth is the code hidden in the depth of Android source ?
Why isn't the widget available as a part of the API ?
I just can't understand it !

Android definitively misses some standard fun widgets.
Was it because of a lack of time ?
Will the sliding drawer appear in the next version ?
Will we find who killed the colonel Mustard ?

Friday, January 2, 2009

numeric editText and EditText with max number of characters... yes, again !

Sometimes, being a lone developer is a very depressing status.
You want a feature, you fight with the system, the tools, the documentations ( no comment ), the forums, ...
And you found a solution. So you're happy with all your code that do what you wanted.
Until you finally find you could achieve the same thing with only one line of code !

This is exactly what happened to me !
I found that a numeric editText ( or a textView) is done with this XML tag :
android:numeric="decimal"

Then I found that limiting the number of character is also very simple :
android:maxLength="10"


and that's all !


Why didn't I find that in the first time ( and spend so many time on my own solution ? ).
Because, I was looking at a way to do this by code.
And it is less obvious in code.
For the limited number of character, you can add a Android API filter :
InputFilter[] FilterArray = new InputFilter[1];
FilterArray[0] = new InputFilter.LengthFilter(8);
editEntryView.setFilters(FilterArray);


For the numeric editText, there is also a obscur solution :
DigitsKeyListener MyDigitKeyListener =
new DigitsKeyListener(true, true); // first true : is signed, second one : is decimal
editEntryView.setKeyListener( MyDigitKeyListener );


So all my work was useless ?
Possibly ( the politically correct answer is : oh no, I learned so many things in the process ), there is still a feature I have with my solution that is not 'that simple' with those solution, but I think I can do it also with implementing my own filter.
Now should I do it ? Filters look like they are no user friendly beasts, and my solution is already up and working !

Thursday, January 1, 2009

Happy New Year

I wish you all a very happy new year, with a lot of happy Android ( or other ) programming !

Full of activities of any sorts ( poor pun intended )!

I plan to ship my first Android program as soon as possible (this month would be great), and to continue explaining issues and solutions found here !

2009 should be the year of the Android explosion, with several new phones coming...
It will definitively be an interesting year for an android developer !