Home Engidea Home Circle

Import ASCII Contacts into Nokia E90, Symbian Programming

Wrestling with HBufC, RBuf, CContactIdArray, CContactCard, CContactItem, CContactDatabase, RFile and many others

The beginning

I waited many years to buy a phone that had vibracall and GPS. When Nokia E90 arrived I decided that it was my phone!. I must admit it didn't have a good start, problems with the keyboard touching the screen (and damaging it) and microphone issues, but after many months from the first release (February 2007) I decided that at December Nokia should have fixed all problems. I was wrong.

I should remind you that in Italy the phone sale price is 900Euros, with this money you can buy a laptop, a good one. For this price one expect the machine to be "perfect".. I went to "Città Mercato" and they had two, both of them wobbling when put on a flat surface (since the phone has a keyboard you are supposed to put it into a flat surface). Then I did try to buy it trough Esprinet and even that model had the wobbling issue (basically one of the feet is higher than the others). Finally I settled with a Nokia shop that even had a price less than the reseller... (Esprinet)

The unit I have is wobbling slightly (the picture shows what could be something like half millimiter), still VERY annoying, but I was exausted to wait for the phone... It also has camera button that has no feeling whatsoever and it makes taking pictures a challenge, but it has vibracall and GPS and many other good things. So basically the machine is a good one.

Wobbling E90

You may wonder why I am writing the blog then ?!

You have to know that I still have a Nokia 9110i (with the original battery) loaded with addresses and one of the reasons to buy a E90 was that "surely" there was an easy way to import the old 9110i contacts into E90. Yes yes... I see you start laughing, after all nowdays compatibility is a bonus. Look a Microsoft, each new Word version has a file format that is incompatible with the previous version, and I would not attempt to open an old Word document (beside a basic one) with the new Word.

Anyway, I connected my E90 end looked for "import" into the PCSuite... to no avail. After looking hard into all documentation I concluded There is no ascii/xml import whatsoever (Yes, I know you can import a VCard at the time, I would not call this a way to import export of data). AAAAArghhhh.. so I started looking for help or to be more precise I wanted to write a MIDLET to import my old addresses. The first thing is to subscribe to a forum. I subscribed to Forum Nokia for End Users and that allows you to post into Nokia discussion board where you can possibly ask for "help". Since I already digged up all the possible options I was then looking for help, any help..

Request for help

If you look at the stream of my post on the issue you will discover that I am not the only one that is wishing to be able to import and export the Contacts in plain text. Yes, they allow synchronization with some PIM but you are out of luck if you do not have them and it is all to be seen how those PIM will export your data. (I will discover later that even Nokia 9110i cannot manage to export its own data properly)

The battle begins

My first attempt was to write a Java Midlet, let me tell you how it went...

Should you use Nokia Emulator to develop Midlets ?

I did try it up, the latest version both nS60_jme_sdk_3rd_e_FP2_Beta.zip and nS60_jme_sdk_3rd_e_FP1.zip loading EclipseME and all the needed bits. The end result is slow and unreliable (even this one had emulator not working). Writing the application is somewhat "easy", the difficult part is handling the certificates !!! (more on certificates later)

The answer to the previous question is no, do NOT use Nokia tools to develop Midlets !

For Midlets use Netbeans IDE 6.0

Give it a try, it is not the slow dog it used to be (amazing how difficult it is to clear up a bad name) you can find it at Netbeans WebsiteNetbeans and be sure to download the edition for MIDLETS my filename was netbeans-6.0-mobility-windows.exe

I managed to have a basic Contacts importer in less than an hour (including self signed certificate and so on). When I go and try to load up and run I am prompted with handful of confirmation questions. Opening Contacts, accessiong contacts, writing contact etc... I had to import about 600 records with basically three clicks every contact it was going to be a royal pain.

Looking for the right certificate

This is the root of the problem. You have to know that Nokia E90 is a caged phone and you (me) are caged with it. I do not own the phone, Nokia does, even if it is legally my property. Let me explain, it seems that all is done in the name of SECURITY, but this is plain false. All is done in name of CONTROL.

An example to understand

Let's say that you buy a car and the manufacturer says that for SECURITY reasons you can ONLY carry CERTIFIED passengers. The real trick is that only a handful of "authority" can certify who are the "good" persons. This is what happens with E90 (and all the S60 phones)

You also have to remember that this is not a once for all grant, if tomorrow Nokia decides that one passenger is unwelcome then it can deny the access to the car, your car, the car you want the passenger to travel !

Some developers are already shouting this, and Sony-Ericsson allows you to install your own root certificate in their phones. So it is not a technical issue, just politics and control. If you really have to buy a Symbian phone do not do my error, buy a Sony-Ericsson at least they allow you to use your phone as you wish.

A friendly fellow emailed me asking how "disabling" the check for signed application affects your ability to run applications in the Phone. (Tools-Settings-App. Manager-Software Installation-All). As far as I understand this allows you to Install Unsigned application, but running them is another story. I did lots of trial and actually my phone is now set to allow all software installation, but still you are prompted with a barrage of confirmation for activities on Contacts. (Unless you use c++, proper certificate and proper capabilities)

Since I didn't want to pay for a certificate that I needed only once and since I thought that writing a "native" application should not be so bad (I was wrong) I started with writing my own symbian c++ application.

Getting a c++ developer certificate

Amazingly Nokia gives you a free certificate if you develop in c++ Symbian (no free certificate for MIDLETS, guess why..) The certificate expires, obviously, so Nokia can always close me out later, if they wish so, but by that time there may be better alternatives :-) (hopefully)

To get a certificate you go to Symbian Signed website where you must first register. As far as I understand you CANNOT register unless you are a COMPANY, this is (of course) in the name of SECURITY, or better to keep away all those pesky people that just want to play with their phones. After all they should just shut up and pay !

After the usual EULA I manage to obtain the certificate, that is BOUND TO ONE DEVICE ONLY, so even if you find my program useful you will NOT be able to use it since it is signed for my device only and there is no way around this (beside me paying for a certificate). If you want to know more details about certificates, just ask, look at the bottom of this page.

Request for help

Setting up c++ development

I downloaded S60-SDK-200634-3.1-Cpp-f.1090b.zip Carbide.c++_v1.2.exe (you also need Active Perl 5.8.8) from Nokia Forum, got my certificate from Symbian Signed and I was ready to go. I fired up the emulator and what I got is a crash...

I went to the Forum and I discovered that I am not the only one experiencing this. This is my report:

Nokia S60 Emulator Crash

And this is Nokia reply. Really how can I expect Nokia to fix their bugs for free ??!! One wonders if Companies appreciate when a developer does the work of setting up a testing environment and finding bugs..

Nokia S60 Emulator Crash

But I must be fair, I managed to find a way to report the bug and I got a more appropriate reply.

Dear Damiano

Thank you for submitting this software issue, it has been placed in a queue for further investigations.
Please be aware that this is a channel solely for the purpose of reporting S60 software issues
and requesting technical feedback for the issues is not recommended.
Any solutions or workarounds identified will be published in Forum Nokia’s Technical Library without prior notification.

Best Regards,
Forum Nokia – Professional Support

Nothing after this Email. Nokia expects me to check every day if they solved the bug in their product ?. They surely know how to send an Email when they solve the bug ,would they !?

Working without Emulator

Yes, it is possible, extremly painful, but possible. The first thing I did is to run the Contacts Example that is in the Example directory of the devkit C:\S60\symbian92\S60_3rd_FP1\S60Ex\Contacts

From here onward I am going to be really technical, this is painful, if you do not stand pain, stop reading now.

Carbide C++ what you really need to know

This is really important. If you are a person that already knows Eclipse (Carbide is based on Eclipse) then you may think that the Symbian project is managed trough the "normal" Eclipse interface, NO ! Symbian uses ITS OWN configuration tools !!!

Let me repeat. It is no good to add include or libraries trough the normal Eclipse Interface, you HAVE to use Symbian tools. The tools/files you need are:

group/projectname.mmp

This file is the main config file, here you add includes, libraries, and define the capabilities that your program request.

Carbide c++ mmp panel

Project Properties

This is embedded into the Eclipse interface, in the Properties panel of the project you find where you can define how to sign your program to be imported into the telephone. You will download the *.sisx file in the telephone. Note that the password field is blank since I just deleted my password, but you need to put your own password and your own certificates. (the one you got trough symbian signed)

Carbide c++ mmp panel

Beware of the linking errors !!!

Carbide++ will report compilation errors in the gui, or at least it does this fairly often, so it is fairly clear when the produced sis is garbage (or better is is just the previous version). What Carbide c++ does NOT do is to report linking errors (this happens when you use a new function/class, include the header file but "forget" to include the library into the linking process.
Since sis signing goes on even after this error you end up with uploading a SIS that is just the previous version and if you expected something to happen ... well it does not happen. This has hit me a couple of times, so it is fairly important. What you have to do is to search for Error in Carbide c++ logging console

Starting my own project

You are thinking that I am mad. Why on earth did I start my own project (from scratch) instead of using the example Nokia provided ????? Simple, I did want to share my work with you and Nokia Copyright on the examples is unforgiving. Below is the copyright on the examples files. Note that I am not posting the copyrighted material, just the Copyright notice...

/*
 * ==============================================================================
 *  Name        : ccontapp.h
 *  Part of     : Contacts database example
 *  Interface   :
 *  Description :
 *  Version     :
 *
 *  Copyright (c) 2004 - 2006 Nokia Corporation.
 *  This material, including documentation and any related
 *  computer programs, is protected by copyright controlled by
 *  Nokia Corporation.
 * ==============================================================================
 */

Why is Nokia putting such Copyright on Examples is unknown, maybe they will realize that this just makes developers life difficult and this is ultimately bad for them, whatever....

If you plan to develop with Simbian read on

From now on I will tell you what are the things I was looking for and where how I found them. This is the result of roughly four days where I went from knowing nothing of Symbian to actually being able to do what I wanted, so it is not theory, it is hard sought knowledge.

Create empty symbian GUI project

Please use the wizard, at least it will set up all the mad things for you. On Carbide do a New Project, Others and go on with the following wizard.

Carbide c++ create symbian GUI

The wizard will create a bunch of files and directory. The first thing you want to do is to run the empty application in your phone (that includes signing it). It is not enough to run it in the emulator (if you manage to do it) since the emulator can use fake certificates and security, a real device has more limitation than the emulator !

After you managed the above, BACKUP YOUR PROJECT, if you are technical you can use Subversion to manage your project or just 7z everything and put it away. You will need it when some changes you made cannot be corrected...

Create your own Menu Item

For the time being do NOT try to change a menu item that is already there, try to add your own. The files you have to touch are

data/projectname.rss here you actually define you menu item. At this stage just put the text to display in right in the resource file, you can do fancy things later. The important thing is defining the command label (EvOpenFile, EvOpenDbase, etc) these are defined in another place, inc/projectname.hrh is is just an enum where you have to add your own command

Symbian GUI add Menu Item

The next step is to edit src/projectnameAppUi.cpp, look for HandleCommandL and add a case statement for you new menu.

Have a function that display some message

This is asked countlessly on the forums, the code below may not be perfect but it is a starting point. Bear in mind that one of the issues is providing the same function for all the variations of "descriptors" more on descriptors next

The first thing you want to try is the one that display a char string....

void CCdbInportExportAppUi::ProgressMessage( char * message)
	{
	TPtrC8 ptr(reinterpret_cast<const TUint8*>(message));

	ProgressMessage ( ptr);
	}

void CCdbInportExportAppUi::ProgressMessage( TPtrC16 ptr)
	{
	// Since I call NewLC then this is put into the Cleanup stack
	HBufC* buffer = HBufC::NewLC (ptr.Length ());

	// copy the data into the buffer.
	buffer->Des().Copy (ptr);

	ProgressMessage (buffer);

	// And tehrefore I need... to clear the last leave that was inserted...
	CleanupStack::PopAndDestroy ();
	}

void CCdbInportExportAppUi::ProgressMessage( TPtrC8 ptr)
	{
	// Since I call NewLC then this is put into the Cleanup stack
	HBufC* buffer = HBufC::NewLC (ptr.Length ());

	// copy the data into the buffer.
	buffer->Des().Copy (ptr);

	ProgressMessage (buffer);

	// And tehrefore I need... to clear the last leave that was inserted...
	CleanupStack::PopAndDestroy ();
	}

/**
 * This is the one that actually does the work
 */
void CCdbInportExportAppUi::ProgressMessage( HBufC* buffer)
	{
	CAknInformationNote* msg = new (ELeave) CAknInformationNote(ETrue);
	// apparently ExecuteLD deletes possible leaks found in a forum...
	msg->ExecuteLD (*buffer);
	}

Attempt to understand descriptors

I can understand the reasons of descriptors "invention", but they are just a mess. What you need to know is that they DO NOT SHARE a common class and therefore they are NOT compatible with each other. Wait wait, you Symbian guru, I did not say that you cannot COPY stuff from one to the other, I said that you cannot pass a descriptor of one type to a function that wants another type of descriptor.

So, most of the time is spent to understand how to get a type of descriptor when you have another in hand. Let me give you some hints. (This reminds of a Scott Adams comic where Account troll is sealed in a wine barrel and spews new ideas... I have to ask Scott permission to publish that comic...

Another Blog post on descriptors with further references

Difference between 8 bits and 16 bits descriptors

Do not believe that you should "prefer" the size independent version of descriptors. It is NOT just a matter of word size, they really are different beast !
The 8 bits version is needed to read files that are plain ASCII files, to store arrays of data. The 16 bits one is really holding Unicode content and as such it is used for the GUI and to store information that are Unicode.

They have a different "meaning", if you use the size independent version you will discover that your application may switch from Unicode to ASCII or viceversa without you knowing anything ! After all if you WANT unicode then you should have it and be warned if the platform you are using does not support it.

To move data from one form to the other you use the Copy method. But beware that it is safe to go from 8 to 16 bits but not the other way around (unless you know the data fits in 8 bits)

void CCdbInportExportAppUi::ProgressMessage( TPtrC8 ptr)
	{
	// Since I call NewLC then this is put into the Cleanup stack
	HBufC* buffer = HBufC::NewLC (ptr.Length ());

	// copy the data into the buffer.
	buffer->Des().Copy (ptr);

   ...... do something with buffer

 	// And tehrefore I need... to clear the last leave that was inserted...
	CleanupStack::PopAndDestroy ();
	}

You have a RBuf ad you want a HBufC

RBuf is the suggested storage descriptor, but many methods request a HBufC, use the AllocLC method to get a HBufC if you have a RBuf

You have a char * (string) and the method wants a TUint8 * and a len

Do not construct a HBufC or whatever just to get the len, use the old and simple strlen to find out the len. I had to write a few messages to a file and I could use this method.

#include <string.h>

void CCdbInportExportAppUi::logWrite( char * message)
	{
	logFileP->WriteL ((const TUint8*)message,strlen(message));
	}

You have to link the estlib to have the strlen function

Attempt to understand cleanup stack

This is also a mess, mainly because the life of a "descriptor" may be well beyond the function that allocated it. This is the case when a method returns a pointer to a descriptor allocated in there. If that descriptor in in the cleanup stack and at some point in the future I need to clean it up... and if there are other descriptors on top of it.... well I cannot (as far as I understand). So I have to pop it out of the stack or just avoid putting it into the Cleanup Stack. But.... if then have a Leave that descriptor will not be cleared....

It is not enough to have to call delete to clean things up in c++ (thanks Java for garbage collect) you ALSO have to call Close() (but it is not always close, it may be Destroy or maybe some other name.... to free up further resources, but WAIT !! depends if some other function has got hold of that descriptor, and in such case, no, you should not call the Close()....

I can only say, do NOT believe the simple examples, they are misleading. Do not believe that there is one way to do things that holds trough the API, be alert for pitfalls and google a lot.

Browse the C++ Class Hierarchy

Open symbian_devlib.chm go to Index, open C++ Class Hierarchy search for HBufC, RBuf and so on You will understand the relations between classes. You need this since some methods publish as parameter an abstract class but you have to create a new instance and you need to know what is the name of the concrete Class that you can create. The only way out is to use this help. Here you realize that the Descriptors classes do NOT share a common ancestor, not even to define a set of methods that can handle data conversion.

But be aware that the documentation can be wrong, so you have to rely on Carbide to show you what is the parent of a given class, as an example HBufC16 seems to have no ancestors in the Class Hierarchy but instead it has TBufCBase16 and TDesC16 as ancestors.

If some guru will says that the above is not true since somewhere else things are correct then please get lost. I am using the help files that comes with the DEVKIT, how am I supposed to know that somewhere else the documentation is correct ???

Get TaskSpyS60 to display Panic Codes

One wonders why Nokia S60 does not display any message when an application dies. With S60 you gets absolutely nothing, it would be far better if there was a config setting that enables panic messages. I really needed to know the panic code when my application dies !!!
Thank goodness there is still someone willing to help and so I downloaded TaskSpyS60 of course I had to sign it with my own certificate, so it is not something you can just grab and install, but is better than nothing.

Having the panic codes is a must, you go from a wild guess to an almost sure hit (especially if you develop and test one bit at the time)

Have a logging stream for things that happens

Even if you have the emulator, there are countless cases when your program finds a bug and it is willing to log the event (of course you have to write a few lines of code, but this saves days of debugging). To do logging you have to have a way to write your messages to a file, below you find how you can do it.

What you need is an instance of RFileWriteStream as log stream and a few functions. You put the instance into the private part of your class, open the file on constructor and then use the logging. Below there are few code snippets, at the end of the blog you can find the whole application source.

private: // allocate a pointer to the object in your class private data
	RFs   *fsSessionP;
   RFileWriteStream *logFileP;
LIT( LogFileName, "E:\\Others\\Damiano\\CdbLog.txt" );

/**
 * In the laving part of you class constructor initialize your logfile.
 */
void CCdbInportExportAppUi::ConstructL()
	{
	fsSessionP = new (ELeave) RFs;
	User::LeaveIfError (fsSessionP->Connect ());

	TInt err = fsSessionP->MkDirAll (LogFileName);
	if ( (KErrNone != err) && (KErrAlreadyExists != err))
		{
		ProgressMessage ("MkDirAll: Failed");
		return;
		}

	logFileP = new (ELeave) RFileWriteStream;

	err = logFileP->Replace (*fsSessionP, LogFileName, EFileWrite | EFileStreamText );
	if ( KErrNone != err)
		{
		ProgressMessage ("logFile->Replace: Failed");
		return;
		}

	ProgressMessage ("Log File Opened");
   }
/**
 * This is the one that actually does the writing
 * Do not destroy the buffer, the caller will do it if he wish so
 */
void CCdbInportExportAppUi::logWrite( HBufC8* buffer)
	{
	logFileP->WriteL (*buffer);
	}

void CCdbInportExportAppUi::logWrite( char * message)
	{
	logFileP->WriteL ((const TUint8*)message,strlen(message));
	}


void CCdbInportExportAppUi::logWrite( RBuf8 *message)
	{
	logFileP->WriteL (*message);
	}

/**
 * This gets a RBuf16, unicode
 */
void CCdbInportExportAppUi::logWrite( RBuf16 *message)
	{
	HBufC8* buffer = HBufC8::NewLC (message->Length ());
	buffer->Des().Copy (*message);

	logWrite (buffer);

	// And tehrefore I need... to clear the last leave that was inserted...
	CleanupStack::PopAndDestroy ();
	}

It is important to note that the RFileWriteStream class is a buffered writer, this makes your writing to file hundered of time faster (really) than using the plain RFile class, so you should really use this.

Do your own content parsing

You may need to read a file that is formatted according to your specification (mostly because somebody else produces it) In this case you probably need to read the file one character at the time and decide what to do. What follows is an efficient way to Read a line from a text file, this is of course Symbian code....

private: // allocate a pointer to the object in your class private data
	RFs   *fsSessionP;
   RFileReadStream *inputFileP
   // this piece of code opens the file for reading
   // you can put this into an event or constructor
   inputFileP = new (ELeave) RFileReadStream;

   TInt err=inputFileP->Open (*fsSessionP, inputFileName, EFileStreamText | EFileRead);
   if ( err==KErrNotFound)
      {
      ProgressMessage ("File open failed");
      return;
      }

   ProgressMessage ("File open OK");
/**
 * The method that reads a line reports EOF using a class private variable.
 * On EOF the len of risulP would be zero.
 * NOTE: you could get the buffer len from max the RBuf that would be more portable.
 * @param risulP a pointer to a RBuf8 with allocated space.
 */
void CCdbInportExportAppUi::readLine(RBuf8 *risulP)
	{
	risulP->SetLength(0);

	if ( inputFileP == NULL)
		{
		ProgressMessage ("Please open input file");
		inputFileEof=1;
		return;
		}

	// I need a single buffer to store a char I am reading from input file
	unsigned char abuf[1];

	int index;
	for (index=0; index<LINE_LEN_MAX; index++)
		{
		TRAPD(err,inputFileP->ReadL(abuf,1));

		if(err==KErrEof)
			{
			inputFileEof=1;
			break;
			}

		// character 13 is to be ignored
		if ( abuf[0] == 13) continue;

		// this is the real end of line
		if ( abuf[0] == 10) break;

		// none of the above and I therefore append bytes...
		risulP->Append (abuf,1);
		}
	}

Manage to have a label to show application status

This is fairly complex and I suggest that you look at the whole application, not just the snippets. The basic idea is that the wizard has split the application into a AppUi class and a AppView class. You should put your drawable components into the View class. What follows is a working start

NOTE: You have to include the right includes for CEikLabel and the libraries (if not included already)

NOTE: if you are updating the label content into a GUI callback (eg: when you respond to a button event) then the label will not be updated until you return from the event handling method ! If you have to do long operations look forward for a way to do it.

/**
 * You have to construct your label in the leaving part of the AppView
 */
void CCdbInportExportAppView::ConstructL( const TRect& aRect )
	{
	// Create a window for this application view
	CreateWindowL();

	progressLabelP = new (ELeave) CEikLabel();
	progressLabelP->SetContainerWindowL(*this);
    _LIT(KLabelText, "LabelOne");
    progressLabelP->SetTextL(KLabelText);
	progressLabelP->SetPosition(TPoint(20,20));
	progressLabelP->SetExtentToWholeScreen();

	// Set the windows size
	SetRect( aRect );

	// Activate the window, which makes it ready to be drawn
	ActivateL();
	}
/**
 * Then you provide a method that can be called to update the label
 */
void CCdbInportExportAppView::setLabelText ( RBuf16 *messageP)
	{
	progressLabelP->SetTextL(*messageP);
	progressLabelP->DrawDeferred();
	}
/**
 * You have to let the GUI subsystem to know how many components thare are
 * and have a way to get them
 */
TInt CCdbInportExportAppView::CountComponentControls() const
	{
    return 1;
	}

CCoeControl* CCdbInportExportAppView::ComponentControl(TInt aIndex) const
	{
    switch (aIndex)
    	{
        case 0:
            return progressLabelP;

        default:
            return NULL;
	    }
	}

How to handle long running operations

The usual example is spreadsheet recalculation, but it can be anything long to do. The important part is that it should be splittable in small timed operations. As far as I understand waiting for a network connection does not fall into this, if you have such a problem you have to create a task.

But if you just want to do something light you can use the CIdle class

public: // define this method as static
		static TInt staticBackgroundRecalc(TAny* aPointer);

private:  // add this into your private class parts
   		CIdle* cdbReloadP;
/**
 * This is just a helper that calls the method that does the real work
 * if the method returns 1 then it will be called again when the system is idle
 * if it returns 0 then no more calls will be done
 */
TInt CCdbInportExportAppUi::staticBackgroundRecalc(TAny* aPointer)
	 {
	 return ((CCdbInportExportAppUi*)aPointer)->parseInputFile();
	 }

void CCdbInportExportAppUi::startCidleTask ()
	{
	if (  cdbReloadP == NULL )
	  cdbReloadP = CIdle::NewL(-100);//CActive::TPriority::EPriorityIdle);

	recordCounter = 0;
	inputFileEof = 0;

	cdbReloadP->Start(TCallBack(staticBackgroundRecalc,this));
	}

Download the Importer application

Below you can find the source code of my application. I cannot distribute a SIS since I do not have a certificate and really is is a rough application (beware that OPENING the contacts database will clear it up !!!)

Download the Contact Databse Project Source
If you wish me to change it I could work on it, after all I have spent four days to know Symbian, I could spend another couple more days to produce a real application :-)

What I wish from Nokia

Here there is a list of things I wish Nokia will understand, they are good for them, for the user, and for the developer.

Allow Root Certificate installation

Even the ones that allow installation and running of applications (any application, for any purpose). This is just politics, there is no technical reason to stop this. It is MY machine, I should be able to do whatever I am pleased with it. Arguing that the machine I have bought is like this is bogus, if Nokia does not want to change the policy then it should make it clear that what is being sold is a caged machine whose control is still with Nokia.

Provide a way to save and restore device data in ASCII/xml

Not providing a way to export/import data in ascii plaintext format is a vendor lok-in strategy. Nokia should fight on the quality of the products not on the impossibility for a user to change brand. I would also argue that the policy of binary/sealed content is a backfire even if one buys from the same company. Even Nokia does not have an upgrade path for its own machines.

On a side note I discovered that the ASCII export of my nokia 9110i simply omits all second lines of address or notes. So, I still have to scan trough all my 600 addresses but at least I do not have to rewrite all of them.....

Make phone menu smarter

After having worked with Symbian and E90 for four days I realized that current menu definition is suboptimal. Yes, they are easy to define, but they are fixed, the order of menu items is fixed. What is needed is a way to remember what is the most used menu item in a menu and the next time a user opens that menu it will be prompted as default choice with the most used menu item.

Of course the user can change the selection (as it does now) and if the most selected menu is another one then the new one will became the default selection. Of course you can make this thing configurable, maybe a user wants a specific order of menu items anyway !

Note that there could be countless variations on how you define "most used menu", the most evident one being the menu item that is selected more often, but you could provide a "make default" switch or a rearrange menu panel... etc.

In case some patent troll think this idea is patentable, well, it is not, I wrote it (29 December 2007) here and as far as I can see it is more than evident for any developer that barely worked with cellphones. I really hope this will not be patented since it is a useful thing and should not be stopped by patenting laws.

Handle product defects better

I have a phone that is defective, having one leg shorter is not acceptable. The current policy is that I take it to "repair" and wait until it gets fixed. This makes the customer angry. It feels like the hot potato game, where everybody is passing around a hot potato, nobody willing to cool it down. The reseller does not want to know anything about it, the shop hopes to "push" the defective units to the customer and the customer is left with a product that is defective. Yes, I know, I bought it even if it has one leg shorter, I was frustrated of waiting for it, I will not repeat the same error again.

The real issue is that the shop does NOT allow me to open another Nokia E90 to see if the next one is "good" since the shop CANNOT return the phone to Nokia and get a replacement unit (this is as far as I have been told). The issue is really on how Nokia handles defective products.

Conclusion

I must say that I am pleased. I managed to fight and win to reach my goal. This is not for light hearts. Symbian is a pain to develop with, no wonder Nokia wants your application to be "revised", it is way too easy to make errors ! I normally work in Java, C#(a copy of Java) and normal 'c'. I did almost forget the ugliness of c++ (yes it is better than nothing).

But it is done ! I have my addresses back and this is time to cheer

Happy new year to everybody !


If you want to contact me, just write your message below and press the side button.
Leave an Email address if you want to be called back

   
Last Updated 01/01/2008 Damiano Bolla