从android中的指定组获取联系人
Posted
技术标签:
【中文标题】从android中的指定组获取联系人【英文标题】:getting contacts from a specified group in android 【发布时间】:2012-08-29 02:33:51 【问题描述】:我正在尝试从已知 id 的特定组中获取联系人。我能够获取该组中的组 id 和联系人姓名。但我无法获取联系人号码。尝试了一些来自谷歌搜索的解决方案,但是每次我得到与组ID相同的电话号码时,如果我使用Phone.number,Phone.DISPLAY_NAME查询组的电话号码和联系人姓名。如果我使用以下方法,我会收到错误 请帮我弄清楚我的代码有什么问题。
代码:
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.group_contacts);
addGroups = (Button) findViewById(R.id.selectGroup);
groupAdapter = new SimpleCursorAdapter(getApplicationContext(),
android.R.layout.select_dialog_singlechoice, GroupCursor(),
new String[] ContactsContract.Groups.TITLE ,
new int[] android.R.id.text1 );
setListAdapter(groupAdapter);
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
addGroups.setOnClickListener(new OnClickListener()
public void onClick(View v)
Intent intent = new Intent(myGroups.this, Main.class);
Bundle carry = new Bundle();
carry.putStringArrayList("numbers", cNumbers);
carry.putStringArrayList("name", cNames);
intent.putExtras(carry);
setResult(RESULT_OK, intent);
finish();
);
private Cursor GroupCursor()
String[] projection = ContactsContract.Groups.TITLE,
ContactsContract.Groups._ID ;
Cursor gCursor = getContentResolver().query(
ContactsContract.Groups.CONTENT_URI, projection, null, null,
ContactsContract.Groups.TITLE);
// int idcolumn = gCursor.getColumnIndex(ContactsContract.Groups._ID);
// String id = gCursor.getString(idcolumn);
// Log.d(E, "group id : " + id );
return gCursor;
@Override
protected void onListItemClick(ListView l, View v, int position, long id)
super.onListItemClick(l, v, position, id);
Log.d(E, "id : " + id);
String groupId = Long.toString(id);
String[] cProjection = Phone.NUMBER, Phone.DISPLAY_NAME ,Contacts.DISPLAY_NAME, Contacts._ID;
Cursor groupCursor = getContentResolver().query(Data.CONTENT_URI,
cProjection,
CommonDataKinds.GroupMembership.GROUP_ROW_ID + "= ?",
new String[]groupId, null);
if (groupCursor != null)
groupCursor.moveToFirst();
do
int nameCoumnIndex = groupCursor
.getColumnIndex(Phone.DISPLAY_NAME);
String name = groupCursor.getString(nameCoumnIndex);
String cId = groupCursor.getString(groupCursor.getColumnIndex(Contacts._ID));
Cursor numberCursor = getContentResolver().query(Phone.CONTENT_URI, new String[]Phone.NUMBER, Phone._ID +"="+cId, null, null);
numberCursor.moveToFirst();
int numberColumnIndex = numberCursor
.getColumnIndex(Phone.NUMBER);
Log.d(E, "numberindex : " + numberColumnIndex);
String number = numberCursor.getString(numberColumnIndex);
cNumbers.add(number);
Log.d(E, "contact " + name + ":" + number);
cNames.add(name);
while (groupCursor.moveToNext());
日志:
09-04 17:59:24.943: D/dalvikvm(18084): GC_EXTERNAL_ALLOC freed 23K, 48% free 2844K/5379K, external 1032K/1039K, paused 24ms
09-04 17:59:26.054: D/(18084): id : 14
09-04 17:59:26.074: D/(18084): numberindex : 0
09-04 17:59:26.074: D/AndroidRuntime(18084): Shutting down VM
09-04 17:59:26.074: W/dalvikvm(18084): threadid=1: thread exiting with uncaught exception (group=0x40015568)
09-04 17:59:26.084: E/AndroidRuntime(18084): FATAL EXCEPTION: main
09-04 17:59:26.084: E/AndroidRuntime(18084): android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
09-04 17:59:26.084: E/AndroidRuntime(18084): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
09-04 17:59:26.084: E/AndroidRuntime(18084): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
09-04 17:59:26.084: E/AndroidRuntime(18084): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
09-04 17:59:26.084: E/AndroidRuntime(18084): at android.database.CursorWrapper.getString(CursorWrapper.java:135)
09-04 17:59:26.084: E/AndroidRuntime(18084): at hm.swarna.groupsms.myGroups.onListItemClick(myGroups.java:117)
09-04 17:59:26.084: E/AndroidRuntime(18084): at android.app.ListActivity$2.onItemClick(ListActivity.java:319)
09-04 17:59:26.084: E/AndroidRuntime(18084): at android.widget.AdapterView.performItemClick(AdapterView.java:284)
09-04 17:59:26.084: E/AndroidRuntime(18084): at android.widget.ListView.performItemClick(ListView.java:3535)
09-04 17:59:26.084: E/AndroidRuntime(18084): at android.widget.AbsListView$PerformClick.run(AbsListView.java:1827)
09-04 17:59:26.084: E/AndroidRuntime(18084): at android.os.Handler.handleCallback(Handler.java:587)
09-04 17:59:26.084: E/AndroidRuntime(18084): at android.os.Handler.dispatchMessage(Handler.java:92)
09-04 17:59:26.084: E/AndroidRuntime(18084): at android.os.Looper.loop(Looper.java:130)
09-04 17:59:26.084: E/AndroidRuntime(18084): at android.app.ActivityThread.main(ActivityThread.java:3703)
09-04 17:59:26.084: E/AndroidRuntime(18084): at java.lang.reflect.Method.invokeNative(Native Method)
09-04 17:59:26.084: E/AndroidRuntime(18084): at java.lang.reflect.Method.invoke(Method.java:507)
09-04 17:59:26.084: E/AndroidRuntime(18084): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
09-04 17:59:26.084: E/AndroidRuntime(18084): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
09-04 17:59:26.084: E/AndroidRuntime(18084): at dalvik.system.NativeStart.main(Native Method)
09-04 17:59:27.556: I/Process(18084): Sending signal. PID: 18084 SIG: 9
【问题讨论】:
你已经实现了“// TODO 自动生成的方法存根”? 【参考方案1】:尝试在您的 onListItemClick 方法中使用以下代码:
long groupId = id;
String[] cProjection = Contacts.DISPLAY_NAME, GroupMembership.CONTACT_ID ;
Cursor groupCursor = getContentResolver().query(
Data.CONTENT_URI,
cProjection,
CommonDataKinds.GroupMembership.GROUP_ROW_ID + "= ?" + " AND "
+ ContactsContract.CommonDataKinds.GroupMembership.MIMETYPE + "='"
+ ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE + "'",
new String[] String.valueOf(groupId) , null);
if (groupCursor != null && groupCursor.moveToFirst())
do
int nameCoumnIndex = groupCursor.getColumnIndex(Phone.DISPLAY_NAME);
String name = groupCursor.getString(nameCoumnIndex);
long contactId = groupCursor.getLong(groupCursor.getColumnIndex(GroupMembership.CONTACT_ID));
Cursor numberCursor = getContentResolver().query(Phone.CONTENT_URI,
new String[] Phone.NUMBER , Phone.CONTACT_ID + "=" + contactId, null, null);
if (numberCursor.moveToFirst())
int numberColumnIndex = numberCursor.getColumnIndex(Phone.NUMBER);
do
String phoneNumber = numberCursor.getString(numberColumnIndex);
Log.d("your tag", "contact " + name + ":" + phoneNumber);
while (numberCursor.moveToNext());
numberCursor.close();
while (groupCursor.moveToNext());
groupCursor.close();
在查询属于指定组的联系人时,您需要指定 mimetype。而且由于单个联系人可以有多个电话号码,因此您可能需要查询所有电话号码。
编辑: 要获取至少有一个联系人电话号码的所有组,您可以使用以下查询:
ContentResolver cr = getContentResolver();
Uri groupsUri = ContactsContract.Groups.CONTENT_SUMMARY_URI;
String where = "((" + ContactsContract.Groups.GROUP_VISIBLE + " = 1) AND ("
+ ContactsContract.Groups.SUMMARY_WITH_PHONES + "!= 0))";
Cursor cursor = cr.query(groupsUri, null, where, null, null);
至于从指定组中获取具有电话号码的联系人 - 我不知道简单的解决方案。
【讨论】:
你能告诉我如何从一个群组以及至少有一个联系人的群组中获取带有电话号码的联系人吗?【参考方案2】:这是您所要求的答案。从特定组#name 获取所有电话号码。这个意大利面条肯定可以更短,如果你花一些时间来优化它。
public ArrayList<String> getAllNumbersFromGroupId(String navn)
String selection = ContactsContract.Groups.DELETED + "=? and " + ContactsContract.Groups.GROUP_VISIBLE + "=?";
String[] selectionArgs = "0", "1" ;
Cursor cursor = context.getContentResolver().query(ContactsContract.Groups.CONTENT_URI, null, selection, selectionArgs, null);
cursor.moveToFirst();
int len = cursor.getCount();
ArrayList<String> numbers = new ArrayList<String>();
for (int i = 0; i < len; i++)
String title = cursor.getString(cursor.getColumnIndex(ContactsContract.Groups.TITLE));
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Groups._ID));
if (title.equals(navn))
String[] cProjection = Contacts.DISPLAY_NAME, GroupMembership.CONTACT_ID ;
Cursor groupCursor = context.getContentResolver().query(
Data.CONTENT_URI,
cProjection,
CommonDataKinds.GroupMembership.GROUP_ROW_ID + "= ?" + " AND "
+ ContactsContract.CommonDataKinds.GroupMembership.MIMETYPE + "='"
+ ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE + "'",
new String[] String.valueOf(id) , null);
if (groupCursor != null && groupCursor.moveToFirst())
do
int nameCoumnIndex = groupCursor.getColumnIndex(Phone.DISPLAY_NAME);
String name = groupCursor.getString(nameCoumnIndex);
long contactId = groupCursor.getLong(groupCursor.getColumnIndex(GroupMembership.CONTACT_ID));
Cursor numberCursor = context.getContentResolver().query(Phone.CONTENT_URI,
new String[] Phone.NUMBER , Phone.CONTACT_ID + "=" + contactId, null, null);
if (numberCursor.moveToFirst())
int numberColumnIndex = numberCursor.getColumnIndex(Phone.NUMBER);
do
String phoneNumber = numberCursor.getString(numberColumnIndex);
numbers.add(phoneNumber);
while (numberCursor.moveToNext());
numberCursor.close();
while (groupCursor.moveToNext());
groupCursor.close();
break;
cursor.moveToNext();
cursor.close();
return numbers;
【讨论】:
【参考方案3】:我的解决方案
public static HashMap<String, String> getContactsForGroup(String groupID, Activity activity)
Cursor dataCursor = activity.getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
new String[] // PROJECTION
ContactsContract.Data.CONTACT_ID,
ContactsContract.Data.DISPLAY_NAME, // contact name
ContactsContract.Data.DATA1 // group
,
ContactsContract.Data.MIMETYPE + " = ? " + "AND " + // SELECTION
ContactsContract.Data.DATA1 + " = ? ", // set groupID
new String[] // SELECTION_ARGS
ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE,
groupID
,
null);
dataCursor.moveToFirst();
HashMap<String, String> map = new HashMap<>();
while (dataCursor.moveToNext()) //
String s0 = dataCursor.getString(0); //contact_id
String s1 = dataCursor.getString(1); //contact_name
String s2 = dataCursor.getString(2); //group_id
Log.d("tag", "contact_id: " + s0 + " contact: " + s1 + " groupID: "+ s2);
map.put(s0, s1);
return map;
【讨论】:
以上是关于从android中的指定组获取联系人的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Android 中的联系人中获取 ContactNumbers 数组的联系人姓名?
如何从 Android 中的联系人列表中获取联系人?使用联系提供商