5

如何在 FireMonkey 移动应用程序中获取手机的联系人列表?

4

3 回答 3

3

给你..它还没有完成,因为它读取了一个人的所有数字,如果有两个数字,你将在列表中列出这个人的两倍..但我认为你可以从这里开始工作并根据你的需要进行调整:) )

function GetContact: TStringList;
var
cursorContacts, cursorContactsPhone: JCursor;
hasPhoneNumber: Integer;
id: Int64;
displayName, phoneNumber, contactID: string;
begin
Result := TStringList.Create;
cursorContacts := SharedActivity.getContentResolver.query(TJContactsContract_Contacts.JavaClass.CONTENT_URI, nil, nil, nil, nil);
if (cursorContacts.getCount > 0) then
begin
while (cursorContacts.moveToNext) do
begin
id := cursorContacts.getLong(cursorContacts.getColumnIndex(StringToJString('_ID')));
displayName := JStringToString(cursorContacts.getString(cursorContacts.getColumnIndex(StringToJString('DISPLAY_NAME'))));
hasPhoneNumber := cursorContacts.getInt(cursorContacts.getColumnIndex(StringToJString('HAS_PHONE_NUMBER')));
if (hasPhoneNumber > 0) then
begin
cursorContactsPhone := SharedActivity.getContentResolver.query(TJCommonDataKinds_Phone.JavaClass.CONTENT_URI, nil,StringToJString('CONTACT_ID = ' + IntToStr(id)),nil, nil);
while (cursorContactsPhone.moveToNext) do
begin
phoneNumber := JStringToString(cursorContactsPhone.getString(cursorContactsPhone.getColumnIndex(StringToJString('DATA1'))));
contactID := JStringToString(cursorContactsPhone.getString(cursorContactsPhone.getColumnIndex(StringToJString('CONTACT_ID'))));
Result.Add(displayName + ': ' + phoneNumber);
end;
cursorContactsPhone.close;
end;
end;
end;
cursorContacts.close;
end;

最好的问候,克鲁诺

于 2013-12-31T17:00:13.330 回答
1

这是我的代码(受@mali kruno 启发并最初创建,我只是根据我的需要更改它!)基于 TEdit OnChange 事件搜索所有联系人:

我在我的 commonfunctions.pas 单元中使用这个函数:

function GetContact (Name: string; Number: string; const tip: integer) : TStringList;
var
cursorContactsPhone: JCursor;
Typo1, Typo2: string;
FindBy: JString;
ToFind: TJavaObjectArray<JString>;
CurRec: integer;
begin
Result:=TStringList.Create;
CurRec:=0;
ToFind:= TJavaObjectArray<JString>.Create(2);
if Name <> '' then
  begin
    ToFind.Items[0] := StringToJString('data1');
    ToFind.Items[1] := StringToJString('display_name');
    FindBy := StringToJString('display_name LIKE "%' + Name + '%"');
    Typo1:='data1';
    Typo2:='display_name';
  end
else if Number <> '' then
  begin
    ToFind.Items[0] := StringToJString('display_name');
    ToFind.Items[1] := StringToJString('data1');
    FindBy := StringToJString('data1 LIKE "%' + Number + '%"');
    Typo1:='display_name';
    Typo2:='data1';
  end;
cursorContactsPhone := SharedActivity.getContentResolver.query(TJCommonDataKinds_Phone.JavaClass.CONTENT_URI, ToFind, FindBy, nil, nil);
while (cursorContactsPhone.moveToNext) do
begin
Result.Add
(JStringToString(cursorContactsPhone.getString(cursorContactsPhone.getColumnIndex(StringToJString(Typo2)))) + ' - ' +
JStringToString(cursorContactsPhone.getString(cursorContactsPhone.getColumnIndex(StringToJString(Typo1)))));
CurRec:=CurRec+1;
end;
cursorContactsPhone.close;
end;

我从 ContactSearch.Change 事件(它是 TEdit 组件)中调用它,如下所示:

procedure TMainF.ContactsSearch.Change(Sender: TObject);
var ResultNo: integer; SearchContacts: string; Results: TStringList;
begin                   // begin main procedure
if ContactsSearch.Text.Length > 1 then
begin                 //begin search and memo update
SearchContacts:=ContactsSearch.Text;
Results:=GetContact(SearchContacts, '', 0);
ResultNo:=0;
Memo1.Lines.Clear;
for ResultNo := 0 to Results.Count-1
do
begin
Memo1.Lines.Add(Results.Strings[ResultNo]);
end;

Results.Free;
end;
end;

请注意,Result在函数中创建并在备忘录更新后在过程中释放的TStringList 。 另请注意,我只搜索 TEdit长度是否为 2 或更多,因为否则在 tedit 中仅输入“a”会显示所有名称中包含字母“a”的联系人,因此每次搜索、使用退格等时它都会冻结一点……解决方法是加载应用程序启动时 TStringList 中的电话簿,然后仅搜索字符串列表,但这会带来一些其他麻烦:a)不会检测到电话簿更新,或者您必须实现“更新”按钮,这会使根本没有意义做解决方法.. b) 应用程序启动需要更长的时间 c) 没有尝试过,并且不确定它实际上会加速搜索多少,因为 Memo.Lines.Add 比查询自己,所以...

至于重复项,您可以看到这里没有处理,因为目前我不需要这样做,但是您可以使用备忘录中的“排序”轻松处理,或者,如果您不这样做更好想要丢失否则会显示为重复的条目,在 TStringList 本身内部管理它们,以便您在同一行中合并数字,或为每个名称创建子字符串列表(当然,只有当一个名称出现多次时,如果您不想最终获得两倍于实际需要的字符串列表)。

希望这可以帮助。

于 2014-02-20T16:06:09.190 回答
0

考虑到 Delphi 没有为这个问题提供统一/包装的解决方案,您可以像使用本机编程 API 的程序员那样做。

您需要研究 Android SDK 如何显示联系人列表以及 iOS SDK 如何显示其联系人列表,然后使用本机 API 来访问它。

这两个平台之间会有很大的不同,但是一旦您在两个不同的操作系统上建立了实现并查看了提供的内容以及可以跨两个实现访问的内容,就可以为其编写一些独立于操作系统的接口。这就是 FMX 在两个平台上实现的类似功能的其他实例中所做的。

如果所需的 API 尚未导入到 Delphi 的 RTL 中,这很有可能,那么您还需要为您需要的那些 API 编写导入,以便能够首先调用它们。

执行摘要:

  1. 卷起你的袖子
  2. 陷在
  3. 自己编码
  4. 享受一些很酷的 API 工作的乐趣
于 2013-11-13T10:58:03.680 回答