Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
New Developer
Posts: 37
Registered: ‎07-13-2014
My Device: Z10
My Carrier: Vodafone
Accepted Solution

Generating vcf file using ContactService api

Hi All,

 

I have written a code which retrieves all contacts using ContactService api. The code is as follows:-

 

foreach (const Contact &idContact, contactsList) {
		// Fetch the complete details for this contact ID
		const Contact contact = m_contactService->contactDetails(idContact.id());
		QByteArray contactArray = m_contactService->contactToVCard(contact);
	}

 Here contactsList is list retrieved using ContactService api.

 

I cant figure out how to proceed further i.e I need to convert all contacts of contact list a single vcf file and store it in memory card.

 

Please guide.

 

Thanks & Regards

Developer
Posts: 158
Registered: ‎01-03-2013
My Device: n/a
My Carrier: n/a

Re: Generating vcf file using ContactService api

[ Edited ]

This would be to save the data

 

QFile myFile(QDir::currentPath() + "vCardContacts.dat");

if(myFile.open(QIODevice::WriteOnly))
{
  QDataStream ds(&myFile);
  //First a magic number to identify the file as your custom format (define it as a constant!)
  ds << (quint32)0xAAAAFFAA
  //Second the version number of your custom file (define it as a constant!)
  ds << (quint32)777
  //depending on the version number of your file you should select the 
  //apropiate datastream version
  ds.setVersion(QDataStream::Qt_4_6);
   foreach (const Contact &idContact, contactsList) 
   {
      // Fetch the complete details for this contact ID
      const Contact contact = m_contactService->contactDetails(idContact.id());
      QByteArray contactArray = m_contactService->contactToVCard(contact);
      ds << contactArray;
   }
  myFile.close()
}

To read you have to check the magic number and then the number version to select the appropriate datastream version.

Regards.

If my answer has been useful to you, please, click the button
New Developer
Posts: 37
Registered: ‎07-13-2014
My Device: Z10
My Carrier: Vodafone

Re: Generating vcf file using ContactService api

Thanks a lot for sharing this solution.

 

Well i have a query i copied the entire code and placed it in my method whats is now happening that while debugging i noticed that QFile object is not getting created.

void AddressBook::storeContactsToMemoryCard()
{

	QFile myFile(QDir::currentPath() + "vCardContacts.dat");

	if(myFile.open(QIODevice::WriteOnly))
	{
	  QDataStream ds(&myFile);
	  //First a magic number to identify the file as your custom format (define it as a constant!)
	  ds << (quint32)0xAAAAFFAA ;
	  //Second the version number of your custom file (define it as a constant!)
	  ds << (quint32)777 ;
	  //depending on the version number of your file you should select the
	  //apropiate datastream version
	  ds.setVersion(QDataStream::Qt_4_6);
	   foreach (const Contact &idContact, contactsList)
	   {
	      // Fetch the complete details for this contact ID
	      const Contact contact = m_contactService->contactDetails(idContact.id());
	      QByteArray contactArray = m_contactService->contactToVCard(contact);
	      ds << contactArray;
	   }
	  myFile.close();
	}

 Debugging at first line i noticed that QFile is not getting created. Please suggest what is missing in code.What all extra things need to be added

 

Also i have some queries:-

 

1.)  In code instead of QDir:currentPath if i wish to use the path of memory card is that feasible. The dat file should be generated in memory card. Some thing like FilePicker for memory card.

 

2.)  As you talked about magic number to identify the custom format of file is "0xAAAAFFAA" version number of custom file.

 

3.)  Will this dat file be valid for cross platforms too, for instance i want to read this file in an andriod application will it comply with that ?

 

4.) ALso please tell read code , how will be able to read file extract the contacts  and merge the contacts with existing in phone.

 

Please guide, I shall be highly obliged if you do so.

 

Thanks & Regards,

 

Developer
Posts: 158
Registered: ‎01-03-2013
My Device: n/a
My Carrier: n/a

Re: Generating vcf file using ContactService api

If you're going to let the user pick the path maybe you'd like to provide a parameter to the function to pass the path:

 

void AddressBook::storeContactsToMemoryCard(const QString& thePath)

 

 

As regards your questions:

 

1)I wrote QDir::currentPath as an example, you should provide the path your user has selected from a FilePicker.

2)It's just an example, you should define a magic number (whichever you want) for your file. This way, outside the class:

 

const quint32 magic = 0xABCABCAA

 3)Unless you're using Qt for android I don't think so. Keep in mind that each QDataStream version can change the internal way It saves the data, that's why you should have a way to identify which version the dataStream used to save the data. (that's the purpose of the version number in the file).

 

Take a look at this:

 

http://qt-project.org/doc/qt-4.8/qdatastream.html#versioning

 

4)

 

	QFile myFile(WHERE_THE_FILE_WAS_SAVED);

	if(myFile.open(QIODevice::ReadOnly))
	{
	  QDataStream ds(&myFile);
	  //First a magic number to identify the file as your custom format (define it as a constant!)
          quint32 magic;
	  ds >> magic;
	  //MyMagicNumber is a constant defined outside the class
          if(magic != MyMagicNumber)
	  {
	    //File is incompatible, return whatever you want to check for error
            return;
          }
	  //Second the version number of your custom file (define it as a constant!)
          quint32 fileVersion
	  ds >> fileVersion;
	  //depending on the version number of your file you should select the
	  //apropiate datastream version 
	  switch(fileVersion)
	  {
	    case 100:
	    case 200:
	      ds.setVersion(QDataStream::Qt_4_0);
	      break;
	    case 777:
	      ds.setVersion(QDataStream::Qt_4_6);
	      break;
	  }

	   while(!ds.atEnd())
	   {
              QByteArray tmpByteArray;
	      ds >> tmpByteArray;
	      //Fill your contactList
	   }
	  myFile.close();

 

 

 

 

 

Regards.

If my answer has been useful to you, please, click the button
New Developer
Posts: 37
Registered: ‎07-13-2014
My Device: Z10
My Carrier: Vodafone

Re: Generating vcf file using ContactService api

Hi Magnum,

 

Thanks i tried the above code but again i am getting the same error while debugging.

 

I am using BB10 simulator for running the application.

I have also enabled permission in bar_descriptor.xml file as:-

 

<permission system="true">run_native</permission>
    <permission>access_pimdomain_contacts</permission>
    <permission>access_shared</permission>
    <permission>access_sms_mms</permission>

 

The problem which is happening the code flow is not moving inside. myFile is coming as empty

 

if(myFile.open(QIODevice::WriteOnly))
{

 While debugging i also found the value of current path as:-

 

Name : currentPath
	Details:"/accounts/1000/appdata/com.example.bb10samples.pim.addressbook.testDev_addressbookf2ac4dee"
	Default:"/accounts/1000/appdata/com.example.bb10samples.pim.addressbook.testDev_addressbookf2ac4dee"
	Decimal:"/accounts/1000/appdata/com.example.bb10samples.pim.addressbook.testDev_addressbookf2ac4dee"
	Hex:"/accounts/1000/appdata/com.example.bb10samples.pim.addressbook.testDev_addressbookf2ac4dee"
	Binary:"/accounts/1000/appdata/com.example.bb10samples.pim.addressbook.testDev_addressbookf2ac4dee"
	Octal:"/accounts/1000/appdata/com.example.bb10samples.pim.addressbook.testDev_addressbookf2ac4dee"

 Method is as under:

 

void AddressBook::storeContactsToMemoryCard()
{

	QString currentPath = QDir::currentPath();
	QFile myFile(QDir::currentPath() + "vCardContacts.dat");

	if(myFile.open(QIODevice::WriteOnly))
	{
	  QDataStream ds(&myFile);
	  //First a magic number to identify the file as your custom format (define it as a constant!)
	  ds << (quint32)0xAAAAFFAA ;
	  //Second the version number of your custom file (define it as a constant!)
	  ds << (quint32)777 ;
	  //depending on the version number of your file you should select the
	  //apropiate datastream version
	  ds.setVersion(QDataStream::Qt_4_6);
	   foreach (const Contact &idContact, contactsList)
	   {
	      // Fetch the complete details for this contact ID
	      const Contact contact = m_contactService->contactDetails(idContact.id());
	      QByteArray contactArray = m_contactService->contactToVCard(contact);
	      ds << contactArray;
	   }
	  myFile.close();
	}
	/*// Iterate over the contact list and convert each contact into vCard format
	foreach (const Contact &idContact, contactsList) {
		// Fetch the complete details for this contact ID
		const Contact contact = m_contactService->contactDetails(idContact.id());
		QByteArray contactArray = m_contactService->contactToVCard(contact);
	}*/
}

 

Please tell what i am skipping here.

 

Thanks & Regards,

BlackBerry Development Advisor
Posts: 15,263
Registered: ‎07-09-2008
My Device: BlackBerry Passport
My Carrier: Bell

Re: Generating vcf file using ContactService api

You can't create a file in QDir::currentPath(), you need to use one of its sub directories or the shared area.  Refer to this doc for more information on where you can and should place your files.

 

Working with the file system

Mark Sohm
BlackBerry Development Advisor

Please refrain from posting new questions in solved threads.
Problem solved? Click the Accept As Solution button.
Found a bug? Report it using Issue Tracker
Highlighted
New Developer
Posts: 37
Registered: ‎07-13-2014
My Device: Z10
My Carrier: Vodafone

Re: Generating vcf file using ContactService api

Thanks Mark it worked