我尝试使用此代码段来检索一个接一个的联系人。
信息:我已设置权限<uses-permission android:name="android.permission.READ_CONTACTS"/>
Context context = getActivity();
Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, new String[]{Phone.NUMBER}, null, null, null);
while (cursor.moveToNext()) {
String number = cursor.getString(cursor.getColumnIndex(Phone.NUMBER));
Log.i("Number: ", number);
}
cursor.close();
这就是我的StackTrace发布的内容,我真的不明白它的内容:
Pick [Android Application]
<terminated>Pick [Android Application]
<disconnected>DalvikVM [localhost:8600]
Pick [Android Application]
DalvikVM [localhost:8600]
Thread [<1> main] (Suspended (exception IllegalArgumentException))
<VM does not provide monitor information>
ContextImpl$ApplicationContentResolver(ContentResolver).query(Uri, String[], String, String[], String, CancellationSignal) line: 458
ContextImpl$ApplicationContentResolver(ContentResolver).query(Uri, String[], String, String[], String) line: 360
FragmentContacts.onCreateView(LayoutInflater, ViewGroup, Bundle) line: 21
FragmentContacts(Fragment).performCreateView(LayoutInflater, ViewGroup, Bundle) line: 1500
FragmentManagerImpl.moveToState(Fragment, int, int, int, boolean) line: 927
FragmentManagerImpl.moveToState(int, int, int, boolean) line: 1104
BackStackRecord.run() line: 682
FragmentManagerImpl.execPendingActions() line: 1467
FragmentManagerImpl$1.run() line: 440
Handler.handleCallback(Message) line: 730
FragmentActivity$1(Handler).dispatchMessage(Message) line: 92
Looper.loop() line: 137
ActivityThread.main(String[]) line: 5419
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 525
ZygoteInit$MethodAndArgsCaller.run() line: 1187
ZygoteInit.main(String[]) line: 1003
NativeStart.main(String[]) line: not available [native method]
Thread [<10> Binder_2] (Running)
Thread [<9> Binder_1] (Running)
Daemon Thread [<11> RefQueueWorker@org.apache.http.impl.conn.tsccm.ConnPoolByRoute@42a6b128] (Running)
Thread [<14> pool-3-thread-1] (Running)
Thread [<15> ParseCommandCache.runLoop()] (Running)
答案 0 :(得分:2)
这是因为您正在尝试获取查询时未请求的列数据。将您的查询行更改为:
Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, new String[]{Phone.NUMBER}, null, null, null);
对于要从中读取数据的每一列,请确保您还将其包含在投影数组中。 query()方法的第二个参数是一个String数组,其中包含您感兴趣的列。
更好的方法是:
// columns we're interested in reading data from
String[] projection = {Phone.NUMBER, OTHER_COLUMNS};
Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, projection, null, null, null);
阅读本教程以获取更多信息:http://developer.android.com/training/load-data-background/index.html
更新:您无法直接从联系人表格中获取电话号码。它们存储在不同的表中,因为联系人可以有多个号码。
为此,我们必须使用嵌套的游标查询。以下是它的工作方式:
将ContactsContract.Contacts._ID
添加到投影数组中。此ID字段包含每个联系人的联系人ID。
迭代光标和每个联系人ID,获取他的号码。
以下是详细解决方案:
// uri for the contacts data
Uri contactsUri = ContactsContract.Contacts.CONTENT_URI;
// columns we're interested in
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
};
// we do not want contacts who do not have phone numbers
// so we'll only query contacts whose phone numbers count is > 0
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + " >? ";
String[] selectionArgs = new String[] {"0"};
// query all contacts
Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, projection, selection, selectionArgs, null);
// this list will hold lists of phone numbers of all contacts
ArrayList<ArrayList<String>> allContactNumbers = new ArrayList<ArrayList<String>>();
if(cursor != null){
try{
// for each contact Id, we'll fetch his numbers
while(cursor.moveToNext()){
// get his contactId
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID))
// ArrayList that will hold his phone numbers
ArrayList<String> phoneNumbers = new ArrayList<String>();
Cursor numberCursor = contResv.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{ contactId }, null);
try{
// add each phone number to phoneNumbers
while (numberCursor.moveToNext()){
String contactNumber = numberCursor.getString(numberCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
phoneNumbers.add(contactNumber);
}
}finally{
numberCursor.close();
}
// and add each contact's phone numbers to our master list
allContactNumbers.add(phoneNumbers);
}finally{
// close the cursor when we're done using it to avoid any database leaks
cursor.close();
}
}
// now do whatever you want with allContactNumbers.