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

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

1
你是否已经厌倦了阅读有关此主题的AndroidiOS文档? - RRUZ
我不是用Java或Object C来编写代码,我正在使用Rad Studio XE5。 - Christos K.
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;

最好的问候, Kruno


1
你需要在uses中使用Androidapi.Jni.Provider,并且还要加入以下内容:Androidapi.JNIBridge、Androidapi.Jni.GraphicsContentViewText、Androidapi.Jni.Net、Androidapi.Jni.JavaTypes、FMX.Helpers.Android... - mali kruno
我已经把它搞定了。:) 无论如何还是谢谢你!! 我进行了排序,所以没有重复项,我还通过使用“LIKE”属性通过名称查询来实现了tEdit.OnChange事件的自动搜索,尽管如果我只用一个字母,它会非常慢,所以现在我至少使用两个字符,并且它完美无缺地工作 :) - That Marc
当然可以。一旦我到达家里的电脑并获取源文件,我会发布另一个答案。 - That Marc
由于我在这里还是新手,所以无法对您的回答进行评论,所以我们开始吧。 谢谢Marc ;) - mali kruno
没问题。谢谢你提供原始代码。 :) 我只希望你也能以某种方式提供MMS部分... :3 ;) - That Marc
显示剩余4条评论

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,并在更新Memo后在一个过程中释放。 还要注意,我只搜索长度为2或更多的TEdit,否则在TEdit中仅输入"a"将显示所有姓名中有字母"a"的联系人,因此每次搜索、使用退格键等都会稍微卡顿... 解决方法是在应用程序启动时将电话簿加载到TStringList中,然后仅通过字符串列表进行搜索,但这会带来一些其他问题: a)无法检测到电话簿更新,或者您必须实现“更新”按钮,这样做根本没有意义... b)应用程序启动时间会更长 c)尚未尝试过,并不确定它实际上会加速搜索多少,因为Memo.Lines.Add所需的时间比查询本身更长,所以...
关于重复项,您可以看到这里没有处理,因为目前我没有这样做的需要,但是您可以轻松地使用Memo中的“sort”来处理它们,或者更好的方法是,如果您不想失去将出现为重复项的条目,请在TStringList本身内部管理它们,以便合并同一行中的数字,或为每个名称创建子字符串列表(当然,仅当名称出现多次时,如果您不想最终拥有两倍于实际所需的字符串列表)。

希望这能帮到您。


这个例子不会百分之百地工作,因为项目"data1"用于在显示屏上显示电话号码(在某些设备型号上用于显示号码,例如空格或破折号)。最好使用项目"data4",因为它使用原始数据。 - pudnivec74

0

您可以像使用本地编程API的程序员一样完成此操作,因为Delphi没有提供统一/封装的解决方案。

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

这两个平台之间的差异将非常大,但是一旦您在两个不同的操作系统上确定了实现并了解了两个实现中提供的内容和可访问性,就可以编写一些与操作系统无关的接口。 FMX在其他实现类似功能的情况下也是这样处理两个平台。

如果所需的API尚未导入到Delphi的RTL中,则需要编写那些需要的API的导入,以便首先能够调用它们。

执行摘要:

  1. 卷起袖子
  2. 开始进入
  3. 自己编码
  4. 享受得到一些酷API工作的乐趣

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接