简体   繁体   中英

How can I get a phone's contact list in a Firemonkey mobile application?

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

here you go .. It's not finished as it reads all numbers for one person and if there are two numbers you will have two times this person listed inside list .. but from here I think you can work and adjust it to your needs :))

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;

Best Regards, Kruno

Here's my code (inspired and originally created by @mali kruno, I only changed it to my needs!) to search through all contacts based on TEdit OnChange event:

I use this function in my commonfunctions.pas unit:

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;

I call it from ContactSearch.Change event (it's TEdit component) like this:

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;

Note, that the Result is a TStringList created in a function and freed in a procedure after Memo update. Note also, that I only search if TEdit length is 2 or more , since otherwise entering just "a" in a tedit would show all contacts that have a letter "a" in their name, and therefore it would freeze a little every time you search, use backspace etc... The workaround would be to load the phonebook in a TStringList on application start, and then search through the stringlist only, but that would make few other troubles: a) phonebook update wouldn't be detected, or you'd have to implement "Update" button, which would make no sense to do the workaround at all.. b) app start would take longer c) haven't tried that and not sure how much would it actually speed-up the search, since the Memo.Lines.Add takes more time than the query itself, so...

As for the duplicates, you can see that here are not handled, because currently I don't have a need to do so, but you can easily handle this using "sort" in a Memo, or, even better if you don't want to lose the entries that would otherwise appear as a duplicate, manage them inside a TStringList itself, so that you merge numbers in the same line, or create sub-stringlists for each name (of course, only if a name appears more than once, if you don't want to end up having twice as much stringlists as you'd actually need).

Hope this helps.

You do it in much the same way as a programmer would who uses the native programming APIs, given that Delphi does not provide a unified/wrapped solution to this problem.

You need to research how the Android SDK surfaces the contact list and how the iOS SDK surfaces its contact list, then make use of the native APIs to access it.

It will differ wildly between the 2 platforms, but it would be feaible to write some OS-independent interface to it once you've established the implementation on the 2 different OSs and seen what is on offer and what is accessible across the two implementations. This is what FMX does in other instances of similar features implemented on the two platforms.

If the required APIs haven't already been imported into Delphi's RTL, which is quite possible, then you'd also need to write the imports for those APIs you need in order to be able to call them in the first place.

Executive summary:

  1. Roll up your sleeves
  2. Get stuck in
  3. Code it up yourself
  4. Bask in the pleasure of having got some cool API stuff working

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM