如何使用Android原生API以Vcard格式获取Android联系人

时间:2011-11-07 11:28:09

标签: android vcard

我正在尝试使用Android Api阅读VCard格式的Android设备联系人。 我找到了一个相同的链接: Android contatcs vcard API

并尝试编写相同的代码,但它无法正常工作,因为我无法获取lookupkey:

ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
                null, null, null, null);  
int num = cur.getCount();  // I get 2 , as there are two contacts

String lookupKey = cur.getString(cur.getColumnIndex(Contacts.LOOKUP_KEY));
// The above line gives error : android.database.CursorIndexOutOfBoundsException:
//  Index -1 requested, with a size of 2

Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd = resolver.openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
    byte[] b = new byte[(int)fd.getDeclaredLength()];
fis.read(b);
String vCard = new String(b);
sb.append(vCard);

任何人都可以告诉我如何获取上述代码的lookupkey,或者我们可以通过Android api获得联系人VCard格式。

3 个答案:

答案 0 :(得分:7)

你在这里:

Cursor cursor = context.getContentResolver().query(
                ContactsContract.Contacts.CONTENT_URI, null, null, null, null);

if (cursor != null && cursor.moveToFirst()) {
    try {
        do {
            String lookupKey = cursor.getString(cursor
                    .getColumnIndex(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[] b = new byte[(int) fd.getDeclaredLength()];
                fis.read(b);
                String vCard = new String(b);
                Log.i(TAG, vCard);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } while (cursor.moveToNext());
    } finally {
        cursor.close();
    }
}

答案 1 :(得分:1)

- 编辑2 ---

看起来你在读光标之前没有做cur.moveToFirst(),所以你得到了优秀。试着看看描述同样问题的android.database.CursorIndexOutOfBoundsException: Index -1 requested

- 编辑回答 -

代码中的

LookUpKey用于特定联系人。您使用的conde示例是获取特定联系人的vcard。你必须循环通过可用的联系人,你可以在里面放置你必须使用的代码。您可以从联系合同中查找密钥。

除此之外,您应该考虑采用一般解决方案:

  1. 请在logcat
  2. 中添加错误
  3. 您是否在应用程序清单中添加了联系人权限以允许应用程序阅读联系人?

答案 2 :(得分:0)

public static void getVCF() {
    final String vfile = "Contacts.csv";
    Cursor phones = mContext.getContentResolver().query(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
            null, null);
    phones.moveToFirst();

    do {
        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();
        }
    } while (phones.moveToNext());

}