【发布时间】:2013-11-08 18:17:27
【问题描述】:
如何在 FireMonkey 移动应用程序中获取手机的联系人列表?
【问题讨论】:
标签: android ios delphi firemonkey delphi-xe5
如何在 FireMonkey 移动应用程序中获取手机的联系人列表?
【问题讨论】:
标签: android ios delphi firemonkey delphi-xe5
给你 .. 它还没有完成,因为它读取了一个人的所有数字,如果有两个数字,你将在列表中列出这个人的两倍 .. 但是从这里我认为你可以工作并调整它以适应你的需要:))
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;
最好的问候, 克鲁诺
【讨论】:
这是我的代码(灵感来自 @mali kruno,最初由 @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 本身内部管理它们,以便您在同一行中合并数字,或为每个名称创建子字符串列表(当然,只有在出现名称时不止一次,如果您不想最终获得两倍于实际需要的字符串列表)。
希望这会有所帮助。
【讨论】:
考虑到 Delphi 没有为这个问题提供统一/封装的解决方案,您的操作方式与使用本机编程 API 的程序员大致相同。
您需要研究 Android SDK 如何显示联系人列表以及 iOS SDK 如何显示其联系人列表,然后使用原生 API 来访问它。
这两个平台之间会有很大的不同,但是一旦您在 2 个不同的操作系统上建立了实现并查看了提供的内容以及跨平台可访问的内容,编写一些独立于操作系统的接口是可行的两个实现。这就是 FMX 在两个平台上实现的类似功能的其他实例中所做的。
如果所需的 API 尚未导入 Delphi 的 RTL(这很有可能),那么您还需要为您需要的那些 API 编写导入,以便能够首先调用它们。
执行摘要:
【讨论】: