ENERGY Опубликовано 23 декабря, 2016 Поделиться Опубликовано 23 декабря, 2016 Никак не могу сделать поиск контакта по номеру. Есть пример на Java, я все пытаюсь научиться переводить с java на Delphi, но не всегда получается. Вот пример (там же есть полный пример.): Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber)); resolver.query(uri, new String[]{PhoneLookup.DISPLAY_NAME,... В нем используется Uri.withAppendedPath (это Jnet_UriClass из Androidapi.JNI.Net) Я нигде не нашел пример работы с ним. Попытался сделать сам : vUriClass: Jnet_UriClass; vfilter : TJavaObjectArray<JString>; wUri := vUriClass.withAppendedPath( TJContactsContract_PhoneLookup.JavaClass.CONTENT_FILTER_URI, vUriClass.encode( StringToJString('+11111111') ) ); vfilter := TJavaObjectArray<JString>.Create(1); vfilter[0] := TJCommonDataKinds_StructuredName.JavaClass.DISPLAY_NAME; with SharedActivity.getContentResolver do wCursor :=query(wUri, vfilter, nil,nil, nil); // Query to get all contact sorted by displayname Но ничего не получилось, вылетает ошибка сегментации в withAppendedPath. Помогите пожалуйста, одна на вас надежда. Второй день пошел уже. Как этот ContactsContract.PhoneLookup provider использовать? Вот полный код на Java : public String getContactDisplayNameByNumber(String number) { Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); String name = "?"; ContentResolver contentResolver = getContentResolver(); Cursor contactLookup = contentResolver.query(uri, new String[] {BaseColumns._ID, ContactsContract.PhoneLookup.DISPLAY_NAME }, null, null, null); try { if (contactLookup != null && contactLookup.getCount() > 0) { contactLookup.moveToNext(); name = contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)); //String contactId = contactLookup.getString(contactLookup.getColumnIndex(BaseColumns._ID)); } } finally { if (contactLookup != null) { contactLookup.close(); } } return name; } Цитата Ссылка на комментарий
0 Администраторы Brovin Yaroslav Опубликовано 23 декабря, 2016 Администраторы Поделиться Опубликовано 23 декабря, 2016 Есть компонент TAddressBook, он не подходит? Andrey Efimov и Kitty 2 Цитата Ссылка на комментарий
0 ENERGY Опубликовано 24 декабря, 2016 Автор Поделиться Опубликовано 24 декабря, 2016 (изменено) Большое Вам спасибо Ярослав, за то что вносите большой вклад в развитие Mobile Delphi. Очень мало примеров и документации (причем на любом языке) по этому поводу, ваш сайт очень выручает. Я попробовал демку c:\Program Files (x86)\Embarcadero\Studio\18.0\Samples\Object Pascal\Multi-Device Samples\Device Sensors and Services\Address Book\Contacts\Contacts_Delphi.dproj с TAddressBook . Delphi 10 upd 1 Запускал на телефоне HTC - ни один контакт не загрузился - просто пустой список. UPD: Вместо AddressBook1.AllContacts(Source, Contacts); Нужно AddressBook1.AllContacts(nil, Contacts); тогда загружает все контакты. Вся проблема в том, что он считывает сразу все контакты. А мне это не нужно. Лучше использовать код для поиска конкретного номера, прекрасно находит работает (также работает и вставка нового контакта, здесь описал http://stackoverflow.com/questions/29782398/insert-contacts-in-android-with-delphi/41294891#41294891): function TCore.IsNumberInAddressBook(const aNumber: string): boolean; var vCursor: JCursor; vQueryStr: string; begin Result := false; // will be: data1 LIKE '%+380501960000%' (with quotes) vQueryStr := JStringToString( TJCommonDataKinds_Phone.JavaClass.NORMALIZED_NUMBER) + ' LIKE ''%' + aNumber + '%'''; vCursor := TAndroidHelper.Activity.getContentResolver.query( TJCommonDataKinds_Phone.JavaClass.CONTENT_URI, nil, //projection String: A list of which columns to return. Passing null will return all columns, which is inefficient. StringToJString(vQueryStr), // String: A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given URI. nil, nil); // Query help: https://developer.android.com/reference/android/content/ContentResolver.html#query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String) if vCursor <> nil then try Result := vCursor.getCount > 0; finally vCursor.close; end; end; // а это может пригодится while (cursor.moveToNext) do begin lbContactsList.Text := JStringToString(cursor.getString( cursor.getColumnIndex(StringToJString('DISPLAY_NAME')))); lbContactsList.Tag := cursor.getInt(cursor.getColumnIndex(StringToJString('_ID'))); // ListBox1.AddObject(ListBoxItem); end; Цитата У меня вопрос к Вам. Вы не в курсе где находится исходный код процедуры procedure AllContacts(const ASource: TAddressBookSource; var AContacts: TAddressBookContacts); (unit FMX.AddressBook)? UPD: AllContacts находится в \source\fmx\FMX.AddressBook.Android.pas А вообще для самообразования хотелось бы узнать как вызвать ContactsContract.PhoneLookup.CONTENT_FILTER_URI И что это за конструкция такая Uri.withAppendedPath, ведь в будущем наверняка с ней придется сталкиваться. Если вы в курсе, расскажите пожалуйста. Изменено 27 декабря, 2016 пользователем ENRGY Ingalime 1 Цитата Ссылка на комментарий
0 x11 Опубликовано 3 февраля, 2018 Поделиться Опубликовано 3 февраля, 2018 В 24.12.2016 в 01:35, Brovin Yaroslav сказал: Есть компонент TAddressBook, он не подходит? А как быть со службой? Если в USES есть FMX.AddressBook, то в службах это работать не будет. Цитата Ссылка на комментарий
0 x11 Опубликовано 6 февраля, 2018 Поделиться Опубликовано 6 февраля, 2018 Всё-таки есть у кого-нибудь рабочий пример поиска имени по номеру телефона? Буду премного благодарен. Цитата Ссылка на комментарий
0 x11 Опубликовано 7 февраля, 2018 Поделиться Опубликовано 7 февраля, 2018 Есть такой пример поиска имени контакта по номеру телефона. Он компилируется, работает, но номер телефона не находит. function TDMSrv.GetContactByPhoneNumber(const sTel: string): string; var wJDislpayName, wJFirstName, wJLastName, wJQueryStr: JString; wJQueryParams: TJavaObjectArray<JString>; wSubCursor: JCursor; wfilter: TJavaObjectArray<JString>; wDataUri: JNet_URI; begin if sTel.IsEmpty then begin log('GetContactByPhoneNumber. Phone number is empty!'); exit; end; wDataUri := TJContactsContract_Data.JavaClass.CONTENT_URI; wfilter := TJavaObjectArray<JString>.Create(3); wfilter[0] := TJCommonDataKinds_StructuredName.JavaClass.DISPLAY_NAME; wfilter[1] := TJCommonDataKinds_StructuredName.JavaClass.FAMILY_NAME; wfilter[2] := TJCommonDataKinds_StructuredName.JavaClass.GIVEN_NAME; wJQueryStr := StringToJString('mimetype = ? AND lookup = ?'); wJQueryParams := TJavaObjectArray<JString>.Create(2); wJQueryParams[0] := TJCommonDataKinds_Phone.JavaClass.NUMBER; wJQueryParams[1] := StringToJString(sTel); wSubCursor := TAndroidHelper.Context.getContentResolver.Query(wDataUri, wfilter, wJQueryStr, wJQueryParams, nil); try if wSubCursor.getCount > 0 then begin // Getting only first row, as we retrieving only names, a contact can have only one first name, one familyname, // for phone number for example, we need to loop on each row (while (wSubCursor.moveToNext) do) because a contact can have many phone number log('wSubCursor.getCount = ' + wSubCursor.getCount.ToString); wSubCursor.moveToNext; wJDislpayName := wSubCursor.getString(0); wJLastName := wSubCursor.getString(1); wJFirstName := wSubCursor.getString(2); end else log('wSubCursor.getCount = 0'); Result := JStringToString(wJDislpayName); finally wSubCursor.close; FreeAndNil(wSubCursor);// := nil; end; end; Цитата Ссылка на комментарий
0 Администраторы Brovin Yaroslav Опубликовано 7 февраля, 2018 Администраторы Поделиться Опубликовано 7 февраля, 2018 21 час назад, x11 сказал: Всё-таки есть у кого-нибудь рабочий пример поиска имени по номеру телефона? Буду премного благодарен. Возьмите сорцы FMX.AddressBook.Android и заиспользуйте тот код. Единственная причина по которой адресная книга тянет за собой всю платформу в сервисах - это работа с TBitmapSurface. В теории, если уберете всю работу с BitmapSurface (он нужен только для загрузки фоток), то уберете зависимость от платформы. и в этом случае можно использовать эту реализацию напрямую в сервисах. Цитата Ссылка на комментарий
0 x11 Опубликовано 7 февраля, 2018 Поделиться Опубликовано 7 февраля, 2018 (изменено) Спасибо, конечно... но... 51 минуту назад, Brovin Yaroslav сказал: В теории, если уберете всю работу с BitmapSurface (он нужен только для загрузки фоток), то уберете зависимость от платформы. и в этом случае можно использовать эту реализацию напрямую в сервисах. На сколько я знаю, то FMX.AddressBook тянет за собой всю адресную книгу себе... зачем? Ну и я не настолько в этом разбираюсь, чтобы правильно что-то "убрать". Изменено 7 февраля, 2018 пользователем x11 Цитата Ссылка на комментарий
0 x11 Опубликовано 7 февраля, 2018 Поделиться Опубликовано 7 февраля, 2018 (изменено) Взял файл, удалил из uses все упоминания, начинающиеся с FMX, "прикрепил" к проекту, при попытке скомпилировать - 70+ ошибок. Изменено 7 февраля, 2018 пользователем x11 Цитата Ссылка на комментарий
0 mazayhin Опубликовано 8 февраля, 2018 Поделиться Опубликовано 8 февраля, 2018 18 часов назад, x11 сказал: Взял файл, удалил из uses все упоминания, начинающиеся с FMX, "прикрепил" к проекту, при попытке скомпилировать - 70+ ошибок. Ну и правильно, удалить то удалили, а зависимости не разрешили. Из исходника в свой юнит или куда еще, надо перенести именно те методы, дергающие api, которые нужны для решения задачи. Завтра конкретнее посмотрю Цитата Ссылка на комментарий
0 x11 Опубликовано 8 февраля, 2018 Поделиться Опубликовано 8 февраля, 2018 Для решения задачи, по идее, мне нужна только одна маленькая процедура. Т.е. получается за многолетнюю историю FMX я сейчас пока что единственный, кому понадобилось выполнить поиск контакта по номеру в сервисе? Ну или другой поиск в адресной книге Андроида. Цитата Ссылка на комментарий
0 Модераторы Равиль Зарипов (ZuBy) Опубликовано 8 февраля, 2018 Модераторы Поделиться Опубликовано 8 февраля, 2018 смотрите код на джава, примеров уйма на стаке. сравните что в вашем коде выше не так, вот ссылочка для примера Цитата Ссылка на комментарий
0 x11 Опубликовано 8 февраля, 2018 Поделиться Опубликовано 8 февраля, 2018 В том-то и дело, что не получается. Вот пример (см там, где 79 оценок) https://stackoverflow.com/questions/3712112/search-contact-by-phone-number как его перевести в Delphi? Цитата Ссылка на комментарий
0 x11 Опубликовано 8 февраля, 2018 Поделиться Опубликовано 8 февраля, 2018 (изменено) Вот мне подсказали на sql.ru рабочий пример, который и у меня получилось использовать в службе. Я так понимаю, что приходится в этом случае получать полностью всю адресную книгу и потом перебирать её у себя в коде циклом, что не совсем правильно. Пример компилируется и работает на Delphi Tokyo: function GetContactByNumbers(const aPhoneNumbers: TList<String>): string; var wUri: JNet_URI; lookupID: String; wCursor, wSubCursor: JCursor; wLookup_Idx: Integer; wDisplayNameIdx: integer; wfilter, wJQueryParams: TJavaObjectArray<JString>; wDataUri: JNet_URI; begin wUri := TJContactsContract_Contacts.JavaClass.CONTENT_URI; wCursor := TAndroidHelper.Context.getContentResolver.query(wUri, nil, nil, nil, StringToJString('display_name ASC')); try wLookup_Idx := wCursor.getColumnIndex(StringToJString('lookup')); wDisplayNameIdx := wCursor.getColumnIndex(StringToJString('display_name')); while wCursor.moveToNext do begin lookupID := JStringToString(wCursor.getString(wLookup_Idx)); wfilter := TJavaObjectArray<JString>.Create(1); wfilter[0] := TJCommonDataKinds_Phone.JavaClass.NUMBER; // Qurey condition (Exrtact only data for specific ID) wJQueryParams := TJavaObjectArray<JString>.Create(2); wJQueryParams[0] := TJCommonDataKinds_Phone.JavaClass.CONTENT_ITEM_TYPE; wJQueryParams[1] := StringToJString(lookupID); wDataUri := TJContactsContract_Data.JavaClass.CONTENT_URI; // Contacts data uri wSubCursor := TAndroidHelper.Context.getContentResolver. Query(wDataUri,wfilter,StringToJString('mimetype = ? AND lookup = ?') , wJQueryParams,nil); // Exec query try if wSubCursor.getCount > 0 then begin while (wSubCursor.moveToNext) do begin if aPhoneNumbers.Contains(JStringToString(wSubCursor.getString(0))) then begin Result := JStringToString(wCursor.getString(wDisplayNameIdx)); Break; end; end; end; finally wSubCursor.close; wSubCursor := nil; end; end; finally wCursor.Close; wCursor := nil; end; end; К сожалению, в справке по Delphi нет описания TJContactsContract_Contacts, TJCommonDataKinds_Phone и TAndroidHelper.Context.getContentResolver.query. И примеров нет. И пример использования: // В USES нужно добавить System.Generics.Collections для TList. VAR ListNumbers: TList<string>; begin ListNumbers := TList<string>.Create; try ListNumbers.Add(sTel);// передаем полный номер: +380681234567 ListNumbers.Add(RightStr(sTel, 10));// если в адресной книге записан номер без кода оператора - 0681234567 ContactName := GetContactByNumbers(ListNumbers); finally FreeAndNil(ListNumbers); end; Изменено 8 февраля, 2018 пользователем x11 Цитата Ссылка на комментарий
0 x11 Опубликовано 8 февраля, 2018 Поделиться Опубликовано 8 февраля, 2018 И ещё не понятно, как работает код, когда у контакта в адресной книге есть 2 номера телефона. Я проверил - оба функция находит, но где это, в каком месте кода, я не понял. Цитата Ссылка на комментарий
0 x11 Опубликовано 12 февраля, 2018 Поделиться Опубликовано 12 февраля, 2018 В 23.12.2016 в 22:09, ENERGY сказал: Есть пример на Java, я все пытаюсь научиться переводить с java на Delphi, но не всегда получается. Вот пример (там же есть полный пример.): function TContactsManager.GetContactByNumber( const aPhoneNumber: string): string; var wUri: JNet_URI; wCursor: JCursor; wfilter, wJQueryParams: TJavaObjectArray<JString>; begin Result := ''; wUri := TJNet_URI.JavaClass.withAppendedPath ( TJContactsContract_PhoneLookup.JavaClass.CONTENT_FILTER_URI, StringToJString(aPhoneNumber) ); wfilter := TJavaObjectArray<JString>.Create(2); wfilter[0] := StringToJString('lookup'); wfilter[1] := StringToJString('display_name'); with SharedActivity.getContentResolver do wCursor := query(wUri, wfilter, nil, nil, nil); try if Assigned(wCursor) and (wCursor.getCount > 0) then begin wCursor.moveToNext; Result := JStringToString(wCursor.getString( wCursor.getColumnIndex(StringToJString('display_name')))); end; finally wCursor.Close; wCursor := nil; end; end; http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1183758&msg=21183983 #WAMACO и Ingalime 2 Цитата Ссылка на комментарий
Вопрос
ENERGY
Никак не могу сделать поиск контакта по номеру.
Есть пример на Java, я все пытаюсь научиться переводить с java на Delphi, но не всегда получается. Вот пример (там же есть полный пример.):
В нем используется
Uri.withAppendedPath (это Jnet_UriClass из Androidapi.JNI.Net) Я нигде не нашел пример работы с ним.
Попытался сделать сам :
vUriClass: Jnet_UriClass;
vfilter : TJavaObjectArray<JString>;
wUri := vUriClass.withAppendedPath( TJContactsContract_PhoneLookup.JavaClass.CONTENT_FILTER_URI,
vUriClass.encode( StringToJString('+11111111') ) );
vfilter := TJavaObjectArray<JString>.Create(1);
vfilter[0] := TJCommonDataKinds_StructuredName.JavaClass.DISPLAY_NAME;
with SharedActivity.getContentResolver do
wCursor :=query(wUri, vfilter, nil,nil, nil); // Query to get all contact sorted by displayname
Но ничего не получилось, вылетает ошибка сегментации в withAppendedPath.
Помогите пожалуйста, одна на вас надежда. Второй день пошел уже. Как этот ContactsContract.PhoneLookup provider использовать?
Вот полный код на Java :
Ссылка на комментарий
15 ответов на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.