Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/186.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我如何通过在Android的native Contacts应用程序中单击自定义字段来获取联系人的电话号码?_Android_Native_Contacts_Android Contact Mimetype - Fatal编程技术网

我如何通过在Android的native Contacts应用程序中单击自定义字段来获取联系人的电话号码?

我如何通过在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.

情况: 我已经按照和中的说明向Android中的联系人添加了自定义操作。按下时,我想在我的应用程序中拨打该联系人。我能够在按下自定义操作时打开的活动中成功检索联系人

我执行以下命令:

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