我如何通过在Android的native Contacts应用程序中单击自定义字段来获取联系人的电话号码?
情况: 我已经按照和中的说明向Android中的联系人添加了自定义操作。按下时,我想在我的应用程序中拨打该联系人。我能够在按下自定义操作时打开的活动中成功检索联系人 我执行以下命令:我如何通过在Android的native Contacts应用程序中单击自定义字段来获取联系人的电话号码?,android,native,contacts,android-contact-mimetype,Android,Native,Contacts,Android Contact Mimetype,情况: 我已经按照和中的说明向Android中的联系人添加了自定义操作。按下时,我想在我的应用程序中拨打该联系人。我能够在按下自定义操作时打开的活动中成功检索联系人 我执行以下命令: Cursor cursor = context.getContentResolver().query(data, null, null, null, null); if (cursor != null) { newIntent = true; contact = LocalContactAsync.
Cursor cursor = context.getContentResolver().query(data, null, null, null, null);
if (cursor != null) {
newIntent = true;
contact = LocalContactAsync.getContacts(cursor, context.getContentResolver()).get(0);
cursor.close();
}
我从Android检索到的数据是:
content://com.android.contacts/data/2849
请注意末尾的数字2849,这不是联系人的本机ID。联系人的本机ID为459
。我能够成功检索执行此查询的联系人,返回以下数据:
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID);
-返回'2849'
cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)) ;
-返回正确的“样本样本”
但尽管这是事实:
cursor.getInt(cur.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0)
以下函数返回一个空游标:
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id}, null);
-在这种情况下,id=2849,但如果我填写459,我将检索正确数量的电话号码
真实联系人有3个号码,因此它应该返回3个号码
我怎样才能解决这个问题
编辑:
这就是我检索号码的方式,很清楚:我得到了正确的姓名,但是当联系人有号码时,下面的查询返回null
ArrayList<Number> numbers = new ArrayList<>();
if (cur.getInt(cur.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id}, null);
while (pCur.moveToNext()) {
numbers.add(new nl.coffeeit.clearvoxnexxt.objects.dto.Number(pCur.getString(pCur.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER))));
}
pCur.close();
}
return numbers;
ArrayList number=new ArrayList();
if(cur.getInt(cur.getColumnIndex(
Contacts contact.Contacts.HAS_PHONE_NUMBER))>0){
游标pCur=cr.query(
ContactsContract.CommonDataTypes.Phone.CONTENT\u URI,
无效的
ContactsContract.CommonDataTypes.Phone.CONTACT_ID+“=?”,
新字符串[]{id},null);
while(pCur.moveToNext()){
add(新的nl.coffeet.clearvoxnexxt.objects.dto.Number(pCur.getString(pCur.getColumnIndex(
Contacts contract.CommonDataTypes.Phone.NUMBER));
}
pCur.close();
}
返回号码;
请注意,我不请求意向,我通过添加到本机联系人的自定义操作接收意向,如Viber和WhatsApp do:
完整代码LocalContacts异步:
private static final String TAG = "LocalContactAsync";
private static List<Contact> contacts;
private Context context;
private boolean refreshOtherFragments;
private boolean renew;
private synchronized List<Contact> getContacts(Context context) {
if (!renew && contacts != null) {
return contacts;
}
ContentResolver cr = context.getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
if (cur != null && cur.getCount() > 0) {
contacts = getContacts(cur, cr);
cur.close();
return contacts;
}
if (cur != null) {
cur.close();
}
return new ArrayList<>();
}
public static List<Contact> getContacts(Cursor cur, ContentResolver cr) {
List<Contact> contacts = new ArrayList<>();
while (cur.moveToNext()) {
String id = getId(cur);
String name = getName(cur);
ArrayList<Number> numbers = getNumbers(cur, cr, id);
if (name != null) {
contacts.add(new Contact(id, name, numbers));
}
}
Log.d(TAG, "amount of contacts" + contacts.size());
return contacts;
}
private static ArrayList<Number> getNumbers(Cursor cur, ContentResolver cr, String id) {
ArrayList<Number> numbers = new ArrayList<>();
if (cur.getInt(cur.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id}, null);
while (pCur.moveToNext()) {
numbers.add(getNumber(pCur));
}
pCur.close();
}
return numbers;
}
private static Number getNumber(Cursor pCur) {
return new nl.coffeeit.clearvoxnexxt.objects.dto.Number(pCur.getString(pCur.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER)));
}
private static String getId(Cursor cur) {
return cur.getString(
cur.getColumnIndex(ContactsContract.Contacts._ID));
}
private static String getName(Cursor cur) {
return cur.getString(cur.getColumnIndex(
ContactsContract.Contacts.DISPLAY_NAME));
}
private static final String TAG=“LocalContactAsync”;
私人静态列表联系人;
私人语境;
私有布尔片段;
私有布尔更新;
专用同步列表getContacts(上下文){
如果(!续订和联系人!=空){
返回联系人;
}
ContentResolver cr=context.getContentResolver();
Cursor cur=cr.query(Contacts contract.Contacts.CONTENT\u URI,
空,空,空,空);
如果(cur!=null&&cur.getCount()>0){
触点=获取触点(电流、电流);
cur.close();
返回联系人;
}
如果(cur!=null){
cur.close();
}
返回新的ArrayList();
}
公共静态列表getContacts(游标cur、ContentResolver cr){
列表联系人=新建ArrayList();
while(cur.moveToNext()){
字符串id=getId(cur);
字符串名称=getName(cur);
ArrayList numbers=getNumbers(cur、cr、id);
if(name!=null){
联系人。添加(新联系人(id、姓名、号码));
}
}
Log.d(标记“联系人数量”+contacts.size());
返回联系人;
}
私有静态ArrayList getNumbers(游标cur、ContentResolver cr、字符串id){
ArrayList编号=新的ArrayList();
if(cur.getInt(cur.getColumnIndex(
Contacts contact.Contacts.HAS_PHONE_NUMBER))>0){
游标pCur=cr.query(
ContactsContract.CommonDataTypes.Phone.CONTENT\u URI,
无效的
ContactsContract.CommonDataTypes.Phone.CONTACT_ID+“=?”,
新字符串[]{id},null);
while(pCur.moveToNext()){
添加(getNumber(pCur));
}
pCur.close();
}
返回号码;
}
专用静态编号getNumber(光标pCur){
返回新的nl.coffeeit.clearvoxnext.objects.dto.Number(pCur.getString(pCur.getColumnIndex(
Contacts contract.CommonDataTypes.Phone.NUMBER));
}
私有静态字符串getId(游标cur){
返回cur.getString(
cur.getColumnIndex(ContactsContract.Contacts.\u ID));
}
私有静态字符串getName(游标cur){
返回cur.getString(cur.getColumnIndex(
Contacts contract.Contacts.DISPLAY_NAME));
}
数字DTO的代码:
public class Number implements Parcelable, Serializable {
@SerializedName("number")
@Expose
public String number;
@SerializedName("type")
@Expose
public String type = "";
@SerializedName("inherited")
@Expose
public Boolean inherited = false;
public Number(String number) {
this.number = number;
}
protected Number(Parcel in) {
number = in.readString();
type = in.readString();
byte inheritedVal = in.readByte();
inherited = inheritedVal == 0x02 ? null : inheritedVal != 0x00;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(number);
dest.writeString(type);
if (inherited == null) {
dest.writeByte((byte) (0x02));
} else {
dest.writeByte((byte) (inherited ? 0x01 : 0x00));
}
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<Number> CREATOR = new Parcelable.Creator<Number>() {
@Override
public Number createFromParcel(Parcel in) {
return new Number(in);
}
@Override
public Number[] newArray(int size) {
return new Number[size];
}
};
public Number setNumber(String number) {
this.number = number;
return this;
}
}
公共类编号实现可包裹、可序列化{
@序列化名称(“编号”)
@暴露
公共字符串号;
@序列化名称(“类型”)
@暴露
公共字符串类型=”;
@SerializedName(“继承的”)
@暴露
公共布尔值=false;
公共编号(字符串编号){
这个数字=数字;
}
受保护编号(包裹中){
number=in.readString();
type=in.readString();
byte inheritedVal=in.readByte();
inherited=inheritedVal==0x02?null:inheritedVal!=0x00;
}
@凌驾
公共int描述内容(){
返回0;
}
@凌驾
公共无效写入包裹(包裹目的地,内部标志){
目的地记录(编号);
目的写入限制(类型);
if(继承==null){
目标写入字节((字节)(0x02));
}否则{
dest.writeByte((字节)(继承的?0x01:0x00));
}
}
@抑制警告(“未使用”)
public static final Parcelable.Creator=新建Parcelable.Creator(){
@凌驾
公共编号createFromParcel(地块中){
返回新号码(在中);
}
@凌驾
公共编号[]新数组(整数大小){
返回新编号[大小];
}
};
公共编号setNumber(字符串编号){
这个数字=数字;
归还这个;
}
}
首先要注意的是,对联系人选择器的调用如下:
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
content://com.android.contacts/contacts/lookup/3163r328-4D2941473F314D2941473F3131/328
content://com.android.contacts/data/2849
将返回如下所示的Uri:
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
content://com.android.contacts/contacts/lookup/3163r328-4D2941473F314D2941473F3131/328
content://com.android.contacts/data/2849
第二条至最后一条路径(3163r…)i