【问题标题】:How do I get a phone number from a ContentResolver with a single query?如何通过单个查询从 ContentResolver 获取电话号码?
【发布时间】:2016-06-25 10:13:31
【问题描述】:

我正在使用下面的代码获取联系人姓名和 ID,但我没有得到电话号码。如何从下面的代码中获取电话号码?

ContentResolver contentResolver = getBaseContext().getContentResolver();

Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = {
        ContactsContract.Contacts._ID,
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.Contacts.HAS_PHONE_NUMBER,
        ContactsContract.Contacts.STARRED,
        ContactsContract.Contacts.TIMES_CONTACTED,
        ContactsContract.Contacts.LAST_TIME_CONTACTED
};
String selection = String.format("%s > 0", ContactsContract.Contacts.HAS_PHONE_NUMBER);
String[] selectionArgs = null;
String sortOrder = String.format(
        "%s DESC, %s DESC, %S DESC, UPPER(%s) ASC",
        ContactsContract.Contacts.STARRED,
        ContactsContract.Contacts.TIMES_CONTACTED,
        ContactsContract.Contacts.LAST_TIME_CONTACTED,
        ContactsContract.Contacts.DISPLAY_NAME
);
Cursor cursor = contentResolver.query(uri, projection, selection, selectionArgs, sortOrder);

if (cursor.getCount() > 0) {
    while (cursor.moveToNext()) {
        String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
        String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));


        if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {

            System.out.println("name : " + name + ", ID : ");

         }

        }
    }
    cursor.close();
}

【问题讨论】:

  • 你能在这方面取得进展吗?

标签: android android-contentresolver


【解决方案1】:

CModel.java

public class CModel {
String firstname;
String lastname;
String contactno;
String Imagepath;
int ID;
String contactid;

public String getCheck() {
    return Check;
}

String Check;

public String getContactid() {
    return contactid;
}

 public CModel(String fnm, String lastname, String userprofile, int ID,    String contactno, String Check) {
    this.firstname = fnm;
    this.lastname = lastname;
    this.Imagepath = userprofile;
    this.ID = ID;
    this.contactno = contactno;
    this.Check = Check;
}


public String getFirstname() {
    return firstname;
}

public String getLastname() {
    return lastname;
}

public String getContactno() {
    return contactno;
}

public String getImagepath() {
    return Imagepath;
}

public int getID() {
    return ID;
}

在你的活动文件中调用这个方法

private ArrayList<CModel> getcontact() {
ArrayList<CModel> contactlist = new ArrayList<CModel>;
try {
    Bitmap my_btmp = null;
    String profilepic;
    String phone = null;
    contactlist = new ArrayList<CModel>();
    ContentResolver cr = getContentResolver();
    String[] projection = new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, projection, null, null,
            ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
    while (cur.moveToNext()) {
        String contactId = cur.getString(cur.getColumnIndex(ContactsContract.Data._ID));
        String displayName = cur.getString(cur.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
        Uri my_contact_Uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(contactId));
        InputStream photo_stream = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), my_contact_Uri);
        Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                new String[]{contactId}, null);
        while (pCur.moveToNext()) {
            phone = pCur.getString(
                    pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        }
        pCur.close();
        if (photo_stream != null) {
            BufferedInputStream buf = new BufferedInputStream(photo_stream);
            my_btmp = BitmapFactory.decodeStream(buf);
            profilepic = BitMapToString(my_btmp);
        } else {
            Bitmap bitmap = BitmapFactory.decodeResource(HomePage.this.getResources(), R.drawable.profilepic);
            my_btmp = bitmap;
            profilepic = BitMapToString(my_btmp);

        }
        String columns[] = {
                ContactsContract.CommonDataKinds.Event.START_DATE,
                ContactsContract.CommonDataKinds.Event.TYPE,
                ContactsContract.CommonDataKinds.Event.MIMETYPE,
        };
        String where =ContactsContract.CommonDataKinds.Event.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE + "' and " + ContactsContract.Data.CONTACT_ID + " = " + contactId;
        String[] selectionArgs = null;
        String sortOrder = ContactsContract.Contacts.DISPLAY_NAME;
        Cursor birthdayCur = cr.query(ContactsContract.Data.CONTENT_URI, columns, where, selectionArgs, sortOrder);
        if (birthdayCur.getCount() > 0) {
            if (birthdayCur.moveToFirst()) {
                do {

                    contactlist.add(new CModel(displayName, "", profilepic, 0, phone,"phone"));
                    boolean flag = con.comparedata(phone);

                } while (birthdayCur.moveToNext());

            }

        }
        birthdayCur.close();
    }
    cur.close();
} catch (Exception e) {
}
return contactlist;

}

【讨论】:

  • 创建第一个 CModel.java 文件并粘贴我已经给出的第一个代码,然后在你的活动文件中粘贴 getcontact() 方法和 ctrl+space 如果在导入所有之后发生任何错误需要的包。
  • 然后 jst 调用 getcontact() 它将返回您手机中的联系人列表,并授予读取联系人的权限
  • 但是加载需要很长时间!!
  • 我只需要数字.. 我的代码加载速度非常快,但没有数字
【解决方案2】:

“ContactsContract.Contacts”中没有电话号码,但“ContactsContract.Contacts._ID”和“ContactsContract.CommonDataKinds.Phone.CONTACT_ID”对于每个联系人都是相同的。因此,您可以从 'ContactsContract.CommonDataKinds.Phone.CONTENT_URI' 获取电话号码。将此代码放在光标的循环中。总的来说,这是两个查询,但至少您知道在哪里搜索。这应该不会花费太多时间。

Cursor phoneCursor = managedQuery(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId , null, null);

        while (phoneCursor.moveToNext()) {
           String phone = phoneCursor.getString(phoneCursor
                    .getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));

        }

【讨论】:

    【解决方案3】:

    编辑:这是我在 1 个查询中检索每个电话号码的尝试,但我不确定是否存在任何没有电话号码的联系人;通常,最佳做法是始终查询具有电话号码的联系人列表,然后仅查询这些联系人号码。

    Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
    while (phones.moveToNext())
    {
        String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
        String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
    
        //Do something with each name and phone somewhere each time you loop through; in your provided code you seemed to be printing them out
    
    }
    phones.close();
    

    供参考:Read all contact's phone numbers in android



    根据我之前写给联系人的一些工作,这篇较旧的帖子似乎很有帮助:How to get contacts' phone number in Android

    一般情况下,电话号码存储为:

    ContactsContract.CommonDataKinds.Phone.NUMBER 
    

    所以对你提供的代码做一个 sn-p,我会大致这样编辑:

    if (cursor.getCount() > 0) {
            while (cursor.moveToNext()) {
                String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
                String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
    
    
                ...
                ...
    
            cursor.close();
        } 
    

    当然,您需要确保在查询中从联系人中获取正确的数据段(即更新您的投影),但这应该有望为您指明正确的方向!

    【讨论】:

    • 我收到一个错误,因为该列不存在。请你写下整个查询。因为这个查询总是在系统上崩溃。我已经尝试了大约 100 次...请你能用电话号码重写整个查询吗..谢谢..我真的很感激。
    • ContactsContract 数据库有各种可扩展的表,您可以通过在查询中定义的 URI 访问这些表。这些不同的表在这里定义:developer.android.com/reference/android/provider/… 所以在你提供的代码中,URI 是 ContactsContract.Contacts.CONTENT_URI;但是,此 URI 指向 Contacts 表,因此您无权访问 ContactsContract db 中的其他表。因此,您需要 1. 对不同的表进行多次查询(听起来是错误的)或 2. 在 ContactsContract 中找到一个可以访问您需要的所有数据的表。
    • ^ 然后修改您的 URI(和投影/选择)以访问正确的表并检索您想要的值(数字、名称和 id)。另请注意,_id 通常只是表/联系人数据库中联系人的 id,我认为这与行号有关,因此可能不是有用的信息。
    • 通过更多的研究,似乎没有一种方法可以同时检索联系人列表和他们的电话号码,只需 1 个查询。所以执行速度总会受到2个查询的阻碍。这将是及时的,因为您不是在查找一个特定的数字,而是每个 1。
    猜你喜欢
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多