gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 00:49:47 25 4
gpt4 key购买 nike

情况:我已按照 this question 中的说明向 Android 中的联系人添加自定义操作和 related sample app on GitHub .按下时,我想在我的应用程序中调用该联系人。我能够在按下自定义操作时打开的 Activity 中成功检索联系人。

我执行这个:

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,这不是联系人的 native ID。联系人的 native ID 是 459。我能够成功检索执行此查询的联系人,返回以下数据:

cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID); 

-返回“2849”

cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)) ; 

-返回正确的“sample sample”

虽然这是真的:

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;

请注意,我不请求 Intent ,我通过添加到 native 联系人的自定义操作接收它,就像 Viber 和 WhatsApp 那样:

custom action android contact

完整代码 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));
}

数字 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;
}
}

最佳答案

首先要注意的是像这样调用联系人选择器:

Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);

将返回这样的 Uri:

content://com.android.contacts/contacts/lookup/3163r328-4D2941473F314D2941473F3131/328

倒数第二个路径 (3163r....) 是查找键,而 328 是 NAME_RAW_ID .

将此与您从 sample application 获得的 Intent 进行比较.这包含一个如下所示的 Uri:

content://com.android.contacts/data/2849

如您所说,使用此 Uri 调用内容解析器不足以检索电话号码,尽管它可用于检索联系人的姓名和 ID。因此,我们将使用不完整的 Intent Uri 来构建一个新的 Lookup Uri,我们可以用它来获取电话号码。

让我们将以下方法添加到您的 LocalContactAsync(我不会重构您到目前为止所做的任何事情,我只会添加您使用过的样式):

public static Uri getLookupUri(Cursor cur) {
return getContentUri(getLookupKey(cur), getNameRawId(cur));
}

private static String getLookupKey(Cursor cur) {
return cur.getString(
cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
}

private static String getNameRawId(Cursor cur) {
return cur.getString(cur.getColumnIndex(ContactsContract.Contacts.NAME_RAW_CONTACT_ID));
}

private static Uri getContentUri(String lookupKey, String nameRawId) {
return new Uri.Builder()
.scheme("content")
.authority("com.android.contacts")
.appendPath("contacts")
.appendPath("lookup")
.appendPath(lookupKey)
.appendPath(nameRawId)
.build();
}

让我们修改 ViewingActivity在示例应用程序中,以便它实际检索联系人详细信息。我们现在可以在 onResume() 中使用以下代码来做到这一点:

@Override
protected void onResume() {
super.onResume();
Uri uri = getIntent().getData();
Cursor intentCursor = this.getContentResolver().query(uri, null, null, null, null);
Contact contact = null;
if (intentCursor != null) {
intentCursor.moveToFirst();
Uri lookupUri = LocalContactAsync.getLookupUri(intentCursor);
Cursor lookupCursor = this.getContentResolver().query(lookupUri, null, null, null, null);
contact = LocalContactAsync.getContacts(lookupCursor, this.getContentResolver()).get(0);
intentCursor.close();
lookupCursor.close();
}
}

联系人现在将包含所需的电话号码。

关于android - 如何通过单击 Android native 联系人应用程序中的自定义字段来获取联系人的电话号码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41244655/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com