I want to export the Phone contacts to External storage area. I didn't work with this type of method. Anyone guide me to do this?
-
1"I didn't work with this type of method?" - which type of method? – user370305 Nov 16 '11 at 06:26
-
@user370305 : I don't have any experience of exporting files from phone programmatically. – Praveenkumar Nov 16 '11 at 06:29
-
Do you want it in programmatic way? – Dinesh Prajapati Nov 16 '11 at 06:30
-
@Drax : Yes, i want this as programmatically. – Praveenkumar Nov 16 '11 at 06:31
-
@Drax : I've this exception - java.lang.IllegalArgumentException: URI: content://com.android.contacts/contacts/as_vcard, calling user: com.android.phonecontacts, calling package:com.android.phonecontacts – Praveenkumar Nov 16 '11 at 07:07
-
@user370305 : See my exceptioin – Praveenkumar Nov 16 '11 at 07:07
-
@SPK there mistake regarding Argument – sam_k Nov 16 '11 at 07:30
-
@SPK have you done this. because I encounter with same exception. – Maheshwar Ligade Apr 14 '16 at 05:15
-
@Praveen its not working for me it throws IOException on device – Maheshwar Ligade Apr 14 '16 at 05:31
-
@MaheshwarLigade What kind of exception? – Praveenkumar Apr 14 '16 at 05:33
-
fis.read(buf), java.io.IOException: read failed: EINVAL (Invalid argument) – Maheshwar Ligade Apr 14 '16 at 05:37
-
Have you given proper permissions? @MaheshwarLigade – Praveenkumar Apr 14 '16 at 05:47
-
yes i have given all permission – Maheshwar Ligade Apr 14 '16 at 05:52
8 Answers
In your code, you wrote one function but from where is this function called? And what is the meaning of get(View view)
function? This function is not being called so it can be removed.
I've edited my answer as per your requirements and tested it with 500 Contacts to save a single vCard file with 500 contacts in my sd card.
package com.vcard;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
public class VCardActivity extends Activity
{
Cursor cursor;
ArrayList<String> vCard ;
String vfile;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
vfile = "Contacts" + "_" + System.currentTimeMillis()+".vcf";
/**This Function For Vcard And here i take one Array List in Which i store every Vcard String of Every Conatact
* Here i take one Cursor and this cursor is not null and its count>0 than i repeat one loop up to cursor.getcount() means Up to number of phone contacts.
* And in Every Loop i can make vcard string and store in Array list which i declared as a Global.
* And in Every Loop i move cursor next and print log in logcat.
* */
getVcardString();
}
private void getVcardString() {
// TODO Auto-generated method stub
vCard = new ArrayList<String>();
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if(cursor!=null&&cursor.getCount()>0)
{
cursor.moveToFirst();
for(int i =0;i<cursor.getCount();i++)
{
get(cursor);
Log.d("TAG", "Contact "+(i+1)+"VcF String is"+vCard.get(i));
cursor.moveToNext();
}
}
else
{
Log.d("TAG", "No Contacts in Your Phone");
}
}
public void get(Cursor cursor)
{
//cursor.moveToFirst();
String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd;
try {
fd = this.getContentResolver().openAssetFileDescriptor(uri, "r");
// Your Complex Code and you used function without loop so how can you get all Contacts Vcard.??
/* FileInputStream fis = fd.createInputStream();
byte[] buf = new byte[(int) fd.getDeclaredLength()];
fis.read(buf);
String VCard = new String(buf);
String path = Environment.getExternalStorageDirectory().toString() + File.separator + vfile;
FileOutputStream out = new FileOutputStream(path);
out.write(VCard.toString().getBytes());
Log.d("Vcard", VCard);*/
FileInputStream fis = fd.createInputStream();
byte[] buf = new byte[(int) fd.getDeclaredLength()];
fis.read(buf);
String vcardstring= new String(buf);
vCard.add(vcardstring);
String storage_path = Environment.getExternalStorageDirectory().toString() + File.separator + vfile;
FileOutputStream mFileOutputStream = new FileOutputStream(storage_path, false);
mFileOutputStream.write(vcardstring.toString().getBytes());
} catch (Exception e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}

- 7,594
- 4
- 34
- 45

- 5,983
- 14
- 76
- 110
-
-
java.lang.IllegalArgumentException: URI: content://com.android.contacts/contacts/as_vcard, calling user: com.android.phonecontacts, calling package:com.android.phonecontacts – Praveenkumar Nov 16 '11 at 07:06
-
1When i run this code i've this exception. This is the full detail. – Praveenkumar Nov 16 '11 at 07:09
-
hello sam_k i want to send .vcf file to mail id but after using ur code i get all contact's seprate .vcf file on my external storage(SD card) but problem is mine is that how to write all .vcf file in one single file and send it via attachment, i know how to send mail in android but how to make .vcf of all contacts in single file if its possible..vv thanks – shyam Dec 13 '11 at 09:42
-
and can u also explain about .vcf and how to use it for our contacts in android as i have done with .csv – shyam Dec 13 '11 at 09:44
-
-
@shyam Means You want to get all contacts in one file ?? if this is problem than send me code i will do and send back to you – sam_k Dec 13 '11 at 10:21
-
i only use ur above code for save contact information in sd card as.vcf file – shyam Dec 13 '11 at 10:26
-
but now how to send all the existing contacts as single .vcf file to any email id – shyam Dec 13 '11 at 10:59
-
hello sam_k i am waiting for ur response..sam_k i dont know more about vcard file and uses of vcf file can u pls explain it..and how to send .vcf file for all contacts as an attachment via mail – shyam Dec 13 '11 at 11:25
-
-
where is vcard.vcf file in sdcard...using our above code...there is only "Contacts" + "_" + System.currentTimeMillis()+".vcf"; named files in sd card where all vcf are diffrentiated by System.currentTimeMillis() method – shyam Dec 13 '11 at 11:49
-
let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/5811/discussion-between-sam-k-and-shyam) – sam_k Dec 13 '11 at 12:06
-
-
I have not read all the above comments....What I saw in code based on that get() method will be called again and again till the last contact we have...hence these lines will also execute every time : String storage_path = Environment.getExternalStorageDirectory().toString() + File.separator + vfile; FileOutputStream mFileOutputStream = new FileOutputStream(storage_path, false); mFileOutputStream.write(vcardstring.toString().getBytes());....hence @last we will have only one contact & I hv ran abov code & got wht I hv told in earlier lines. Hence I edited & posted again. – Caution Continues Nov 27 '12 at 08:57
-
@CautionContinues ya your are right. i will genrate multiple files for contacts. because the question requirement is like that ,dats y :) – sam_k Nov 27 '12 at 09:26
-
-
Android Nougat Update :
Other answers code working for lots of people before Nougat update.
Please take care of :
byte[] buf = new byte[(int) fd.getDeclaredLength()];
is not working on Android Nougat.
fd.getDeclaredLength() is always return -1.
Please use below code for read bytes without any library :
byte[] buf = readBytes(fis);
public byte[] readBytes(InputStream inputStream) throws IOException {
// this dynamically extends to take the bytes you read
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
// this is storage overwritten on each iteration with bytes
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
// we need to know how may bytes were read to write them to the byteBuffer
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
// and then we can return your byte array.
return byteBuffer.toByteArray();
}
The method readBytes() get from this answer.
-
I had this problem and had to post this [question](http://stackoverflow.com/q/42017591/4333665) – Balakrishna Avulapati Feb 13 '17 at 05:10
-
I am getting `java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.util.ArrayList.add(java.lang.Object)' on a null object reference` with this method. And `fd.getDeclaredLength()` is returning -1. – Shahbaz Talpur Oct 19 '17 at 15:30
-
-
@Shahbaz Talpur you are adding item to the list which is already null, means not initialized. Please initialize it before adding any data. fd.getDeclaredLength() return -1 in nougat, please use above code by passing your FileInputStrem to it. – SANAT Oct 20 '17 at 10:48
-
@SANAT I used your above code and it is giving me that null exception. I have passed my FileInputStream to it. – Shahbaz Talpur Oct 20 '17 at 11:05
-
@Shahbaz Talpur there is no java List and its add method in above readbytes() function. Please check your error's line number carefully. – SANAT Oct 20 '17 at 11:41
-
it's failed when number of contacts huge , error is FAILED BINDER TRANSACTION !!! (parcel size = 472) – iamkdblue Mar 20 '18 at 13:44
Try out this. its work for me to create a .vcf file of all contact and stored it into SDCARD.
make sure all permission are give properly.
public static void getVCF()
{
final String vfile = "POContactsRestore.vcf";
Cursor phones = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null, null, null);
phones.moveToFirst();
for(int i =0;i<phones.getCount();i++)
{
String lookupKey = phones.getString(phones.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd;
try
{
fd = mContext.getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
byte[] buf = new byte[(int) fd.getDeclaredLength()];
fis.read(buf);
String VCard = new String(buf);
String path = Environment.getExternalStorageDirectory().toString() + File.separator + vfile;
FileOutputStream mFileOutputStream = new FileOutputStream(path, true);
mFileOutputStream.write(VCard.toString().getBytes());
phones.moveToNext();
Log.d("Vcard", VCard);
}
catch (Exception e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}

- 983
- 3
- 13
- 25
I have removed the exception and other error and below is my CODE :
private final String vfile = "POContactsRestore.vcf";
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
null, null, null);
phones.moveToFirst();
String lookupKey = phones.getString(phones.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd;
try {
fd = this.getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
byte[] buf = new byte[(int) fd.getDeclaredLength()];
fis.read(buf);
String vCard = new String(buf);
String path = Environment.getExternalStorageDirectory().toString() + File.separator + vfile;
FileOutputStream mFileOutputStream = new FileOutputStream(path, false);
mFileOutputStream.write(vCard.toString().getBytes());
Log.d("Vcard", vCard);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
If you can iterate through loop and get the vCard for the contacts and store it in the SDCARD.

- 9,724
- 11
- 63
- 92

- 9,274
- 5
- 30
- 47
-
Yes, it's working perfect. I can see the vcard output in my logcat. Thanks. – Praveenkumar Nov 16 '11 at 07:55
-
-
this will be inside your package.. you can store this Vcard to SDCARD – Dinesh Prajapati Nov 16 '11 at 08:04
-
Well i can't see any VCard in my package. Could you please tell me how to store this to SDCARD – Praveenkumar Nov 16 '11 at 09:12
-
You have the String VCard = new String(buf); after that write code to write that in to the SDCARD. simple java program would do it – Dinesh Prajapati Nov 16 '11 at 09:18
-
1
-
-
i'm just beginner for SDCard usage. I didn't use sdcard for before this project. – Praveenkumar Nov 16 '11 at 10:05
-
Oh God! this is not working when i'm trying to do like this i've this exception - java.io.FileNotFoundException: /mnt/sdcard/test.vcf (Permission denied). But, i've already give External storage permission. What am missing? – Praveenkumar Nov 16 '11 at 10:49
-
-
give write permission for external storage. and read contacts – Dinesh Prajapati Nov 16 '11 at 11:13
-
For me no Crash copy pasted your code and got the file generated. are you using Emulator/device? please check for SDCARD on Both – Dinesh Prajapati Nov 16 '11 at 11:35
-
-
-
let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/5052/discussion-between-drax-and-spk) – Dinesh Prajapati Nov 16 '11 at 11:44
-
this code not working for android api 7.0+ nougat show java.io.FileNotFoundException: /sdcard/POContactsRestore.vcf (No such file or directory) but it work for lower api can you help? – Jayman Jani Sep 25 '17 at 09:04
-
Maybe you have to make sure for permission for external storage. as we are creating the file and storing it on the SDCARD. you can create file wherever possible for your project – Dinesh Prajapati Sep 26 '17 at 14:08
I tried above two codes and I got the .VCF file too, but it was containing only one contact. so here is Perfectly Edited and running code....you will get all contacts in .VCF file:
private void getVcardString() throws IOException {
// TODO Auto-generated method stub
vCard = new ArrayList<String>(); // Its global....
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if(cursor!=null&&cursor.getCount()>0)
{
int i;
String storage_path = Environment.getExternalStorageDirectory().toString() + File.separator + vfile;
FileOutputStream mFileOutputStream = new FileOutputStream(storage_path, false);
cursor.moveToFirst();
for(i = 0;i<cursor.getCount();i++)
{
get(cursor);
Log.d("TAG", "Contact "+(i+1)+"VcF String is"+vCard.get(i));
cursor.moveToNext();
mFileOutputStream.write(vCard.get(i).toString().getBytes());
}
mFileOutputStream.close();
cursor.close();
}
else
{
Log.d("TAG", "No Contacts in Your Phone");
}
}
Second Method:
private void get(Cursor cursor2) {
String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd;
try {
fd = this.getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
byte[] buf = new byte[(int) fd.getDeclaredLength()];
fis.read(buf);
String vcardstring= new String(buf);
vCard.add(vcardstring);
} catch (Exception e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
Please Don't forget to add :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

- 743
- 2
- 10
- 25
-
1I have used above code and getting error in `fis.read(buf)`, `java.io.IOException: read failed: EINVAL (Invalid argument)` – Dharmik Jun 29 '13 at 05:03
-
-
Where r u testing I mean emulator or real device ??? and If you are using emulator then make sure that you have allocated some space to emulator SD cards coz we are writing .VCF file on SD cards. On real device I am not getting any problem....Pls check and let me know... – Caution Continues Sep 19 '13 at 07:21
It's working for me and as well working in Nougat devices. Thank you so much @pratik and @sanat .
public static void getVCF(Context context)
{
final String vfile = "POContactsRestore.vcf";
Cursor phones = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null, null, null);
phones.moveToFirst();
for(int i =0;i<phones.getCount();i++)
{
String lookupKey = phones.getString(phones.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd;
try
{
fd = context.getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
byte[] buf = readBytes(fis);
fis.read(buf);
String VCard = new String(buf);
String path = Environment.getExternalStorageDirectory().toString() + File.separator + vfile;
FileOutputStream mFileOutputStream = new FileOutputStream(path, true);
mFileOutputStream.write(VCard.toString().getBytes());
phones.moveToNext();
Log.d("Vcard", VCard);
}
catch (Exception e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
public static byte[] readBytes(InputStream inputStream) throws IOException {
// this dynamically extends to take the bytes you read
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
// this is storage overwritten on each iteration with bytes
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
// we need to know how may bytes were read to write them to the byteBuffer
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
// and then we can return your byte array.
return byteBuffer.toByteArray();
}

- 3,448
- 2
- 25
- 43
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.ContactsContract;
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.util.Log;
public class Contacts extends Activity{
Cursor cursor;
ArrayList<String> vCard ;
String vfile;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
getVcardString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void getVcardString() throws IOException {
final String vfile = "POContactsRestore.vcf";
// TODO Auto-generated method stub
vCard = new ArrayList<String>();
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if(cursor!=null&&cursor.getCount()>0)
{
int i;
String storage_path = Environment.getExternalStorageDirectory().toString() + File.separator + vfile;
FileOutputStream mFileOutputStream = new FileOutputStream(storage_path, false);
cursor.moveToFirst();
for(i = 0;i<cursor.getCount();i++)
{
get(cursor);
Log.d("TAG", "Contact "+(i+1)+"VcF String is"+vCard.get(i));
cursor.moveToNext();
mFileOutputStream.write(vCard.get(i).toString().getBytes());
}
mFileOutputStream.close();
cursor.close();
}
else
{
Log.d("TAG", "No Contacts in Your Phone");
}
}
private void get(Cursor cursor2) {
String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd;
try {
fd = this.getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
byte[] buf = new byte[(int) fd.getDeclaredLength()];
fis.read(buf);
String vcardstring= new String(buf);
vCard.add(vcardstring);
} catch (Exception e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.anthem.contactbackup"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="5"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".Con"
android:label="@string/title_activity_contact_backup" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

- 290
- 3
- 20
private void convertToVcfFile(String contactId, File contactFile) {
Cursor mCursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, ContactsContract.CommonDataKinds.Phone._ID + " = " + contactId,
null, null);
if(mCursor != null && mCursor.moveToFirst()) {
do {
String mLookupKey = mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri mUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, mLookupKey);
try {
AssetFileDescriptor mAssetFileDescriptor = getContentResolver().openAssetFileDescriptor(mUri, "r");
if (mAssetFileDescriptor != null) {
FileInputStream mFileInputStream = mAssetFileDescriptor.createInputStream();
byte[] mBuffer = new byte[(int) mAssetFileDescriptor.getDeclaredLength()];
mFileInputStream.read(mBuffer);
String VCardString = new String(mBuffer);
FileOutputStream mFileOutputStream = new FileOutputStream(contactFile, true);
mFileOutputStream.write(VCardString.getBytes());
}
} catch (Exception e1) {
e1.printStackTrace();
}
} while (mCursor.moveToNext());
mCursor.close();
}
}

- 91
- 1
- 2