This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 56).
Expo 分享
一个提供与其他应用共享和接收数据功能的库。
For the complete documentation index, see llms.txt. Use this file to discover all available pages.
expo-sharing 允许你直接与其他兼容应用共享文件,并接收从其他应用共享过来的兼容数据。
Web 上的共享限制
expo-sharingfor web 基于 Web Share API 构建,而该 API 目前仍然只有非常有限的浏览器支持。在调用它之前,请务必先通过Sharing.isAvailableAsync()检查该 API 是否可用。- Web 上需要 HTTPS:Web Share API 仅在页面通过 https 提供时才可用于 web。使用
npx expo start --tunnel运行你的应用以启用它。 - Web 上不支持本地文件共享:通过 URI 共享本地文件在 Android 和 iOS 上可行,但在 web 上不行。你不能在 web 上通过 URI 共享本地文件——你需要先把它们上传到某处,然后共享那个 URI。
安装
- npx expo install expo-sharingIf you are installing this in an existing React Native app, make sure to install expo in your project.
在 app 配置中进行配置
如果你在项目中使用了配置插件(Continuous Native Generation (CNG)),你可以使用 expo-sharing 内置的配置插件进行配置。该插件允许你配置一些无法在运行时设置、且需要构建新的应用二进制文件后才会生效的属性。如果你的应用不使用 CNG,那么你需要手动配置该库。
Example app.json with config plugin
以下示例展示了一个可在 Android 和 iOS 上共享单张或多张图片的配置:
{ "expo": { "plugins": [ [ "expo-sharing", { "ios": { "enabled": true, "activationRule": { "supportsImageWithMaxCount": 5 } }, "android": { "enabled": true, "singleShareMimeTypes": ["image/*"], "multipleShareMimeTypes": ["image/*"] } } ] ] } }
Configurable properties
| Name | Default | Description |
|---|---|---|
ios.enabled | false | 一个布尔值,用于启用 iOS 分享扩展。如果为 |
ios.extensionBundleIdentifier | {appBundleIdentifier}.ShareExtension | iOS 分享扩展的 bundle identifier。 |
ios.appGroupId | group.{appBundleIdentifier} | 用于在应用和扩展之间共享数据的 App Group ID。 |
ios.activationRule | {} | 用于 Info.plist 中 |
android.enabled | false | 一个布尔值,用于启用 Android 分享 intent 处理。如果为 |
android.singleShareMimeTypes | [] | 一个 MIME 类型数组,用于接受单文件共享(使用 |
android.multipleShareMimeTypes | [] | 一个 MIME 类型数组,用于接受多文件共享(使用 |
从其他应用共享到你的应用
注意:此功能目前处于实验性状态。在 iOS 上,共享扩展会打开主目标,而不是在共享ViewController中处理共享内容,这并未得到 Apple 的官方支持,并且可能在未来的 iOS 版本中失效。
当应用用户向你的应用共享内容时,操作系统会启动你的应用(也称为将其置于前台的过程)。要处理此操作,你需要配置导航以处理传入的深度链接。
Expo Router
如果你正在使用 Expo Router,可以使用 +native-intent.ts 文件来处理传入的共享 intent。这允许你检查传入路径并重定向到特定路由。
import { getSharedPayloads } from 'expo-sharing'; export async function redirectSystemPath({ path, initial }: { path: string; initial: boolean }) { try { // 检查该 URL 是否来自分享扩展/intent if (new URL(path).hostname === 'expo-sharing') { return '/handle-share'; } return path; } catch { // 出错时回退到根路径 return '/'; } }
React Navigation
如果你正在使用 React Navigation,可以使用 linking 属性来拦截深度链接。你应该检查传入 URL 的 hostname 是否匹配 expo-sharing scheme,并将用户重定向到特定的处理屏幕。
import * as Linking from 'expo-linking'; import { createStaticNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; const RootStack = createNativeStackNavigator({ screens: { // 其他屏幕 HandleShare: { screen: HandleShare, linking: { path: '/handle-share', }, }, }, }); const Navigation = createStaticNavigation(RootStack); function processUrl(url: string | null) { if (!url) return null; // 你的分享处理屏幕的路径 const handlerUrl = Linking.createURL('/handle-share'); // 检查该 URL 是否来自分享扩展/intent if (new URL(url).hostname === 'expo-sharing') { return handlerUrl; } return url; } export default function App() { return ( <Navigation // 其余的导航配置 linking={{ prefixes: [Linking.createURL('/')], async getInitialURL() { const initialUrl = await Linking.getInitialURL(); return processUrl(initialUrl); }, subscribe(listener) { const linkingSubscription = Linking.addEventListener('url', ({ url }) => { const processedUrl = processUrl(url) ?? url; listener(processedUrl); }); return () => { linkingSubscription.remove(); }; }, }} /> ); }
没有导航库
如果你正在创建一个不使用导航库的基础应用,那么你的主屏幕就是处理屏幕。你可以继续阅读下一节。
显示共享内容
一旦你将用户重定向到处理屏幕后,就可以使用 useIncomingShare hook 来访问并显示共享数据。
以下示例展示了一个显示共享图片的屏幕:
import { Image } from 'expo-image'; import { useIncomingShare } from 'expo-sharing'; import { View, StyleSheet, ActivityIndicator } from 'react-native'; export default function ShareReceived() { const { resolvedSharedPayloads, isResolving } = useIncomingShare(); if (isResolving) { return ( <View style={styles.container}> <ActivityIndicator size="large" /> </View> ); } return ( <View style={styles.container}> {resolvedSharedPayloads.map((payload, index) => { if (payload.contentType === 'image') { return <Image source={{ uri: payload.contentUri }} style={styles.image} key={index} />; } return null; })} </View> ); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'white', }, image: { width: 300, height: 300, marginBottom: 20, borderRadius: 10, }, });
API
import * as Sharing from 'expo-sharing';
Hooks
Hook, which returns the data shared with the application and updates the data if the shared payload has changed.
UseIncomingShareResultProps
{
enabled: boolean,
multipleShareMimeTypes: string[],
singleShareMimeTypes: string[]
}{
activationRule: ActivationRule,
appGroupId: string,
enabled: boolean,
extensionBundleIdentifier: string
}Methods
Returns resolved data shared with the app. Compared to data returned from getSharedPayloads contains additional
information useful for reading and displaying the data. For example, when a web URL is shared with the app,
a resolved payload will contain additional information about the URL contents.
Depending on what has been shared, this method may require a network connection to resolve content details.
Promise<ResolvedSharePayload[]>Returns raw data shared with the app. Returns an empty array if no data has been shared with the app.
SharePayload[]Determine if the sharing API can be used in this app.
Promise<boolean>A promise that fulfills with true if the sharing API can be used, and false otherwise.
| Parameter | Type | Description |
|---|---|---|
| url | string | Local file URL to share. |
| options(optional) | SharingOptions | A map of share options. Default: {} |
Opens action sheet to share file to different applications which can handle this type of file.
Promise<void>Types
Type: SharePayload extended by:
| Property | Type | Description |
|---|---|---|
| contentMimeType | string | null | Mime type of the content accessible via the |
| contentSize | number | null | Size of the content accessible via the |
| contentType | ContentType | null | Type of the content accessible via the |
| contentUri | string | null | URI which can be used to access the shared content. When resolving contents of a URL with redirects, contains the redirect target URI.
Null when resolving a |
| originalName | string | null | If applicable, value of the |
Literal Type: string
Describes the resolved content type.
Acceptable values are: 'text' | 'audio' | 'image' | 'video' | 'file' | 'website'
Literal Type: union
Represents a payload shared with the app, with additional information about the shared contents.
Acceptable values are: UriBasedResolvedSharePayload | TextBasedResolvedSharePayload
Represents raw data shared with the app.
| Property | Type | Description |
|---|---|---|
| mimeType(optional) | string | The MIME type of the contents of the Default: 'text/plain' |
| shareType(optional) | ShareType | The type of the shared content. Default: 'text' |
| value(optional) | string | The primary value of the content.
Default: "" |
Literal Type: string
Determines the type of content being shared.
text: Plain text content.url: A specific URL.audio: An audio file.image: An image file.video: A video file.file: A generic file.
Acceptable values are: 'text' | 'url' | 'audio' | 'image' | 'video' | 'file'
| Property | Type | Description |
|---|---|---|
| anchor(optional) | {
height: number,
width: number,
x: number,
y: number
} | Only for: iOS Sets the anchor point for iPad |
| dialogTitle(optional) | string | Only for: Android Web Sets share dialog title. |
| mimeType(optional) | string | Only for: Android Sets |
| UTI(optional) | string |
Represents a resolved payload, where a text was shared with the app.
Type: BaseResolvedSharePayload extended by:
| Property | Type | Description |
|---|---|---|
| contentType(optional) | 'text' | - |
Represents a resolved payload, for which the data can be accessed through a URI.
Type: BaseResolvedSharePayload extended by:
| Property | Type | Description |
|---|---|---|
| contentType | 'audio' | 'file' | 'video' | 'image' | 'website' | - |
| contentUri | string | - |
Object returned by useIncomingShare hook containing information about data shared with the app.
| Property | Type | Description |
|---|---|---|
| clearSharedPayloads | () => void | Clears payloads shared with the app. |
| error | Error | null | Contains an error encountered while resolving the shared payload. Null on success. |
| isResolving | boolean | Boolean indicating whether the current shared payloads are being resolved. |
| refreshSharePayloads | () => void | Forces a refresh of the shared payloads. |
| resolvedSharedPayloads | ResolvedSharePayload[] | Contains an array of resolved payloads shared with the app. Returns an empty array if the shared payloads are being resolved or if the resolving has failed. |
| sharedPayloads | SharePayload[] | Returns unresolved payloads shared with the app. Synchronous and available immediately after creating the hook. |
Config plugin types
Describes a configuration for data types that are possible to share in the application on iOS.
| Property | Type | Description |
|---|---|---|
| supportsAttachmentsWithMaxCount(optional) | number | Determines a maximum number of attachments that can be shared with the app.
When Default: 0 |
| supportsFileWithMaxCount(optional) | number | Determines a maximum number of files that can be shared with the app.
When Default: 0 |
| supportsImageWithMaxCount(optional) | number | Determines a maximum number of images that can be shared with the app.
When Default: 0 |
| supportsMovieWithMaxCount(optional) | number | Determines a maximum number of videos that can be shared with the app.
When Default: 0 |
| supportsText(optional) | boolean | Whether the app should accept shared text. Default: false |
| supportsWebPageWithMaxCount(optional) | number | Determines a maximum number of webpages that can be shared with the app.
When Default: 0 |
| supportsWebUrlWithMaxCount(optional) | number | Determines a maximum number of web URLs that can be shared with the app.
When Default: 0 |
| Property | Type | Description |
|---|---|---|
| action | ShareAction | - |
| category | 'android.intent.category.DEFAULT' | - |
| data | undefinedarray | - |
| filters | string[] | - |
Type: IntentFilter extended by:
| Property | Type | Description |
|---|---|---|
| action | MultiShareAction | - |
Literal Type: union
Acceptable values are: SingleShareAction | MultiShareAction
Type: IntentFilter extended by:
| Property | Type | Description |
|---|---|---|
| action | SingleShareAction | - |