模板版本:v0.2.2
[!TIP] Github 地址
请到三方库的 Releases 发布地址查看配套的版本信息:@react-native-oh-tpl/react-native-contacts Releases 。对于未发布到npm的旧版本,请参考安装指南安装tgz包。
进入到工程目录并输入以下命令:
npm install @react-native-oh-tpl/react-native-contacts
yarn add @react-native-oh-tpl/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: "[email protected]",
};
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("[email protected]").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 使用文档。
目前 HarmonyOS 暂不支持 AutoLink,所以 Link 步骤需要手动配置。
首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 harmony
{
...
"overrides": {
"@rnoh/react-native-openharmony" : "./react_native_openharmony"
}
}
目前有两种方法:
- 通过 har 包引入(在 IDE 完善相关功能后该方法会被遗弃,目前首选此方法);
- 直接链接源码。
方法一:通过 har 包引入
[!TIP] har 包位于三方库安装路径的
harmony
文件夹下。
打开 entry/oh-package.json5
,添加以下依赖
"dependencies": {
"@rnoh/react-native-openharmony" : "file:../react_native_openharmony",
"@react-native-oh-tpl/react-native-contacts": "file:../../node_modules/@react-native-oh-tpl/react-native-contacts/harmony/contacts.har"
}
点击右上角的 sync
按钮
或者在终端执行:
cd entry
ohpm install
方法二:直接链接源码
[!TIP] 如需使用直接链接源码,请参考直接链接源码说明
打开 entry/src/main/ets/RNPackagesFactory.ts
,添加:
...
+ import {ContactsPackage} from '@react-native-oh-tpl/react-native-contacts/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [new SamplePackage(ctx),
+ new ContactsPackage(ctx)];
}
点击右上角的 sync
按钮
或者在终端执行:
cd entry
ohpm install
然后编译、运行即可。
要使用此库,需要使用正确的 React-Native 和 RNOH 版本。另外,还需要使用配套的 DevEco Studio 和 手机 ROM。
请到三方库相应的 Releases 发布地址查看 Release 配套的版本信息:@react-native-oh-tpl/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"
}
}
]
[!TIP] "Platform"列表示该属性在原三方库上支持的平台。
[!TIP] "HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
Name | Description | Type | Required | Platform | HarmonyOS Support |
---|---|---|---|---|---|
getAll: Promise<Contact[]> | returns all contacts as an array of objects | function | no | Android,iOS | yes |
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) |
function | no | Android,iOS | yes |
getContactById(contactId): Promise | returns contact with defined contactId (or null if it doesn't exist) | function | no | Android,iOS | yes |
getCount(): Promise | returns the number of contacts | function | no | Android,iOS | yes |
getPhotoForId(contactId: string): Promise | Promise - returns a URI (or null) for a contacts photoURL | function | no | Android,iOS | yes |
addContact(contact: Partial): Promise | adds a contact to the AddressBook | function | no | Android,iOS | yes |
openContactForm(contact: Partial): Promise<Contact | null> | create a new contact and display in contactsUI | function | no | Android,iOS | partially |
openExistingContact(contact: Contact): Promise | open existing contact (edit mode), where contact is an object with a valid recordID | function | no | Android,iOS | partially |
viewExistingContact(contact: { recordID: string }) | open existing contact (view mode), where contact is an object with a valid recordID | function | no | Android,iOS | partially |
editExistingContact(contact: Contact): Promise | add numbers to the contact, where the contact is an object with a valid recordID and an array of phoneNumbers | function | no | Android,iOS | no |
updateContact(contact: Partial & {recordID: string}): Promise | where contact is an object with a valid recordID | function | no | Android,iOS | yes |
deleteContact(contact: Contact): Promise | where contact is an object with a valid recordID | function | no | Android,iOS | yes |
getContactsMatchingString(str: string): Promise<Contact[]> | where string is any string to match a name (first, middle, family) to | function | no | Android,iOS | yes |
getContactsByPhoneNumber(phoneNumber: string): Promise<Contact[]> | where string is a phone number to match to. | function | no | Android,iOS | yes |
getContactsByEmailAddress(emailAddress: string): Promise<Contact[]> | where string is an email address to match to. | function | no | Android,iOS | yes |
checkPermission(): Promise<'authorized' | 'denied' | 'undefined'>; | checks permission to access Contacts ios only | function | no | iOS | yes |
requestPermission(): Promise<'authorized' | 'denied' | 'undefined'> | request permission to access Contacts ios only | function | no | iOS | yes |
writePhotoToPath(contactId: string, file: string): Promise | writes the contact photo to a given path android only | function | no | Android | no |
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 |
地址 | 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) ,请自由地享受和参与开源。