Expo 联系人
一个提供访问手机系统联系人的库。
For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.
expo-contacts 提供对设备系统联系人的访问权限,允许你获取联系人信息,以及添加、编辑或删除联系人。
在 iOS 上,联系人具有一个多层级的分组系统,你也可以通过此 API 访问它。
安装
- npx expo install expo-contactsIf you are installing this in an existing React Native app, make sure to install expo in your project.
在 app 配置中配置
如果你在项目中使用配置插件(Continuous Native Generation (CNG)),你可以使用 expo-contacts 内置的 config plugin 进行配置。该插件允许你配置各种无法在运行时设置、且需要重新构建新的应用二进制文件才会生效的属性。如果你的应用不使用 CNG,那么你需要手动配置该库。
Example app.json with config plugin
{ "expo": { "plugins": [ [ "expo-contacts", { "contactsPermission": "Allow $(PRODUCT_NAME) to access your contacts." } ] ] } }
Configurable properties
| Name | Default | Description |
|---|---|---|
contactsPermission | "Allow $(PRODUCT_NAME) to access your contacts" | Only for: iOS 用于设置 |
Are you using this library in an existing React Native app?
如果你没有使用 Continuous Native Generation(CNG)(也就是你在手动使用原生 android 和 ios 项目),那么你需要在原生项目中配置以下权限:
-
对于 Android,请将
android.permission.READ_CONTACTS和android.permission.WRITE_CONTACTS权限添加到项目的 android/app/src/main/AndroidManifest.xml 中:<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" /> -
对于 iOS,请将
NSContactsUsageDescription键添加到项目的 ios/[app]/Info.plist 中:<key>NSContactsUsageDescription</key> <string>Allow $(PRODUCT_NAME) to access your contacts</string>
使用
import { useEffect } from 'react'; import { StyleSheet, View, Text } from 'react-native'; import * as Contacts from 'expo-contacts'; export default function App() { useEffect(() => { (async () => { const { status } = await Contacts.requestPermissionsAsync(); if (status === 'granted') { const { data } = await Contacts.getContactsAsync({ fields: [Contacts.Fields.Emails], }); if (data.length > 0) { const contact = data[0]; console.log(contact); } } })(); }, []); return ( <View style={styles.container}> <Text>联系人模块示例</Text> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });
API
import * as Contacts from 'expo-contacts';
Component
Type: React.PureComponent<ContactAccessButtonProps>
Creates a contact access button to quickly add contacts under limited-access authorization.
For more details, you can read the Apple docs about the underlying ContactAccessButton SwiftUI view.
ColorValueA color of the button's background. Provided color should not be transparent, otherwise it may not satisfy platform requirements for button legibility.
stringWhen the query produces a single result, the contact access button shows the caption under the matching contact name. It can be nothing (default), email address or phone number.
Acceptable values are: 'default' | 'email' | 'phone'
string[]An array of email addresses. The search omits contacts matching query that also match any email address in this array.
string[]An array of phone numbers. The search omits contacts matching query that also match any phone number in this set.
stringA string to match against contacts not yet exposed to the app. You typically get this value from a search UI that your app presents, like a text field.
ColorValueA color of the button's title. Slightly dimmed version of this color is used for the caption text. Make sure there is a good contrast between the text and the background, otherwise platform requirements for button legibility may not be satisfied.
ColorValueA tint color of the button and the modal that is presented when there is more than one match.
Static Methods
Returns a boolean whether the ContactAccessButton is available on the platform.
This is true only on iOS 18.0 and newer.
booleanConstants
Methods
| Parameter | Type | Description |
|---|---|---|
| contact | Contact | A contact with the changes you wish to persist. The |
| containerId(optional) | string | - |
Creates a new contact and adds it to the system.
Note: For Android users, the Expo Go app does not have the required
WRITE_CONTACTSpermission to write to Contacts. You will need to create a development build and add permission in there manually to use this method.
Promise<string>A promise that fulfills with ID of the new system contact.
Example
const contact = { [Contacts.Fields.FirstName]: 'Bird', [Contacts.Fields.LastName]: 'Man', [Contacts.Fields.Company]: 'Young Money', }; const contactId = await Contacts.addContactAsync(contact);
| Parameter | Type | Description |
|---|---|---|
| contactId | string | ID of the contact you want to edit. |
| groupId | string | ID for the group you want to add membership to. |
Add a contact as a member to a group. A contact can be a member of multiple groups.
Promise<any>Example
await Contacts.addExistingContactToGroupAsync( '665FDBCFAE55-D614-4A15-8DC6-161A368D', '161A368D-D614-4A15-8DC6-665FDBCFAE55' );
| Parameter | Type | Description |
|---|---|---|
| groupId | string | The group you want to target. |
| containerId | string | The container you want to add membership to. |
Add a group to a container.
Promise<any>Example
await Contacts.addExistingGroupToContainerAsync( '161A368D-D614-4A15-8DC6-665FDBCFAE55', '665FDBCFAE55-D614-4A15-8DC6-161A368D' );
| Parameter | Type | Description |
|---|---|---|
| name(optional) | string | Name of the new group. |
| containerId(optional) | string | The container you to add membership to. |
Create a group with a name, and add it to a container. If the container is undefined, the default container will be targeted.
Promise<string>A promise that fulfills with ID of the new group.
Example
const groupId = await Contacts.createGroupAsync('Sailor Moon');
| Parameter | Type | Description |
|---|---|---|
| id | string | The ID of a system contact. |
| fields(optional) | FieldType[] | If specified, the fields defined will be returned. When skipped, all fields will be returned. |
Used for gathering precise data about a contact. Returns a contact matching the given id.
Promise<ExistingContact | undefined>A promise that fulfills with Contact object with ID matching the input ID, or undefined if there is no match.
Example
const contact = await Contacts.getContactByIdAsync('161A368D-D614-4A15-8DC6-665FDBCFAE55'); if (contact) { console.log(contact); }
| Parameter | Type | Description |
|---|---|---|
| contactQuery(optional) | ContactQuery | Object used to query contacts. Default: {} |
Return a list of contacts that fit a given criteria. You can get all of the contacts by passing no criteria.
Promise<ContactResponse>A promise that fulfills with ContactResponse object returned from the query.
Example
const { data } = await Contacts.getContactsAsync({ fields: [Contacts.Fields.Emails], }); if (data.length > 0) { const contact = data[0]; console.log(contact); }
| Parameter | Type | Description |
|---|---|---|
| containerQuery | ContainerQuery | Information used to gather containers. |
Query a list of system containers.
Promise<Container[]>A promise that fulfills with array of containers that fit the query.
Example
const allContainers = await Contacts.getContainersAsync({ contactId: '665FDBCFAE55-D614-4A15-8DC6-161A368D', });
Get the default container's ID.
Promise<string>A promise that fulfills with default container ID.
Example
const containerId = await Contacts.getDefaultContainerIdAsync();
| Parameter | Type | Description |
|---|---|---|
| groupQuery | GroupQuery | Information regarding which groups you want to get. |
Checks user's permissions for accessing contacts data.
Promise<ContactsPermissionResponse>A promise that resolves to a ContactsPermissionResponse object.
Checks if any contacts exist on the device without querying all contacts. This method requires contacts read permission.
Promise<boolean>A promise that fulfills with a boolean, indicating whether there are any contacts on the device.
Example
const hasContacts = await Contacts.hasContactsAsync(); if (hasContacts) { console.log('Contacts are available'); }
Returns whether the Contacts API is enabled on the current device. This method does not check the app permissions.
Promise<boolean>A promise that fulfills with a boolean, indicating whether the Contacts API is available on the current device. It always resolves to false on web.
Presents a modal which allows the user to select which contacts the app has access to. Using this function is reasonable only when the app has "limited" permissions.
Promise<string[]>A promise that resolves with an array of contact identifiers that were newly granted to the app. Contacts which the app lost access to are not listed. On platforms other than iOS and below 18.0, the promise rejects immediately.
Presents a native contact picker to select a single contact from the system. On Android, the READ_CONTACTS permission is required. You can
obtain this permission by calling the Contacts.requestPermissionsAsync() method. On iOS, no permissions are
required to use this method.
Promise<ExistingContact | null>A promise that fulfills with a single Contact object if a contact is selected or null if no contact is selected (when selection is canceled).
| Parameter | Type | Description |
|---|---|---|
| contactId(optional) | string | null | The ID of a system contact. |
| contact(optional) | Contact | null | A contact with the changes you want to persist. |
| formOptions(optional) | FormOptions | Options for the native editor. Default: {} |
Present a native form for manipulating contacts.
Promise<any>Example
await Contacts.presentFormAsync('161A368D-D614-4A15-8DC6-665FDBCFAE55');
| Parameter | Type | Description |
|---|---|---|
| contactId | string | ID of the contact you want to delete. |
Delete a contact from the system.
Promise<any>Example
await Contacts.removeContactAsync('161A368D-D614-4A15-8DC6-665FDBCFAE55');
| Parameter | Type | Description |
|---|---|---|
| contactId | string | ID of the contact you want to remove. |
| groupId | string | ID for the group you want to remove membership of. |
Remove a contact's membership from a given group. This will not delete the contact.
Promise<any>Example
await Contacts.removeContactFromGroupAsync( '665FDBCFAE55-D614-4A15-8DC6-161A368D', '161A368D-D614-4A15-8DC6-665FDBCFAE55' );
| Parameter | Type | Description |
|---|---|---|
| groupId | string | ID of the group you want to remove. |
Delete a group from the device.
Promise<any>Example
await Contacts.removeGroupAsync('161A368D-D614-4A15-8DC6-665FDBCFAE55');
Asks the user to grant permissions for accessing contacts data.
Promise<ContactsPermissionResponse>A promise that resolves to a ContactsPermissionResponse object.
| Parameter | Type | Description |
|---|---|---|
| contact | {
id: string
} & Partial<ExistingContact> | A contact object including the wanted changes. Contact |
Mutate the information of an existing contact. Due to an iOS bug, nonGregorianBirthday field cannot be modified.
Promise<string>A promise that fulfills with ID of the updated system contact if mutation was successful.
Example
const contact = { id: '161A368D-D614-4A15-8DC6-665FDBCFAE55', [Contacts.Fields.FirstName]: 'Drake', [Contacts.Fields.Company]: 'Young Money', }; await Contacts.updateContactAsync(contact);
| Parameter | Type | Description |
|---|---|---|
| groupName | string | New name for an existing group. |
| groupId | string | ID of the group you want to edit. |
Change the name of an existing group.
Promise<any>Example
await Contacts.updateGroupName('Expo Friends', '161A368D-D614-4A15-8DC6-665FDBCFAE55');
| Parameter | Type | Description |
|---|---|---|
| contactQuery(optional) | ContactQuery | Used to query contact you want to write. Default: {} |
Query a set of contacts and write them to a local URI that can be used for sharing.
Promise<string | undefined>A promise that fulfills with shareable local URI, or undefined if there was no match.
Example
const localUri = await Contacts.writeContactToFileAsync({ id: '161A368D-D614-4A15-8DC6-665FDBCFAE55', }); Share.share({ url: localUri, message: 'Call me!' });
Event Subscriptions
| Parameter | Type | Description |
|---|---|---|
| listener | () => void | The function that will be executed when contacts change. This function accepts no arguments. |
Adds a listener for contact changes. The listener will be called whenever contacts are added, updated, or deleted.
Platform differences:
- Android: 5-7 second delay - uses
ContentObserverwith inherent system delays - iOS: Immediate response - uses
CNContactStoreDidChangeNotification
The Android delay is a system limitation that affects all apps using ContentObserver for contacts.
This delay is by design to batch notifications for better performance and battery life.
For more immediate updates, you can also listen to app state changes and refresh
contacts when the app comes to the foreground. This ensures users see the latest contacts when
returning from the native Contacts app.
EventSubscriptionA subscription object with a remove method to stop listening.
Example
const subscription = Contacts.addContactChangeListener(() => { console.log('Contacts changed - refreshing contact list'); // Refresh your contact list when changes are detected loadContacts(); }); // Later, remove the listener subscription.remove();
Types
| Property | Type | Description |
|---|---|---|
| city(optional) | string | City name. |
| country(optional) | string | Country name |
| id(optional) | string | Unique ID. This value will be generated by the OS. |
| isoCountryCode(optional) | string | |
| label | string | Localized display name. |
| neighborhood(optional) | string | Neighborhood name. |
| poBox(optional) | string | P.O. Box. |
| postalCode(optional) | string | Local post code. |
| region(optional) | string | Region or state name. |
| street(optional) | string | Street name. |
Literal Type: union
Acceptable values are: CalendarFormats | {CalendarFormats}
Base contact type without ID. For better type safety, consider using:
Contactwhen creating new contacts (no ID needed)ExistingContactwhen working with contacts returned from the system (ID guaranteed)
| Property | Type | Description |
|---|---|---|
| addresses(optional) | Address[] | Locations. |
| birthday(optional) | Date | Birthday information in Gregorian format. |
| company(optional) | string | Organization the entity belongs to. |
| contactType | ContactType | Denoting a person or company. |
| dates(optional) | Date[] | A labeled list of other relevant user dates in Gregorian format. |
| department(optional) | string | Job department. |
| emails(optional) | Email[] | Email addresses. |
| firstName(optional) | string | Given name. |
| image(optional) | Image | Thumbnail image. On iOS it size is set to 320×320px, on Android it may vary. |
| imageAvailable(optional) | boolean | Used for efficient retrieval of images. |
| instantMessageAddresses(optional) | InstantMessageAddress[] | Instant messaging connections. |
| isFavorite(optional) | boolean | Only for: Android Whether the contact is starred. |
| jobTitle(optional) | string | Job description. |
| lastName(optional) | string | Last name. |
| maidenName(optional) | string | Maiden name. |
| middleName(optional) | string | Middle name |
| name | string | Full name with proper format. |
| namePrefix(optional) | string | Dr., Mr., Mrs., and so on. |
| nameSuffix(optional) | string | Jr., Sr., and so on. |
| nickname(optional) | string | An alias to the proper name. |
| nonGregorianBirthday(optional) | Date | Only for: iOS Birthday that doesn't conform to the Gregorian calendar format, interpreted based on the calendar |
| note(optional) | string | Additional information.
|
| phoneNumbers(optional) | PhoneNumber[] | Phone numbers. |
| phoneticFirstName(optional) | string | Pronunciation of the first name. |
| phoneticLastName(optional) | string | Pronunciation of the last name. |
| phoneticMiddleName(optional) | string | Pronunciation of the middle name. |
| rawImage(optional) | Image | Raw image without cropping, usually large. |
| relationships(optional) | Relationship[] | Names of other relevant user connections. |
| socialProfiles(optional) | SocialProfile[] | Only for: iOS Social networks. |
| urlAddresses(optional) | UrlAddress[] | Associated web URLs. |
Used to query contacts from the user's device.
| Property | Type | Description |
|---|---|---|
| containerId(optional) | string | Only for: iOS Get all contacts that belong to the container matching this ID. |
| fields(optional) | FieldType[] | If specified, the defined fields will be returned. If skipped, all fields will be returned. |
| groupId(optional) | string | Only for: iOS Get all contacts that belong to the group matching this ID. |
| id(optional) | string | string[] | Get contacts with a matching ID or array of IDs. |
| name(optional) | string | Get all contacts whose name contains the provided string (not case-sensitive). |
| pageOffset(optional) | number | The number of contacts to skip before gathering contacts. |
| pageSize(optional) | number | The max number of contacts to return. If skipped or set to |
| rawContacts(optional) | boolean | Only for: iOS Prevent unification of contacts when gathering. Default: false |
| sort(optional) | ContactSort | Sort method used when gathering contacts. |
The return value for queried contact operations like getContactsAsync.
| Property | Type | Description |
|---|---|---|
| data | ExistingContact[] | An array of contacts that match a particular query. |
| hasNextPage | boolean | This will be |
| hasPreviousPage | boolean | This will be |
String union of SortTypes values.
Type: PermissionResponse extended by:
| Property | Type | Description |
|---|---|---|
| accessPrivileges(optional) | 'all' | 'limited' | 'none' | Indicates if your app has access to the whole or only part of the contact library. Possible values are:
|
Used to query native contact containers.
| Property | Type | Description |
|---|---|---|
| contactId(optional) | string | Query all the containers that parent a contact. |
| containerId(optional) | string | string[] | Query all the containers that matches ID or an array od IDs. |
| groupId(optional) | string | Query all the containers that parent a group. |
| Property | Type | Description |
|---|---|---|
| day | number | Day. |
| format(optional) | CalendarFormatType | Format for the date. This is provided by the OS, do not set this manually. |
| id(optional) | string | Unique ID. This value will be generated by the OS. |
| label(optional) | string | Localized display name. |
| month | number | Month - adjusted for JavaScript |
| year(optional) | number | Year. |
| Property | Type | Description |
|---|---|---|
| email(optional) | string | Email address. |
| id(optional) | string | Unique ID. This value will be generated by the OS. |
| isPrimary(optional) | boolean | Flag signifying if it is a primary email address. |
| label | string | Localized display name. |
Type for existing contacts returned from the system - guarantees the id field is present.
Type: Contact extended by:
| Property | Type | Description |
|---|---|---|
| id | string | Immutable identifier used for querying and indexing. This value will be generated by the OS when the contact is created. |
Denotes the functionality of a native contact form.
| Property | Type | Description |
|---|---|---|
| allowsActions(optional) | boolean | Actions like share, add, create. |
| allowsEditing(optional) | boolean | Allows for contact mutation. |
| alternateName(optional) | string | Used if contact doesn't have a name defined. |
| cancelButtonTitle(optional) | string | The name of the left bar button. Only applies when editing an existing contact. |
| displayedPropertyKeys(optional) | FieldType[] | The properties that will be displayed when viewing a contact. |
| groupId(optional) | string | The parent group for a new contact. |
| isNew(optional) | boolean | Present the new contact controller. If set to |
| message(optional) | string | The message displayed under the name of the contact. Only applies when editing an existing contact. |
| preventAnimation(optional) | boolean | Prevents the controller from animating in. |
| shouldShowLinkedContacts(optional) | boolean | Show or hide the similar contacts. |
A parent to contacts. A contact can belong to multiple groups. Here are some query operations you can perform:
- Child Contacts:
getContactsAsync({ groupId }) - Groups From Container:
getGroupsAsync({ containerId }) - Groups Named:
getContainersAsync({ groupName })
| Property | Type | Description |
|---|---|---|
| id(optional) | string | The editable name of a group. |
| name(optional) | string | Immutable id representing the group. |
Used to query native contact groups.
| Property | Type | Description |
|---|---|---|
| containerId(optional) | string | Query all groups that belong to a certain container. |
| groupId(optional) | string | Query the group with a matching ID. |
| groupName(optional) | string | Query all groups matching a name. |
Information regarding thumbnail images.
On Android you can get dimensions using
Image.getSizemethod.
| Property | Type | Description |
|---|---|---|
| base64(optional) | string | Image as Base64 string. |
| height(optional) | number | Only for: iOS Image height |
| uri(optional) | string | A local image URI.
|
| width(optional) | number | Only for: iOS Image width. |
| Property | Type | Description |
|---|---|---|
| id(optional) | string | Unique ID. This value will be generated by the OS. |
| label | string | Localized display name. |
| localizedService(optional) | string | Localized name of app. |
| service(optional) | string | Name of instant messaging app. |
| username(optional) | string | Username in IM app. |
Literal Type: union
Permission expiration time. Currently, all permissions are granted permanently.
Acceptable values are: 'never' | number
An object obtained by permissions get and request functions.
| Property | Type | Description |
|---|---|---|
| canAskAgain | boolean | Indicates if user can be asked again for specific permission. If not, one should be directed to the Settings app in order to enable/disable the permission. |
| expires | PermissionExpiration | Determines time when the permission expires. |
| granted | boolean | A convenience boolean that indicates if the permission is granted. |
| status | PermissionStatus | Determines the status of the permission. |
| Property | Type | Description |
|---|---|---|
| countryCode(optional) | string | Country code. Example
|
| digits(optional) | string | Phone number without format. Example
|
| id(optional) | string | Unique ID. This value will be generated by the OS. |
| isPrimary(optional) | boolean | Flag signifying if it is a primary phone number. |
| label | string | Localized display name. |
| number(optional) | string | Phone number. |
| Property | Type | Description |
|---|---|---|
| id(optional) | string | Unique ID. This value will be generated by the OS. |
| label | string | Localized display name. |
| name(optional) | string | Name of related contact. |
| Property | Type | Description |
|---|---|---|
| id(optional) | string | Unique ID. This value will be generated by the OS. |
| label | string | Localized display name. |
| localizedProfile(optional) | string | Localized profile name. |
| service(optional) | string | Name of social app. |
| url(optional) | string | Web URL. |
| userId(optional) | string | Username ID in social app. |
| username(optional) | string | Username in social app. |
| Property | Type | Description |
|---|---|---|
| id(optional) | string | Unique ID. This value will be generated by the OS. |
| label | string | Localized display name. |
| url(optional) | string | Web URL. |
Enums
This format denotes the common calendar format used to specify how a date is calculated in nonGregorianBirthday fields.
Possible fields to retrieve for a contact.
权限
Android
该库会自动为你的应用添加 READ_CONTACTS 和 WRITE_CONTACTS 权限:
| Android Permission | Description |
|---|---|
Allows an application to read the user's contacts data. | |
Allows an application to write the user's contacts data. |
iOS
此库使用以下用途说明键: