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

时间:2013-11-08 18:17:27

标签: android ios delphi firemonkey delphi-xe5

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

3 个答案:

答案 0 :(得分: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;

最诚挚的问候, Kruno

答案 1 :(得分: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;

请注意,结果是在函数中创建的 TStringList 备忘录更新后,在程序中释放 。 另请注意,我只搜索TEdit 长度为2或更多 ,因为否则只输入&#34; a&#34;在一个tedit中会显示所有带有字母&#34; a&#34;在他们的名字中,因此每次搜索时都会冻结一点,使用退格等... 解决方法是在应用程序启动时将电话簿加载到TStringList中,然后仅搜索字符串列表,但这会带来很少的其他麻烦: a)无法检测到电话簿更新,或者您必须实施&#34;更新&#34;按钮,完全没有办法解决这个问题。 b)应用启动需要更长时间 c)没有尝试过,也不确定实际加速搜索的速度有多大,因为Memo.Lines.Add比查询本身花费的时间更多,所以......

至于副本,你可以看到这里没有处理,因为目前我没有必要这样做,但你可以使用&#34; sort&#34;轻松处理这个问题。在备忘录中,或者,如果您不想丢失原本显示为重复的条目,请更好地在TStringList本身内管理它们,以便您在同一行中合并数字,或创建子字符串列表对于每个名称(当然,只有当一个名称出现不止一次时,如果你不希望最终得到的字符串列表是你实际需要的两倍)。

希望这有帮助。

答案 2 :(得分:0)

你这样做的方式与使用本机编程API的程序员大致相同,因为Delphi没有为这个问题提供统一/包装的解决方案。

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

两个平台之间的差别很大,但是一旦你在2个不同的操作系统上建立了实现,并且看到提供的内容和可访问的内容,就可以编写一些独立于操作系统的界面。跨越两个实现。这就是FMX在两个平台上实现的类似功能的其他实例中的作用。

如果所需的API尚未导入Delphi的RTL,这很有可能,那么您还需要为所需的API编写导入才能使用首先打电话给他们。

执行摘要:

  1. 卷起袖子
  2. 陷入困境
  3. 自己编码
  4. 享受一些很酷的API工作的乐趣