Dear all,

I'm working on a handset application project in my company that uses the PIM API, the target is to backup the clients personal data and upload it to a server, the application is working fine, but there is a problem: that is not all of the data are read through the PIM API, and I think it's a bug in the PIM API implementation.

I'm using the following procedure to get the data:
if (listNames.size() > 0) {
	// Creating new StringBuffer to the XML file
	StringBuffer xmlFile = new StringBuffer();

	// Boolean that handles true if there at least one item has been backuped
	boolean isThereItems = false;

	// New string long date
	String nowdate = Long.toString(new Date().getTime());

	// Building the header of the XML file
	xmlFile.append("<?xml version='1.0' ?>\n");
	xmlFile.append("<!-- Created by PIMBackupMIDlet -->\n");
	xmlFile.append("<BackupLists version='0.1' date='" + nowdate + "'>\n");

	// Start displaying the application status alert
	Display.getDisplay(midlet).setCurrent(alert, caller);

	// Looping through the selected lists
	for (int i = 0; i < listNames.size(); i++) {
		try {
		list = PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE, (String) listNames.elementAt(i));

		// Checking if the list has more elements, so we could start backup process
		if (list.items().hasMoreElements()) {

			isThereItems = true;

			xmlFile.append("<list name='").append((String) listNames.elementAt(i)).append("' type='").append(PIM.CONTACT_LIST).append("' maxFields='").append(list.getSupportedFields().length).append("'>\n");

			for (Enumeration items = list.items(); items.hasMoreElements();) {

				StringBuffer itemDetails = new StringBuffer();

				Contact item = (Contact) items.nextElement();

				itemDetails.append("<item UID='").append(list.isSupportedField(Contact.UID)? item.getString(Contact.UID, 0) : (item.getString(Contact.TEL, PIMItem.ATTR_NONE) != null && item.getString(Contact.TEL, PIMItem.ATTR_NONE).length() > 0) ? item.getString(Contact.TEL, PIMItem.ATTR_NONE) : item.getString(Contact.TEL, Contact.ATTR_HOME)).append("'>\n");

				int[] fields = item.getPIMList().getSupportedFields();

				for (int j = 0; j < fields.length; j++) {

				int field = fields[j];
				int[] fieldAttr = item.getPIMList().getSupportedAttributes(field);

				System.out.print("SupportedFieldAttrs.Count for field " + field + " (" + item.getPIMList().getFieldLabel(field) + "): " + fieldAttr.length + ", field type: " + item.getPIMList().getFieldDataType(field) + ", valueCount: " + item.countValues(field) + ", maxValues: " + item.getPIMList().maxValues(field));

				for (int count = 0; count < (item.countValues(field) < item.getPIMList().maxValues(field) ? item.countValues(field) : item.getPIMList().maxValues(field)); count++){

					// exclude CLASS and Image and Video fields
					if (field == Contact.CLASS || field == Contact.PHOTO) {

					int dataType = item.getPIMList().getFieldDataType(field);
					String label = item.getPIMList().getFieldLabel(field);
					String attributes = Integer.toString(item.getAttributes(field, count));
					String data = null;

					switch (dataType) {
					case PIMItem.STRING: {
						data = item.getString(field, count);

					case PIMItem.BOOLEAN: {
						data = item.getBoolean(field, count) ? "Yes" : "No";

					case PIMItem.STRING_ARRAY: {
						String[] a = item.getStringArray(field, count);
						data = joinStringArray(a);

					case PIMItem.DATE: {
						data = Long.toString(item.getDate(field, count));

					case PIMItem.INT: {
						data = String.valueOf(item.getInt(field, count));

					case PIMItem.BINARY: {
						data = item.getBinary(field, count).toString();
					}catch (Exception e) {
						System.out.print("\nIn Exception ex1, ");
						data = null;

					if(data == null){
						data = "";

					itemDetails.append("<field code='").append(field).append("' index='").append(count).append("' attributes='").append(attributes).append("' label='").append(label).append("' data='").append(XMLEncoder.encode(data)).append("' dataType='").append(dataType).append("' />\n");





		//Closing the PIMList

		} catch (PIMException e) {
			midlet.showMessage("PIMException:\n" + e.getMessage(), MessageScreen.ERROR, caller);
			System.out.println("Error: PIMException occured");
		} catch (SecurityException e) {
			midlet.showMessage("SecurityException:\n" + e.getMessage(), MessageScreen.ERROR, caller);
			System.out.println("Error: SecurityException occured");
		} catch (RecordStoreFullException e) {
			midlet.showMessage("RecordStoreFullException:\n" + e.getMessage(), MessageScreen.ERROR, caller);
			System.out.println("Error: RecordStoreFullException occured");
		} catch (RecordStoreNotFoundException e) {
			midlet.showMessage("RecordStoreNotFoundException:\n" + e.getMessage(), MessageScreen.ERROR, caller);
			System.out.println("Error: RecordStoreNotFoundException occured");
		} catch (RecordStoreException e) {
			midlet.showMessage("RecordStoreException:\n" + e.getMessage(), MessageScreen.ERROR, caller);
			System.out.println("Error: RecordStoreException occured");
		} catch (Exception e) {
			System.out.println("Error: Exception occured");

			String message;

			if ((e.getMessage() != null) && (e.getMessage().length() > 0))
				message = "Exception:\n" + e.getMessage();
				message = "Exception:\nUnknown Error\n"+logMsg.toString();

			midlet.showMessage(message, MessageScreen.ERROR, messageTB, MessageScreen.FOREVER);


	// Checking if there items have been backuped; in order to start uploading the gathered data to the server
	if (isThereItems) {
		// Start to upload the backup file to the server
		Upload up = new Upload(xmlFile.toString(), midlet, 0);
	} else {
		midlet.showMessage("The list(s) you choosed doesn't contain items to be backuped.", MessageScreen.WARNING, caller);
} else {
	midlet.showMessage("You should select at least one list!!", MessageScreen.WARNING, caller);
I tested my application on Nokia S40 SDK 5th edition and also on Nokia S60 SDK 3rd edition, and it works with a small notice: When i have a contact that has 5 emails, the function "item.countValues(Contact.EMAIL)" returns "5", but the function "item.getPIMList().maxValues(Contact.EMAIL)" returns "2" and if I'm trying to get "item.getString(Contact.EMAIL, 2) or item.getString(Contact.EMAIL, 3) ...etc." it throws an exception of "IndexOutOfBoundsException" and i don't know if there is a problem in my code or it's a bug in java implementation.

Then i tested the application on my handset (Nokia 5130 XpressMusic, S40 Ver. 07.91) and also the whole procedure works, but there are a data that couldn't be retrieved, i.e. i have a contacts that have (first name, name, phone number, email) and the PIM API only get (uid, first name, name, email) and doesn't get the (phone number), but for another contacts that have the same details; the PIM can get all the data, also i have a contact that has (first name, second mail, 5 phone numbers, 3 emails, 2 web addresses, company, job title, formal name, nickname, formatted address, birthday, notes, image) then the PIM API could get the following (first name, second mail, 3 phone numbers only or sometimes get all 5 phone numbers, 2 emails only, 1 web address only, company, job title, formal name, nickname, formatted address, birthday, notes, image), and i think it's a problem related to the previous one, and it happens on the Nokia SDK S40 also.

Then i tested the application on my friend's handset (Nokia E65, S60) and also the whole procedure works, and there is a data lost, but this time i have a contact that has (first name, last name, phone number, company, suffix) and the PIM API get only (first name, last name, company), Why..... i don't know? but i searched times and times over the web and I couldn't found a solution, I tried to do the "int[] fields = item.getFields();" instead of "int[] fields = item.getPIMList().getSupportedFields();" and also no way.

If anyone can find the problem; please help me, as I'm getting to frustrate

Thanks all,