【问题标题】:Export the Contacts as VCF file将联系人导出为 VCF 文件
【发布时间】:2011-12-30 03:49:39
【问题描述】:

我想将电话联系人导出到外部存储区。我没有使用这种方法。有人指导我这样做吗?

【问题讨论】:

  • “我没有使用这种方法?” - 哪种方法?
  • @user370305 : 我没有任何以编程方式从手机导出文件的经验。
  • 你想要以编程方式吗?
  • @Drax :是的,我希望以编程方式进行。
  • @Drax:我有这个异常 - java.lang.IllegalArgumentException:URI:content://com.android.contacts/contacts/as_vcard,调用用户:com.android.phonecontacts,调用包:com.android.phonecontacts

标签: android android-contacts vcf-vcard


【解决方案1】:

在您的代码中,您编写了一个函数,但该函数是从哪里调用的? get(View view)函数的含义是什么?此函数未被调用,因此可以将其删除。

我已根据您的要求编辑了我的答案,并使用 500 个联系人对其进行了测试,以便在我的 SD 卡中保存一个包含 500 个联系人的 vCard 文件。

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();
        }
    }
}

【讨论】:

  • 你必须绑定你自己的光标而不是你应该应用这个代码。
  • java.lang.IllegalArgumentException: URI: content://com.android.contacts/contacts/as_vcard,调用用户:com.android.phonecontacts,调用包:com.android.phonecontacts
  • 当我运行这段代码时,我遇到了这个异常。这是完整的细节。
  • 你好 sam_k 我想将 .vcf 文件发送到邮件 ID,但是在使用你的代码后,我在我的外部存储(SD 卡)上获得了所有联系人的单独 .vcf 文件,但我的问题是如何编写所有 .vcf 文件在一个文件中并通过附件发送,我知道如何在 android 中发送邮件,但如果可能的话,如何在单个文件中制作所有联系人的 .vcf ..vv 谢谢
  • 你能否解释一下.vcf 以及如何将它用于我们在android 中的联系人,就像我对.csv 所做的那样
【解决方案2】:

Android Nougat 更新:

在 Nougat 更新之前适用于很多人的其他答案代码。

请保重:

byte[] buf = new byte[(int) fd.getDeclaredLength()];

不适用于 Android Nougat

fd.getDeclaredLength() 总是返回 -1。

请在没有任何库的情况下使用以下代码读取字节:

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();
}

方法 readBytes() 从this 得到答案。

【讨论】:

  • 我遇到了这个问题,不得不发布这个question
  • 我用这种方法得到java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.util.ArrayList.add(java.lang.Object)' on a null object referencefd.getDeclaredLength() 返回 -1。
  • @SANAT 你能看看吗?
  • @Shahbaz Talpur 您正在将项目添加到已经为空的列表中,表示未初始化。请在添加任何数据之前对其进行初始化。 fd.getDeclaredLength() 在牛轧糖中返回 -1,请通过将 FileInputStrem 传递给它来使用上面的代码。
  • @SANAT 我使用了你上面的代码,它给了我那个空异常。我已将我的 FileInputStream 传递给它。
【解决方案3】:

试试这个。我的工作是创建所有联系人的 .vcf 文件并将其存储到 SDCARD 中。

确保正确授予所有权限。

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();
     }

 }
}

【讨论】:

    【解决方案4】:

    我已经删除了异常和其他错误,下面是我的代码:

        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();
                }
    

    如果您可以遍历循环并获取联系人的 vCard 并将其存储在 SDCARD 中。

    【讨论】:

    • 是的,它运行良好。我可以在我的 logcat 中看到 vcard 输出。谢谢。
    • 这个 vcf 文件存储在哪里?
    • 这将在您的包裹内。您可以将此 Vcard 存储到 SDCARD
    • 好吧,我在我的包裹中看不到任何 VCard。你能告诉我如何将它存储到 SDCARD
    • 好的,我会告诉你的。
    【解决方案5】:

    我尝试了以上两个代码,我也得到了 .VCF 文件,但它只包含一个联系人。所以这里是完美编辑和运行的代码......您将在 .VCF 文件中获得所有联系人:

    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");
        }
    }
    

    第二种方法:

    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();
        }
    }
    

    请不要忘记添加:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    

    【讨论】:

    • 我使用了上面的代码,在fis.read(buf)java.io.IOException: read failed: EINVAL (Invalid argument)中出现错误
    • 我使用相同的方法完全没有问题...让我检查一下
    • 你在哪里测试我的意思是模拟器还是真实设备???如果您使用的是模拟器,请确保您已为模拟器 SD 卡分配了一些空间,因为我们正在 SD 卡上写入 .VCF 文件。在真实设备上我没有遇到任何问题......请检查并告诉我......
    【解决方案6】:

    它适用于我,也适用于 Nougat 设备。非常感谢@pratik 和@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();
        }
    

    【讨论】:

      【解决方案7】:
      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>
      

      【讨论】:

        【解决方案8】:
        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();
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2013-08-26
          • 2016-11-13
          • 1970-01-01
          • 1970-01-01
          • 2011-05-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多