跳到主要内容
新架构实战课 实操 + 基建 + 原理全维度包揽,抢先掌握 React Native 新架构精髓 立即查看 >

Linking

Linking提供了一个通用的接口来与传入和传出的 App 链接进行交互。

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

除了 https,你可能还熟悉 mailto scheme。当您打开带有 mailto scheme 的链接时,操作系统将打开已安装的邮件应用程序。同样,也有打电话和发短信的 schemes。阅读下面关于内置 URL schemes 方案的更多信息。

与使用 mailto scheme 一样,可以通过使用自定义 url scheme 链接到其他应用程序。例如,当你收到一封来自 Slack 的 Magic Link 邮件时,Launch Slack 按钮是一个 anchor 标记,带有一个 href,看起来类似与 slack://secret/magic-login/other-secret。就像 Slack 一样,你可以告诉操作系统你想要处理一个自定义 scheme。当 Slack 应用程序打开时,它会接收用于打开它的 URL。这通常被称为 Deep Links。阅读更多关于如何获得 Deep Links 到你的应用程序。

自定义 URL scheme 并不是在手机上打开应用程序的唯一方式。您不希望在电子邮件中的链接中使用自定义 URL scheme,因为这样链接在桌面上就会断开。相反,你想使用常规的 https 链接,如 https://www.myapp.io/records/1234546。在移动设备上,你希望这个链接打开你的应用程序。Android 称之为 Deep Links (Universal Links - iOS)。

内置 URL Schemes

正如在介绍中提到的,每个平台上都存在一些核心功能的 URL schemes。以下是一个非详尽的列表,但涵盖了最常用的方案。

Scheme说明iOSAndroid
mailto打开 mail app, 例如: mailto: support@expo.io
tel打开 phone app, 例如: tel:+123456789
sms打开 SMS app, 例如: sms:+123456789
https / http打开 web browser app, 例如: https://expo.io

基本用法

如果你想在你的应用程序中启用 Deep Links,请遵循以下指南:

要了解更多如何在 Android 上支持深度链接的说明,请参阅Enabling Deep Links for App Content - Add Intent Filters for Your Deep Links.

如果要在现有的 MainActivity 中监听传入的 intent,那么需要在AndroidManifest.xml中将 MainActivity 的launchMode设置为singleTask。相关解释可参考<activity>文档。

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

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

1. 如果应用程序已经打开,应用程序就会出现在前台,并触发一个链接 'url' 事件

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

如果应用程序还没有打开,它就会被打开,并将 url 作为 initialURL 传入

你可以用 Linking.getInitialURL() 来处理这些事件——它会返回一个解析到 URL 的 Promise (如果有的话)。


示例

Open Custom Settings

发送 Intents (Android)

文档

方法

addEventListener()

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

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


canOpenURL()

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

判断设备上是否有已经安装的应用可以处理指定的 URL。

本方法会返回一个Promise对象。当确定传入的 URL 可以被处理时,promise 就会返回,值的第一个参数是表示是否可以打开 URL。

The Promise will reject on Android if it was impossible to check if the URL can be opened or when targetting Android 11 (SDK 30) if you didn't specify the relevant intent queries in AndroidManifest.xml. Similarly on iOS, the promise will reject if you didn't add the specific scheme in the LSApplicationQueriesSchemes key inside Info.plist (see bellow). 如果无法检查 URL 是否可以打开,或者当目标为 Android 11 (SDK 30) 平台且您没有在 AndroidManifest.xml 中指定相关的 intent queries,则 Promise 将在 Android 上拒绝。类似地,在 iOS 上,如果你没有在 Info.plist 中的 LSApplicationQueriesSchemes 键中添加特定的 scheme,Promise 将被拒绝(见下文)。

Parameters:

NameTypeDescription
url
Required
stringThe URL to open.

对于 web 链接来说,协议头("http://", "https://")不能省略!

This method has limitations on iOS 9+. From the official Apple documentation:

  • If your app is linked against an earlier version of iOS but is running in iOS 9.0 or later, you can call this method up to 50 times. After reaching that limit, subsequent calls always resolve to false. If the user reinstalls or upgrades the app, iOS resets the limit.

对于 iOS 9 来说,你需要在Info.plist中添加LSApplicationQueriesSchemes字段,否则canOpenURL可能一直返回 false。

When targeting Android 11 (SDK 30) you must specify the intents for the schemes you want to handle in AndroidManifest.xml. A list of common intents can be found here.

For example to handle https schemes the following needs to be added to your manifest:

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

getInitialURL()

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

If the app launch was triggered by an app link, it will give the link url, otherwise it will give null.

To support deep linking on Android, refer https://developer.android.com/training/app-indexing/deep-linking.html#handling-intents

getInitialURL may return null while debugging is enabled. Disable the debugger to ensure it gets passed.


openSettings()

static openSettings(): Promise<void>;

Open the Settings app and displays the app’s custom settings, if it has any.


openURL()

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

Try to open the given url with any of the installed apps.

You can use other URLs, like a location (e.g. "geo:37.484847,-122.148386" on Android or "https://maps.apple.com/?ll=37.484847,-122.148386" on iOS), a contact, or any other URL that can be opened with the installed apps.

The method returns a Promise object. If the user confirms the open dialog or the url automatically opens, the promise is resolved. If the user cancels the open dialog or there are no registered applications for the url, the promise is rejected.

Parameters:

NameTypeDescription
url
Required
stringThe URL to open.

This method will fail if the system doesn't know how to open the specified URL. If you're passing in a non-http(s) URL, it's best to check canOpenURL() first.

For web URLs, the protocol ("http://", "https://") must be set accordingly!

This method may behave differently in a simulator e.g. "tel:" links are not able to be handled in the iOS simulator as there's no access to the dialer app.


sendIntent()
Android

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

启动 Android intent 时携带 extras。

Parameters:

NameType
action
Required
string
extrasArray<{key: string, value: string | number | boolean}>