跳至主内容

Linking

Linking 提供了一个通用接口,用于处理传入和传出应用程序链接。

每个链接 (URL) 都有一个 URL Scheme(URL 方案),有些网站以 https://http:// 为前缀,其中 http 就是 URL Scheme。我们简称它为 scheme。

除了 https,您可能还熟悉 mailto scheme。当您使用 mailto scheme 打开链接时,您的操作系统会打开一个已安装的邮件应用程序。类似地,还有用于拨打电话和发送短信的 schemes。在下面阅读更多关于内置 URL schemes 的信息。

与使用 mailto scheme 类似,您可以通过使用自定义 URL scheme 来链接到其他应用程序。例如,当您收到 Slack 的魔术链接电子邮件时,启动 Slack 按钮是一个带有 href 的锚标签,其内容类似于:slack://secret/magic-login/other-secret。就像 Slack 一样,您可以告诉操作系统您希望处理一个自定义 scheme。当 Slack 应用程序打开时,它会接收到用于打开它的 URL。这通常被称为深度链接。阅读更多关于如何获取深度链接到您的应用程序的信息。

自定义 URL scheme 并不是在移动设备上打开应用程序的唯一方式。例如,如果您想通过电子邮件发送一个要在移动设备上打开的链接,使用自定义 URL scheme 并不理想,因为用户可能在桌面设备上打开电子邮件,而链接将无法工作。相反,您应该使用标准的 https 链接,例如 https://www.myapp.io/records/1234546。在移动设备上,这些链接可以配置为打开您的应用程序。在 Android 上,此功能称为深度链接,而在 iOS 上,它被称为通用链接

内置 URL Schemes

如简介所述,每个平台都存在一些用于核心功能的 URL scheme。以下是一个非详尽的列表,但涵盖了最常用的 schemes。

Scheme描述iOSAndroid
mailto打开邮件应用程序,例如:mailto: support@expo.io
tel打开电话应用程序,例如:tel:+123456789
sms打开短信应用程序,例如:sms:+123456789
https / http打开网页浏览器应用程序,例如:https://expo.io

如果您想在应用程序中启用深度链接,请阅读以下指南

有关如何在 Android 上添加深度链接支持的说明,请参阅启用应用程序内容的深度链接 - 为您的深度链接添加 Intent 过滤器

如果您希望在 MainActivity 的现有实例中接收 intent,您可以在 AndroidManifest.xml 中将 MainActivity 的 launchMode 设置为 singleTask。请参阅<activity> 文档了解更多信息。

xml
<activity
android:name=".MainActivity"
android:launchMode="singleTask">

有两种方法可以处理打开您应用程序的 URL。

1. 如果应用程序已打开,应用程序将置于前台并触发 Linking 'url' 事件

您可以使用 Linking.addEventListener('url', callback) 来处理这些事件 - 它会以链接的 URL 调用 callback({url})

2. 如果应用程序未打开,它将打开并将 URL 作为 initialURL 传入

您可以使用 Linking.getInitialURL() 处理这些事件 - 它返回一个 Promise,如果存在 URL,则解析为该 URL。


示例

打开自定义设置

发送 Intent(Android)

参考

方法

addEventListener()

tsx
static addEventListener(
type: 'url',
handler: (event: {url: string}) => void,
): EmitterSubscription;

通过监听 url 事件类型并提供处理程序,为 Linking 更改添加处理程序。


canOpenURL()

tsx
static canOpenURL(url: string): Promise<boolean>;

确定已安装的应用程序是否可以处理给定的 URL。

该方法返回一个 Promise 对象。当确定是否可以处理给定 URL 时,该 Promise 会被解析,并且第一个参数表示是否可以打开它。

在 Android 上,如果无法检查 URL 是否可以打开,或者当目标为 Android 11 (SDK 30) 且您未在 AndroidManifest.xml 中指定相关的 intent 查询时,Promise 将被拒绝。类似地,在 iOS 上,如果您未在 Info.plist 中的 LSApplicationQueriesSchemes 键中添加特定 scheme,该 Promise 将被拒绝(参见下文)。

参数

名称类型描述
url
必需
string要打开的 URL。

对于网页 URL,协议 ("http://", "https://") 必须相应设置!

此方法在 iOS 9+ 上有局限性。根据官方 Apple 文档

  • 如果您的应用程序链接到早期版本的 iOS 但在 iOS 9.0 或更高版本中运行,您可以调用此方法最多 50 次。达到此限制后,后续调用始终解析为 false。如果用户重新安装或升级应用程序,iOS 会重置此限制。

从 iOS 9 开始,您的应用程序还需要在 Info.plist 中提供 LSApplicationQueriesSchemes 键,否则 canOpenURL() 将始终解析为 false

当目标为 Android 11 (SDK 30) 时,您必须在 AndroidManifest.xml 中指定要处理的 schemes 的 intent。常见 intent 列表可以在此处找到。

例如,为了处理 https scheme,需要将以下内容添加到您的清单中

<manifest ...>
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https"/>
</intent>
</queries>
</manifest>

getInitialURL()

tsx
static getInitialURL(): Promise<string | null>;

如果应用程序启动是由应用程序链接触发的,它将提供链接 URL,否则将返回 null

为了支持 Android 上的深度链接,请参考https://developer.android.com.cn/training/app-indexing/deep-linking.html#handling-intents

当远程 JS 调试处于活动状态时,getInitialURL 可能会返回 null。禁用调试器以确保其被传递。


openSettings()

tsx
static openSettings(): Promise<void>;

打开“设置”应用程序并显示应用程序的自定义设置(如果有)。


openURL()

tsx
static openURL(url: string): Promise<any>;

尝试使用任何已安装的应用程序打开给定的 url

您可以使用其他 URL,例如位置(例如 Android 上的“geo:37.484847,-122.148386”或 iOS 上的“https://maps.apple.com/?ll=37.484847,-122.148386”)、联系人,或任何其他可以使用已安装应用程序打开的 URL。

该方法返回一个 Promise 对象。如果用户确认打开对话框或 URL 自动打开,则 Promise 会被解析。如果用户取消打开对话框或没有为该 URL 注册的应用程序,则 Promise 会被拒绝。

参数

名称类型描述
url
必需
string要打开的 URL。

如果系统不知道如何打开指定的 URL,此方法将失败。如果您传入的是非 http(s) URL,最好先检查 canOpenURL()

对于网页 URL,协议 ("http://", "https://") 必须相应设置!

此方法在模拟器中的行为可能不同,例如 iOS 模拟器无法处理 "tel:" 链接,因为它无法访问拨号应用程序。


sendIntent()
Android

tsx
static sendIntent(
action: string,
extras?: Array<{key: string; value: string | number | boolean}>,
): Promise<void>;

启动带 extra 参数的 Android intent。

参数

名称类型
action
必需
string
extrasArray<{key: string, value: string | number | boolean}>