7.0.7-0.0.4 • Published 7 months ago

@ohmi/react-native-contacts v7.0.7-0.0.4

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

模板版本:v0.2.2

!TIP(https://gitee.com/kunyuan-hongke/react-native-contacts)

安装与使用

请到三方库的 Releases 发布地址查看配套的版本信息:@ohmi/react-native-contacts Releases 。对于未发布到npm的旧版本,请参考安装指南安装tgz包。

进入到工程目录并输入以下命令:

npm

npm install @ohmi/react-native-contacts

yarn

yarn add @ohmi/react-native-contacts

快速使用:

!WARNING 使用时 import 的库名不变。

import React, { useState } from "react";
import { ScrollView, Button, Alert } from "react-native";
import Contacts from "react-native-contacts";

export const ContactsDemo = () => {
  let emailAddress: Contacts.EmailAddress = {
    label: "emailAddress",
    email: "test@163.com",
  };
  let phoneNumber: Contacts.PhoneNumber = {
    label: "phoneNumber",
    number: "13142536789",
  };

  let postalAddress: Contacts.PostalAddress = {
    label: "label",
    formattedAddress: "formattedAddress",
    street: "street",
    pobox: "pobox",
    neighborhood: "neighborhood",
    city: "city",
    region: "region",
    state: "state",
    postCode: "postCode",
    country: "country",
  };

  let birthday: Contacts.Birthday = {
    day: 1,
    month: 5,
    year: 2024,
  };

  let instantMessageAddress: Contacts.InstantMessageAddress = {
    username: "username",
    service: "service",
  };

  let urlAddress: Contacts.UrlAddress = {
    url: "url",
    label: "label",
  };
  let contact: Contacts.Contact = {
    company: "addcompany",
    emailAddresses: [emailAddress],
    displayName: "adddisplayName",
    familyName: "addfamilyName",
    givenName: "addgivenName",
    middleName: "addmiddleName",
    jobTitle: "addjobTitle",
    phoneNumbers: [phoneNumber],
    hasThumbnail: false,
    thumbnailPath: "addthumbnailPath",
    isStarred: false,
    postalAddresses: [postalAddress],
    prefix: "addprefix",
    suffix: "addsuffix",
    department: "adddepartment",
    birthday: birthday,
    imAddresses: [instantMessageAddress],
    urlAddresses: [urlAddress],
    note: "addnote",
  };

  return (
    <ScrollView>
      <Button
        title="requestPermission"
        onPress={() => {
          Contacts.requestPermission().then((data) => {
            console.log(`requestPermission:${JSON.stringify(data)}`);
            Alert.alert(`requestPermission:${JSON.stringify(data)}`);
          });
        }}
      />
      <Button
        title="checkPermission"
        onPress={() => {
          Contacts.checkPermission().then((data) => {
            console.log(`checkPermission:${JSON.stringify(data)}`);
            Alert.alert(`checkPermission:${JSON.stringify(data)}`);
          });
        }}
      />
      <Button
        title="getAll"
        onPress={() => {
          Contacts.getAll().then((contacts: Contacts.Contact[]) => {
            console.log(`getAll:${JSON.stringify(contacts)}`);
          });
        }}
      />
      <Button
        title="getAllWithoutPhotos"
        onPress={() => {
          Contacts.getAllWithoutPhotos().then(
            (contacts: Contacts.Contact[]) => {
              console.log(`getAllWithoutPhotos:${JSON.stringify(contacts)}`);
            }
          );
        }}
      />
      <Button
        title="getContactById"
        onPress={() => {
          Contacts.getContactById("1").then(
            (contact: Contacts.Contact | null) => {
              console.log(`getContactById:${JSON.stringify(contact)}`);
            }
          );
        }}
      />
      <Button
        title="getCount"
        onPress={() => {
          Contacts.getCount().then((count: number) => {
            console.log(`getCount:${count}`);
          });
        }}
      />
      <Button
        title="getPhotoForId"
        onPress={() => {
          Contacts.getPhotoForId("1").then((photoUrl: string) => {
            console.log(`getPhotoForId:${photoUrl}`);
          });
        }}
      />
      <Button
        title="addContact"
        onPress={() => {
          Contacts.addContact(contact).then((contact: Contacts.Contact) => {
            console.log(`addContact:${JSON.stringify(contact)}`);
          });
        }}
      />

      <Button
        title="openContactForm"
        onPress={() => {
          Contacts.openContactForm(contact).then(
            (contact: Contacts.Contact) => {
              console.log(`openContactForm:${JSON.stringify(contact)}`);
              Alert.alert(`openContactForm success`);
            }
          );
        }}
      />
      <Button
        title="openExistingContact"
        onPress={() => {
          Contacts.openExistingContact({
            recordID: "1",
            phoneNumbers: [
              {
                label: "phoneNumber2",
                number: "13521456721",
              },
            ],
          }).then((contact: Contacts.Contact) => {
            console.log(`openExistingContact:${JSON.stringify(contact)}`);
            Alert.alert(`openExistingContact success`);
          });
        }}
      />
      <Button
        title="viewExistingContact"
        onPress={() => {
          Contacts.viewExistingContact({
            recordID: "1",
            phoneNumbers: [
              {
                label: "phoneNumber2",
                number: "13521456721",
              },
            ],
          }).then((contact: Contacts.Contact) => {
            console.log(`viewExistingContact:${JSON.stringify(contact)}`);
            Alert.alert(`viewExistingContact success`);
          });
        }}
      />
      <Button
        title="editExistingContact"
        onPress={() => {
          Contacts.editExistingContact({
            recordID: "1",
            phoneNumbers: [
              {
                label: "phoneNumber2",
                number: "13521456721",
              },
            ],
          }).then((contact: Contacts.Contact) => {
            console.log(`editExistingContact:${JSON.stringify(contact)}`);
            Alert.alert(`editExistingContact success`);
          });
        }}
      />
      <Button
        title="updateContact"
        onPress={() => {
          Contacts.updateContact({
            recordID: "1",
            familyName: "updateContact",
            givenName: "updateContact",
            phoneNumbers: [
              {
                label: "phoneNumber2",
                number: "13521456721",
              },
              {
                label: "phoneNumber3",
                number: "13521456222",
              },
            ],
          }).then(() => {
            Alert.alert(`updateContact success`);
          });
        }}
      />
      <Button
        title="deleteContact"
        onPress={() => {
          Contacts.deleteContact({
            recordID: "3",
          }).then(() => {
            Alert.alert(`deleteContact success`);
          });
        }}
      />
      <Button
        title="getContactsMatchingString"
        onPress={() => {
          Contacts.getContactsMatchingString("addfamilyName").then(
            (contacts: Contacts.Contact[]) => {
              console.log(
                `getContactsMatchingString:${JSON.stringify(contacts)}`
              );
            }
          );
        }}
      />
      <Button
        title="getContactsByPhoneNumber"
        onPress={() => {
          Contacts.getContactsByPhoneNumber("789").then(
            (contacts: Contacts.Contact[]) => {
              console.log(
                `getContactsByPhoneNumber:${JSON.stringify(contacts)}`
              );
            }
          );
        }}
      />
      <Button
        title="getContactsByEmailAddress"
        onPress={() => {
          Contacts.getContactsByEmailAddress("test@163.com").then(
            (contacts: Contacts.Contact[]) => {
              console.log(
                `getContactsByEmailAddress:${JSON.stringify(contacts)}`
              );
            }
          );
        }}
      />
      <Button
        title="writePhotoToPath"
        onPress={() => {
          Contacts.writePhotoToPath("1", "file").then((data) => {
            console.log(`writePhotoToPath:${JSON.stringify(data)}`);
          });
        }}
      />
      <Button
        title="iosEnableNotesUsage"
        onPress={() => {
          Contacts.iosEnableNotesUsage(true);
          console.log(`iosEnableNotesUsage:true`);
        }}
      />
    </ScrollView>
  );
};

使用 Codegen

本库已经适配了 Codegen ,在使用前需要主动执行生成三方库桥接代码,详细请参考 Codegen 使用文档

Link

目前 HarmonyOS 暂不支持 AutoLink,所以 Link 步骤需要手动配置。

首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 harmony

1.在工程根目录的 oh-package.json5 添加 overrides 字段

{
  ...
  "overrides": {
    "@rnoh/react-native-openharmony" : "./react_native_openharmony"
  }
}

2.引入原生端代码

目前有两种方法:

  1. 通过 har 包引入(在 IDE 完善相关功能后该方法会被遗弃,目前首选此方法);
  2. 直接链接源码。

方法一:通过 har 包引入

!TIP har 包位于三方库安装路径的 harmony 文件夹下。

打开 entry/oh-package.json5,添加以下依赖

"dependencies": {
    "@rnoh/react-native-openharmony" : "file:../react_native_openharmony",
    "@ohmi/react-native-contacts": "file:../../node_modules/@ohmi/react-native-contacts/harmony/contacts.har"
  }

点击右上角的 sync 按钮

或者在终端执行:

cd entry
ohpm install

方法二:直接链接源码

!TIP 如需使用直接链接源码,请参考直接链接源码说明

3.在 ArkTs 侧引入 ContactsPackage

打开 entry/src/main/ets/RNPackagesFactory.ts,添加:

  ...
+ import {ContactsPackage} from '@ohmi/react-native-contacts/ts';

export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [new SamplePackage(ctx),
+   new ContactsPackage(ctx)];
}

4.运行

点击右上角的 sync 按钮

或者在终端执行:

cd entry
ohpm install

然后编译、运行即可。

约束与限制

兼容性

要使用此库,需要使用正确的 React-Native 和 RNOH 版本。另外,还需要使用配套的 DevEco Studio 和 手机 ROM。

请到三方库相应的 Releases 发布地址查看 Release 配套的版本信息:@ohmi/react-native-contacts Releases

权限要求

!TIP "ohos.permission.READ_CONTACTS","ohos.permission.WRITE_CONTACTS"权限等级为system_basic,授权方式为user_grant使用 ACL 签名的配置指导

打开entry/src/main/module.json5,添加:

"requestPermissions": [
     ...
     {
        "name": "ohos.permission.READ_CONTACTS",
        "reason": "$string:read_contacts_reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "always"
        }
      },
      {
        "name": "ohos.permission.WRITE_CONTACTS",
        "reason": "$string:write_contacts_reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "always"
        }
      }
]

API

!TIP "Platform"列表示该属性在原三方库上支持的平台。

!TIP "HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

NameDescriptionTypeRequiredPlatformHarmonyOS Support
getAll: Promise<Contact[]>returns all contacts as an array of objectsfunctionnoAndroid,iOSyes
getAllWithoutPhotos:Promise<Contact[]>same as getAll on Android, but on iOS it will not return uris for contact photos (because there's a significant overhead in creating the images)functionnoAndroid,iOSyes
getContactById(contactId): Promisereturns contact with defined contactId (or null if it doesn't exist)functionnoAndroid,iOSyes
getCount(): Promisereturns the number of contactsfunctionnoAndroid,iOSyes
getPhotoForId(contactId: string): PromisePromise - returns a URI (or null) for a contacts photoURLfunctionnoAndroid,iOSyes
addContact(contact: Partial): Promiseadds a contact to the AddressBookfunctionnoAndroid,iOSyes
openContactForm(contact: Partial): Promise<Contact | null>create a new contact and display in contactsUIfunctionnoAndroid,iOSpartially
openExistingContact(contact: Contact): Promiseopen existing contact (edit mode), where contact is an object with a valid recordIDfunctionnoAndroid,iOSpartially
viewExistingContact(contact: { recordID: string })open existing contact (view mode), where contact is an object with a valid recordIDfunctionnoAndroid,iOSpartially
editExistingContact(contact: Contact): Promiseadd numbers to the contact, where the contact is an object with a valid recordID and an array of phoneNumbersfunctionnoAndroid,iOSno
updateContact(contact: Partial & {recordID: string}): Promisewhere contact is an object with a valid recordIDfunctionnoAndroid,iOSyes
deleteContact(contact: Contact): Promisewhere contact is an object with a valid recordIDfunctionnoAndroid,iOSyes
getContactsMatchingString(str: string): Promise<Contact[]>where string is any string to match a name (first, middle, family) tofunctionnoAndroid,iOSyes
getContactsByPhoneNumber(phoneNumber: string): Promise<Contact[]>where string is a phone number to match to.functionnoAndroid,iOSyes
getContactsByEmailAddress(emailAddress: string): Promise<Contact[]>where string is an email address to match to.functionnoAndroid,iOSyes
checkPermission(): Promise<'authorized' | 'denied' | 'undefined'>;checks permission to access Contacts ios onlyfunctionnoiOSyes
requestPermission(): Promise<'authorized' | 'denied' | 'undefined'>request permission to access Contacts ios onlyfunctionnoiOSyes
writePhotoToPath(contactId: string, file: string): Promisewrites the contact photo to a given path android onlyfunctionnoAndroidno

Contacts | Name | Description | Type | Required | Platform | HarmonyOS Support | | ---- | ----------- | ---- | -------- | -------- | ------------------ | | recordID | 联系人id | string | no | Android,iOS | yes | | backTitle | 返回键标题 | string | no | Android,iOS | no | | company | 公司 | string|no | Android,iOS | yes | | emailAddresses | 电子邮箱地址 | EmailAddress[] | no | Android,iOS | yes | | displayName | 展示名 | string | no | Android,iOS | yes | | familyName | 姓氏 | string | no | Android,iOS | yes | | givenName | 名字 | string | no | Android,iOS | yes | | middleName | 中间名 | string | no | Android,iOS | yes | | jobTitle | 职位名称 | string | no | Android,iOS | yes | | phoneNumbers | 电话号码 | PhoneNumber[] | no | Android,iOS | yes | | hasThumbnail | 有头像 | boolean | no | Android,iOS | no | | thumbnailPath | 头像地址 | string | no | Android,iOS | no | | isStarred | 是否标记 | boolean | no | Android,iOS | yes | | postalAddresses | 邮件地址 | PostalAddress[] | no | Android,iOS | yes | | prefix | 前缀 | string | no | Android,iOS | yes | | suffix | 后缀 | string | no | Android,iOS | yes | | department | 部门 | string | no | Android,iOS | yes | | birthday | 生日 | Birthday | no | Android,iOS | yes | | imAddresses | 即时消息地址 | InstantMessageAddress[] | no | Android,iOS | yes | | urlAddresses | 图片地址 | UrlAddress[] | no | Android,iOS | no | | note | 备注 | string | no | Android,iOS | yes |

EmailAddress | Name | Description | Type | Required | Platform | HarmonyOS Support | | ---- | ----------- | ---- | -------- | -------- | ------------------ | | label | 标题 | string | no | Android,iOS | yes | | email | 地址 | string | no | Android,iOS | yes |

PhoneNumber | Name | Description | Type | Required | Platform | HarmonyOS Support | | ---- | ----------- | ---- | -------- | -------- | ------------------ | | label | 标题 | string | no | Android,iOS | yes | | number | 号码 | string | no | Android,iOS | yes |

PostalAddress | Name | Description | Type | Required | Platform | HarmonyOS Support | | ---- | ----------- | ---- | -------- | -------- | ------------------ | | label | 标题 | string | no | Android,iOS | yes | | formattedAddress | 格式化地址 | string | no | Android,iOS | yes | | street | 街道 | string | no | Android,iOS | yes | | pobox | 信箱 | string | no | Android,iOS | yes | | neighborhood | 邻域 | string | no | Android,iOS | yes | | city | 城市 | string | no | Android,iOS | yes | | region | 区域 | string | no | Android,iOS | yes | | state | 州 | string | no | Android,iOS | yes | | postCode | 邮政编码 | string | no | Android,iOS | yes | | country | 国家/地区 | string | no | Android,iOS | yes |

InstantMessageAddress | Name | Description | Type | Required | Platform | HarmonyOS Support | | ---- | ----------- | ---- | -------- | -------- | ------------------ | | username | 用户名 | string | no | Android,iOS | no | | service | 服务地址 | string | no | Android,iOS | no |

Birthday | Name | Description | Type | Required | Platform | HarmonyOS Support | | ---- | ----------- | ---- | -------- | -------- | ------------------ | | day | 日 | number | no | Android,iOS | yes | | month | 月 | number | no | Android,iOS | yes | | year | 年 | number | no | Android,iOS | yes |

UrlAddress | Name | Description | Type | Required | Platform | HarmonyOS Support | | ---- | ----------- | ---- | -------- | -------- | ------------------ | | url | 路径 | string | no | Android,iOS | yes | | label | 标题 | string | no | Android,iOS | yes |

遗留问题

  • openContactForm:跳转到系统联系人界面只支持姓名和电话参数传递,需要系统联系人应用支持所有属性,另外创建成功之后无法返回联系人信息,联系人应用目前不支持。issue#1
  • openExistingContact:联系人应用新增和编辑是同一个界面,目前参数只支持姓名和电话传递,编辑成功之后也无法拿到联系人信息issue#1
  • viewExistingContact:查看界面只有姓名和电话信息,需要联系人应用补齐所有属性issue#1
  • editExistingContact:没有单独的只支持编辑电话号码的页面,目前同编辑页面issue#1
  • writePhotoToPath:系统联系人应用不支持issue#1

其他

开源协议

本项目基于 The MIT License (MIT) ,请自由地享受和参与开源。