1/** 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import dataShare from '@ohos.data.dataShare'; 17import dataSharePredicates from '@ohos.data.dataSharePredicates'; 18import IContactRepository from './IContactRepository'; 19import Contact from '../entity/Contact'; 20import RawContact from '../entity/RawContact'; 21import ContactBuilder from '../entity/ContactBuilder'; 22import { DataItem } from '../entity/DataItem'; 23import ContactList from './ContactList'; 24import DAOperation from './DAOperation'; 25import ContactDelta from './ContactDelta'; 26import { RawContacts } from '../contract/RawContacts'; 27import { Contacts } from '../contract/Contacts'; 28import { Data } from '../contract/Data'; 29import { HiLog } from '../../../../../../common/src/main/ets/util/HiLog'; 30import ContactListItem from './ContactListItem'; 31import { DataItemType } from '../contract/DataType'; 32import Calls from '../../../../../call/src/main/ets/contract/Calls'; 33import { CallLog } from '../../../../../call/src/main/ets/entity/CallLog'; 34import CallLogBuilder from '../../../../../call/src/main/ets/entity/CallLogBuilder'; 35import { SearchContacts } from '../contract/SearchContacts'; 36import SearchContactListItem from './SearchContactListItem'; 37import ContactUsuallyListItem from './ContactUsuallyListItem'; 38 39const TAG = 'ContactRepository'; 40 41/** 42 * Contact storage management, shielding dependency on the CP layer 43 * Contacts Only 44 */ 45export class ContactRepository implements IContactRepository { 46 static readonly RAW_CONTACT_URL: string = RawContacts.CONTENT_URI; 47 private dataShareHelper; 48 private static instance: ContactRepository; 49 private context: Context 50 51 private constructor() { 52 } 53 54 /* 55 * init if Call From serviceAbility globalThis.context is Null 56 *@param ctx Context used for dataShare 57 */ 58 init(ctx: Context) { 59 this.context = ctx; 60 } 61 62 public static getInstance(): ContactRepository { 63 if (!ContactRepository.instance) { 64 ContactRepository.instance = new ContactRepository(); 65 } 66 return ContactRepository.instance; 67 } 68 69 saveTest() { 70 return false; 71 } 72 73 private async getDataAbilityHelper() { 74 if (this.dataShareHelper == undefined) { 75 this.dataShareHelper = await dataShare.createDataShareHelper(this.context ? this.context : globalThis.context, 76 Contacts.CONTENT_URI); 77 } 78 return this.dataShareHelper; 79 } 80 81 save(contact: ContactDelta, callback) { 82 this.getDataAbilityHelper().then((dataAbilityHelper) => { 83 let opts = contact.buildDiff(); 84 return dataAbilityHelper.executeBatch(ContactRepository.RAW_CONTACT_URL, opts) 85 .then(resultSet => { 86 callback(resultSet); 87 }) 88 .catch(error => { 89 HiLog.w(TAG, 'save error:%s' + JSON.stringify(error.message)); 90 callback(); 91 }); 92 }).catch(error => { 93 HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message)); 94 callback(); 95 }); 96 } 97 98 findById(id: number, callback) { 99 if (id < 0) { 100 HiLog.w(TAG, 'findById: id is invalid.'); 101 callback(); 102 return; 103 } 104 this.getDataAbilityHelper().then((dataAbilityHelper) => { 105 let conditionArgs = new dataSharePredicates.DataSharePredicates(); 106 conditionArgs.equalTo(RawContacts.CONTACT_ID, id).orderByAsc(Data.RAW_CONTACT_ID); 107 dataAbilityHelper.query(Data.CONTENT_URI, conditionArgs, null).then(resultSet => { 108 if (resultSet == undefined || !resultSet.goToFirstRow()) { 109 HiLog.w(TAG, 'findById not found.'); 110 callback(); 111 return; 112 } 113 let contactBuilder = ContactBuilder.fromResultSet(resultSet); 114 let currentRawContactId = -1; 115 let rawContact: RawContact = null; 116 do { 117 let rawContactId = resultSet.getLong(resultSet.getColumnIndex(Data.RAW_CONTACT_ID)); 118 if (rawContactId != currentRawContactId) { 119 currentRawContactId = rawContactId; 120 rawContact = RawContact.fromResultSet(resultSet); 121 contactBuilder.rowContacts.push(rawContact); 122 } 123 if (rawContact != undefined) { 124 rawContact.dataItems.push(DataItem.fromResultSet(resultSet)); 125 } 126 } while (resultSet.goToNextRow()); 127 resultSet.close(); 128 callback(contactBuilder.buildContact()); 129 }).catch(error => { 130 HiLog.e(TAG, 'findById error:%s' + JSON.stringify(error.message)); 131 callback(); 132 }); 133 }).catch(error => { 134 HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message)); 135 callback(); 136 }); 137 } 138 139 findAll(actionData, callback) { 140 let conditionArgs = new dataSharePredicates.DataSharePredicates(); 141 let offset = actionData.page < 3 ? (actionData.page - 1) * 50 : (actionData.page - 2) * 500 + 50; 142 conditionArgs.limit(actionData.limit, offset) 143 // conditionArgs.limitAs(actionData.limit); 144 // conditionArgs.offsetAs(offset); 145 conditionArgs.equalTo(RawContacts.IS_DELETED, '0').orderByAsc(RawContacts.SORT_FIRST_LETTER); 146 this.getDataAbilityHelper().then((dataAbilityHelper) => { 147 dataAbilityHelper.query(Contacts.CONTACT_URI, conditionArgs, ContactListItem.COLUMNS) 148 .then(resultSet => { 149 let rst: ContactListItem[] = []; 150 if (resultSet.rowCount === 0) { 151 resultSet.close(); 152 callback(rst); 153 } else { 154 resultSet.goToFirstRow(); 155 do { 156 rst.push(new ContactListItem(resultSet)); 157 } while (resultSet.goToNextRow()); 158 resultSet.close(); 159 callback(rst); 160 } 161 }) 162 .catch(error => { 163 HiLog.w(TAG, 'findAll error:%s' + JSON.stringify(error.message)); 164 callback([]); 165 }); 166 }).catch(error => { 167 HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message)); 168 callback([]); 169 }); 170 } 171 172 findByQuickSearchKey(searchKey: string, callback) { 173 this.getDataAbilityHelper().then((dataAbilityHelper) => { 174 let conditionArgs = new dataSharePredicates.DataSharePredicates(); 175 conditionArgs.equalTo(Contacts.QUICK_SEARCH_KEY, searchKey).orderByAsc(Data.RAW_CONTACT_ID); 176 dataAbilityHelper.query(Data.CONTENT_URI, conditionArgs, null).then(resultSet => { 177 if (resultSet == undefined || !resultSet.goToFirstRow()) { 178 HiLog.w(TAG, 'findByQuickSearchKey not found.'); 179 callback(); 180 return; 181 } 182 let contactBuilder = ContactBuilder.fromResultSet(resultSet); 183 let currentRawContactId = -1; 184 let rawContact: RawContact = null; 185 do { 186 let rawContactId = resultSet.getLong(resultSet.getColumnIndex(Data.RAW_CONTACT_ID)); 187 if (rawContactId != currentRawContactId) { 188 currentRawContactId = rawContactId; 189 rawContact = RawContact.fromResultSet(resultSet); 190 contactBuilder.rowContacts.push(rawContact); 191 } 192 if (rawContact != undefined) { 193 rawContact.dataItems.push(DataItem.fromResultSet(resultSet)); 194 } 195 } while (resultSet.goToNextRow()); 196 resultSet.close(); 197 callback(contactBuilder.buildContact()); 198 }).catch(error => { 199 HiLog.e(TAG, 'findByQuickSearchKey error:%s' + JSON.stringify(error.message)); 200 callback(); 201 }); 202 }).catch(error => { 203 HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message)); 204 callback(); 205 }); 206 } 207 208 findAllWithBookIndex() { 209 return new ContactList({}); 210 } 211 212 search(queryStr: string) { 213 return new ContactList({}); 214 } 215 216 findByPhoneIsNotNull(favorite: number, editContact: number, callback) { 217 HiLog.i(TAG, 'initContactsList resultList success favoriteForm favorite :' + favorite + '---' + editContact); 218 this.getAllContactNumbers(favorite, editContact, (contactNumberMap) => { 219 this.getDataAbilityHelper().then((dataAbilityHelper) => { 220 let conditionArgs = new dataSharePredicates.DataSharePredicates(); 221 if (-1 !== editContact || 0 === favorite) { 222 conditionArgs.equalTo(RawContacts.IS_DELETED, '0'); 223 if (0 === favorite) { 224 conditionArgs.and(); 225 conditionArgs.equalTo(RawContacts.FAVORITE, 0); 226 } 227 conditionArgs.orderByAsc(RawContacts.SORT_FIRST_LETTER); 228 } else { 229 conditionArgs.equalTo(RawContacts.IS_DELETED, '0') 230 .and() 231 .equalTo(Contacts.HAS_PHONE_NUMBER, '1') 232 .orderByAsc(RawContacts.SORT_FIRST_LETTER); 233 } 234 dataAbilityHelper.query(Contacts.CONTACT_URI, conditionArgs, ContactListItem.COLUMNS) 235 .then(resultSet => { 236 let rst: ContactListItem[] = []; 237 if (resultSet.rowCount === 0) { 238 resultSet.close(); 239 callback(rst); 240 } else { 241 resultSet.goToFirstRow(); 242 do { 243 let id = resultSet.getLong(resultSet.getColumnIndex(Contacts.ID)); 244 if (!contactNumberMap.has(id)) { 245 HiLog.w(TAG, 'findAll: contact id is invalid or contact has no phone number.'); 246 continue; 247 } 248 let contactListItem = new ContactListItem(resultSet); 249 contactListItem.phoneNumbers = contactNumberMap.get(id); 250 rst.push(contactListItem); 251 } while (resultSet.goToNextRow()); 252 resultSet.close(); 253 callback(rst); 254 } 255 }) 256 .catch(error => { 257 HiLog.w(TAG, 'findAll error:%s' + JSON.stringify(error.message)); 258 callback(); 259 }); 260 }).catch(error => { 261 HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message)); 262 callback(); 263 }); 264 }); 265 } 266 267 /** 268 * 查询所有联系人手机号 269 */ 270 private getAllContactNumbers(favorite: number, editContact: number, callback) { 271 this.getDataAbilityHelper().then((dataAbilityHelper) => { 272 let resultColumns = [RawContacts.CONTACT_ID, Data.DETAIL_INFO, Data.EXTEND7, Data.CUSTOM_DATA]; 273 let conditionArgs = new dataSharePredicates.DataSharePredicates(); 274 if (-1 !== editContact || 0 === favorite) { 275 conditionArgs.orderByAsc(RawContacts.CONTACT_ID); 276 } else { 277 conditionArgs.equalTo(Data.TYPE_ID, DataItemType.PHONE).orderByAsc(RawContacts.CONTACT_ID); 278 } 279 dataAbilityHelper.query(Data.CONTENT_URI, conditionArgs, resultColumns).then(resultSet => { 280 // 用于存储联系人及其电话号码的对应关系 281 let contactNumberMap = new Map(); 282 if (resultSet == undefined || !resultSet.goToFirstRow()) { 283 HiLog.w(TAG, 'getAllContactNumbers not found.'); 284 callback(contactNumberMap); 285 return; 286 } 287 let oldContact = resultSet.getLong(resultSet.getColumnIndex(RawContacts.CONTACT_ID)); 288 let oldPhoneNumber = ''; 289 let numberList = []; 290 do { 291 let newContact = resultSet.getLong(resultSet.getColumnIndex(RawContacts.CONTACT_ID)); 292 let phoneNumberObj = { 293 'phoneNumber': resultSet.getString(resultSet.getColumnIndex(Data.DETAIL_INFO)), 294 'labelId': resultSet.getString(resultSet.getColumnIndex(Data.EXTEND7)), 295 'numType': resultSet.getString(resultSet.getColumnIndex(Data.CUSTOM_DATA)) 296 }; 297 // 如果是同一联系人则把手机号放到同一个list中 298 if (oldContact === newContact) { 299 if (oldPhoneNumber != phoneNumberObj.phoneNumber) { 300 numberList.push(phoneNumberObj); 301 } 302 } else { 303 // 联系人变化时,存储联系人与手机号码列表的对应关系 304 contactNumberMap.set(oldContact, numberList); 305 oldContact = newContact; 306 // 将最新的号码数据存储到新的numberList 307 numberList = [phoneNumberObj]; 308 } 309 oldPhoneNumber = phoneNumberObj.phoneNumber; 310 } while (resultSet.goToNextRow()); 311 contactNumberMap.set(oldContact, numberList); 312 resultSet.close(); 313 callback(contactNumberMap); 314 }); 315 }).catch(error => { 316 HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message)); 317 callback(new Map()); 318 }); 319 } 320 321 findByMailIsNotNull() { 322 return new ContactList({}); 323 } 324 325 deleteById(id: number, callback) { 326 if (id < 0) { 327 callback(); 328 return; 329 } 330 this.getDataAbilityHelper().then((dataAbilityHelper) => { 331 let condition = new dataSharePredicates.DataSharePredicates(); 332 condition.equalTo(Contacts.ID, id); 333 dataAbilityHelper.delete(Contacts.CONTACT_URI, condition).then(data => { 334 callback(data); 335 }).catch(error => { 336 HiLog.w(TAG, 'deleteById error:%s' + JSON.stringify(error.message)); 337 callback(); 338 }); 339 }).catch(error => { 340 HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message)); 341 callback(); 342 }); 343 } 344 345 deleteByIdIn(ids: number[]) { 346 return false; 347 } 348 349 notifyChange() { 350 this.getDataAbilityHelper().then((dataAbilityHelper) => { 351 if (dataAbilityHelper) { 352 dataAbilityHelper.notifyChange(Data.CONTENT_URI).then(() => { 353 HiLog.i(TAG, 'notifyChange success') 354 }).catch(error => { 355 HiLog.w(TAG, 'notifyChange error:%s' + JSON.stringify(error.message)); 356 }); 357 } 358 }).catch(error => { 359 HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message)); 360 }); 361 } 362 363 observers: Array<() => void> = []; 364 contactsUrl: Array<string> = [Contacts.CONTACT_URI, Data.CONTENT_URI]; 365 callback = () => { 366 HiLog.d(TAG, 'Contacts changed: Notifying observers...'); 367 for (const observer of this.observers) { 368 observer(); 369 } 370 } 371 372 registerContactsDataChange() { 373 this.contactsUrl.forEach((url, index, array) => { 374 this.getDataAbilityHelper().then((dataAbilityHelper) => { 375 if (dataAbilityHelper) { 376 dataAbilityHelper.on('dataChange', url, this.callback); 377 HiLog.i(TAG, 'registerContactsDataChange success:' + index) 378 } 379 }).catch(error => { 380 HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message)); 381 }); 382 }) 383 } 384 385 unregisterContactsDataChange() { 386 this.contactsUrl.forEach((url, index, array) => { 387 this.getDataAbilityHelper().then((dataAbilityHelper) => { 388 if (dataAbilityHelper) { 389 HiLog.i(TAG, 'start unregisterContactsDataChange:' + index) 390 dataAbilityHelper.off('dataChange', url, this.callback); 391 HiLog.i(TAG, 'unregisterContactsDataChange success:' + index) 392 } 393 }).catch(error => { 394 HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message)); 395 }); 396 }) 397 } 398 399 registerDataChangeObserver(observer: () => void) { 400 if (!observer) { 401 HiLog.i(TAG, `registerDataChangeObserver: observer is null.`); 402 return; 403 } 404 if (this.observers.length == 0) { 405 this.registerContactsDataChange() 406 } 407 const isExist = this.observers.includes(observer); 408 if (isExist) { 409 return HiLog.i(TAG, 'registerDataChangeObserver: Observer has been attached already.'); 410 } 411 HiLog.i(TAG, 'registerDataChangeObserver: Attached an observer.'); 412 this.observers.push(observer); 413 } 414 415 unRegisterDataChangeObserver(observer: () => void) { 416 const observerIndex = this.observers.indexOf(observer); 417 if (observerIndex === -1) { 418 HiLog.i(TAG, 'unRegisterDataChangeObserver: Nonexistent observer.'); 419 return 420 } 421 this.observers.splice(observerIndex, 1); 422 HiLog.i(TAG, 'unRegisterDataChangeObserver: Detached an observer.'); 423 if (this.observers.length == 0) { 424 this.unregisterContactsDataChange(); 425 } 426 } 427 428 queryContactDataByNumber(numberList, callback) { 429 this.getDataAbilityHelper().then((dataAbilityHelper) => { 430 if (!dataAbilityHelper) { 431 HiLog.e(TAG, 'queryContactDataByNumber, dataAbilityHelper is null'); 432 callback([]); 433 return; 434 } 435 let resultColumns = [ 436 'detail_info', 437 'display_name', 438 ]; 439 let condition = new dataSharePredicates.DataSharePredicates(); 440 condition.in('detail_info', numberList); 441 condition.and(); 442 condition.equalTo('type_id', '5'); 443 condition.and(); 444 condition.equalTo('is_deleted', '0'); 445 dataAbilityHelper.query(Data.CONTENT_URI, condition, resultColumns).then(resultSet => { 446 callback(this.dealContactResultSet(resultSet)); 447 }).catch(error => { 448 HiLog.e(TAG, 'queryContactDataByNumber query, error: ' + JSON.stringify(error.message)); 449 }) 450 }).catch(error => { 451 HiLog.e(TAG, 'queryContactDataByNumber, error: ' + JSON.stringify(error.message)); 452 callback([]); 453 }); 454 } 455 456 dealContactResultSet(resultSet) { 457 let contacts = []; 458 while (resultSet?.goToNextRow()) { 459 let contact: { [key: string]: any } = {}; 460 contact.detailInfo = resultSet.getString(0); 461 contact.displayName = resultSet.getString(1); 462 contacts.push(contact); 463 } 464 return contacts; 465 } 466 467 findAllFavorite(actionData, callback) { 468 HiLog.i(TAG, 'refreshUsually findAllFavorite start.'); 469 let conditionArgs = new dataSharePredicates.DataSharePredicates(); 470 conditionArgs.equalTo(RawContacts.IS_DELETED, '0'); 471 conditionArgs.and(); 472 conditionArgs.equalTo(RawContacts.FAVORITE, 1); 473 conditionArgs.and(); 474 conditionArgs.orderByAsc(RawContacts.FAVORITE_ORDER); 475 this.getDataAbilityHelper().then((dataAbilityHelper) => { 476 dataAbilityHelper.query(Contacts.CONTACT_URI, conditionArgs, ContactListItem.COLUMNS) 477 .then(resultSet => { 478 let rst: ContactListItem[] = []; 479 if (resultSet.rowCount === 0) { 480 resultSet.close(); 481 callback(rst); 482 } else { 483 resultSet.goToFirstRow(); 484 do { 485 rst.push(new ContactListItem(resultSet)); 486 } while (resultSet.goToNextRow()); 487 resultSet.close(); 488 HiLog.i(TAG, 'findAllFavorite query data success.'); 489 callback(rst); 490 } 491 }) 492 .catch(error => { 493 HiLog.e(TAG, 'findAllFavorite error:%s' + JSON.stringify(error.message)); 494 callback([]); 495 }); 496 }).catch(error => { 497 HiLog.e(TAG, 'findAllFavorite error:%s' + JSON.stringify(error.message)); 498 callback([]); 499 }); 500 } 501 502 findAllUsually(actionData, callback) { 503 HiLog.i(TAG, 'refreshUsually findAllUsually start.'); 504 let conditionArgs = new dataSharePredicates.DataSharePredicates(); 505 conditionArgs.groupBy([Calls.DISPLAY_NAME, Calls.PHONE_NUMBER]).distinct(); 506 conditionArgs.and(); 507 conditionArgs.orderByDesc(Calls.TALK_DURATION); 508 conditionArgs.and(); 509 conditionArgs.orderByDesc(Calls.CREATE_TIME); 510 this.getDataAbilityHelper().then((dataAbilityHelper) => { 511 dataAbilityHelper.query(Calls.CALL_LOG_URI, conditionArgs, null) 512 .then(resultSet => { 513 let rst: CallLog[] = []; 514 if (resultSet.rowCount === 0) { 515 resultSet.close(); 516 callback(rst); 517 } else { 518 resultSet.goToFirstRow(); 519 do { 520 let builder = CallLogBuilder.fromResultSet(resultSet); 521 if (builder.id > 0) { 522 rst.push(new CallLog(builder)); 523 } 524 } while (resultSet.goToNextRow()); 525 resultSet.close(); 526 HiLog.i(TAG, 'findAllUsually query data success.'); 527 callback(rst); 528 } 529 }) 530 .catch(error => { 531 HiLog.e(TAG, 'findAllUsually error:%s' + JSON.stringify(error.message)); 532 callback([]); 533 }); 534 }).catch(error => { 535 HiLog.e(TAG, 'findAllUsually error:%s' + JSON.stringify(error.message)); 536 callback([]); 537 }); 538 } 539 540 getDisplayNameByFavorite(displayName, usuallyPhone, callback) { 541 HiLog.i(TAG, 'getDisplayNameByFavorite start.'); 542 let conditionArgs = new dataSharePredicates.DataSharePredicates(); 543 conditionArgs.equalTo(RawContacts.IS_DELETED, '0'); 544 conditionArgs.and(); 545 conditionArgs.in(RawContacts.DISPLAY_NAME, displayName); 546 conditionArgs.and(); 547 conditionArgs.in(Data.DETAIL_INFO, usuallyPhone); 548 conditionArgs.and(); 549 conditionArgs.equalTo(RawContacts.FAVORITE, 0); 550 conditionArgs.and(); 551 conditionArgs.equalTo(Data.CONTENT_TYPE, 'phone'); 552 this.getDataAbilityHelper().then((dataAbilityHelper) => { 553 dataAbilityHelper.query(Data.CONTENT_URI, conditionArgs, ContactUsuallyListItem.COLUMNS) 554 .then(resultSet => { 555 let rst: ContactUsuallyListItem[] = []; 556 if (resultSet.rowCount === 0) { 557 resultSet.close(); 558 callback(rst); 559 } else { 560 resultSet.goToFirstRow(); 561 do { 562 rst.push(new ContactUsuallyListItem(resultSet)); 563 } while (resultSet.goToNextRow()); 564 resultSet.close(); 565 HiLog.i(TAG, 'getDisplayNameByFavorite query data sc.'); 566 callback(rst); 567 } 568 }) 569 .catch(error => { 570 HiLog.e(TAG, 'getDisplayNameByFavorite error:%s' + JSON.stringify(error.message)); 571 callback([]); 572 }); 573 }).catch(error => { 574 HiLog.e(TAG, 'getDisplayNameByFavorite error:%s' + JSON.stringify(error.message)); 575 callback([]); 576 }); 577 } 578 579 searchContact(actionData, callback) { 580 HiLog.i(TAG, 'searchContact start.'); 581 let conditionArgs = new dataSharePredicates.DataSharePredicates(); 582 let searchValue: string = actionData.value; 583 conditionArgs.beginWrap() 584 conditionArgs.equalTo(SearchContacts.CONTENT_TYPE, 'phone') 585 conditionArgs.and() 586 conditionArgs.beginWrap() 587 conditionArgs.like(SearchContacts.DETAIL_INFO, '%' + searchValue + '%') 588 conditionArgs.endWrap() 589 conditionArgs.or() 590 conditionArgs.beginWrap() 591 conditionArgs.equalTo(SearchContacts.SORT_FIRST_LETTER, '#') 592 conditionArgs.and() 593 conditionArgs.like(SearchContacts.SEARCH_NAME, '%' + searchValue + '%') 594 conditionArgs.endWrap() 595 conditionArgs.endWrap() 596 conditionArgs.or() 597 conditionArgs.beginWrap() 598 conditionArgs.equalTo(SearchContacts.SORT_FIRST_LETTER, searchValue[0].toUpperCase()) 599 conditionArgs.and() 600 conditionArgs.like(SearchContacts.SEARCH_NAME, '%' + searchValue + '%') 601 conditionArgs.and() 602 conditionArgs.equalTo(SearchContacts.CONTENT_TYPE, 'phone') 603 conditionArgs.endWrap() 604 conditionArgs.or() 605 conditionArgs.beginWrap() 606 conditionArgs.equalTo(SearchContacts.SORT_FIRST_LETTER, searchValue.toUpperCase()) 607 conditionArgs.and() 608 conditionArgs.equalTo(SearchContacts.CONTENT_TYPE, 'phone') 609 conditionArgs.endWrap() 610 conditionArgs.or() 611 conditionArgs.beginWrap() 612 conditionArgs.like(SearchContacts.SEARCH_NAME, '%' + actionData.value + '%') 613 conditionArgs.and() 614 conditionArgs.equalTo(SearchContacts.CONTENT_TYPE, 'phone') 615 conditionArgs.endWrap() 616 conditionArgs.or() 617 conditionArgs.beginWrap() 618 conditionArgs.like(SearchContacts.SEARCH_NAME, '%' + actionData.value + '%') 619 conditionArgs.and() 620 conditionArgs.equalTo(SearchContacts.CONTENT_TYPE, 'name') 621 conditionArgs.and() 622 conditionArgs.equalTo(SearchContacts.HAS_PHONE_NUMBER, '0') 623 conditionArgs.endWrap() 624 conditionArgs.and() 625 conditionArgs.groupBy([SearchContacts.ROW_CONTACT_ID]).distinct(); 626 this.getDataAbilityHelper().then((dataAbilityHelper) => { 627 dataAbilityHelper.query(SearchContacts.CONTENT_URI, conditionArgs, SearchContactListItem.COLUMNS) 628 .then(resultSet => { 629 HiLog.i(TAG, 'searchContact resultSet.rowCount : ' + JSON.stringify(resultSet.rowCount) ); 630 let rst: SearchContactListItem[] = []; 631 let goTo: boolean = false; 632 if (resultSet.rowCount === 0) { 633 resultSet.close(); 634 callback(rst); 635 } else { 636 resultSet.goToFirstRow(); 637 do { 638 rst.push(new SearchContactListItem(resultSet)); 639 goTo = resultSet.goToNextRow(); 640 } while (goTo); 641 resultSet.close(); 642 HiLog.i(TAG, 'searchContact query data success.'); 643 callback(rst); 644 } 645 }) 646 .catch(error => { 647 HiLog.i(TAG, 'searchContact error:%s' + JSON.stringify(error.message)); 648 callback([]); 649 }); 650 }).catch(error => { 651 HiLog.i(TAG, 'searchContact:%s' + JSON.stringify(error.message)); 652 callback([]); 653 }); 654 } 655 656 queryT9PhoneIsNotNull(favorite: any, callback) { 657 this.getAllContactNumbers(0, 0, (contactNumberMap) => { 658 this.getDataAbilityHelper().then((dataAbilityHelper) => { 659 let conditionArgs = new dataSharePredicates.DataSharePredicates(); 660 conditionArgs.like(SearchContacts.DETAIL_INFO, `%${favorite.teleNumber}%`); 661 conditionArgs.equalTo(SearchContacts.CONTENT_TYPE, 'phone'); 662 conditionArgs.orderByAsc(SearchContacts.DISPLAY_NAME) 663 dataAbilityHelper.query( 664 SearchContacts.CONTENT_URI, 665 conditionArgs, 666 SearchContactListItem.COLUMNS 667 ).then(resultSet => { 668 let rst: ContactListItem[] = []; 669 if (resultSet.rowCount === 0) { 670 resultSet.close(); 671 callback(rst); 672 } else { 673 resultSet.goToFirstRow(); 674 do { 675 let id = resultSet.getLong(resultSet.getColumnIndex(Contacts.ID)); 676 if (!contactNumberMap.has(id)) { 677 HiLog.w(TAG, 'findAll: contact id is invalid or contact has no phone number.'); 678 continue; 679 } 680 let contactListItem = new ContactListItem(resultSet); 681 contactListItem.phoneNumbers = contactNumberMap.get(id); 682 rst.push(contactListItem); 683 } while (resultSet.goToNextRow()); 684 resultSet.close(); 685 callback(rst); 686 } 687 }) 688 .catch(error => { 689 HiLog.w(TAG, 'findAll error:%s' + JSON.stringify(error.message)); 690 callback(); 691 }); 692 }).catch(error => { 693 HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message)); 694 callback(); 695 }); 696 }); 697 } 698}