一、预备知识:DeepLink与AppLink
在介绍接入方式前,我们先补充一些背景信息。
接力是一个“会话状态”(如Activity)从A设备流转迁移到B设备的过程。针对B设备如何打开页面以接续该“会话”,我们支持了两种打开页面的方式:
- DeepLink:URI格式,可以自定义scheme、host、path和query。举例如下:
<activity android:name="你的activity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="demo"
android:host="www.example.com"
android:path="/main" />
</intent-filter>
</activity>
- AppLink:Google在Android 6.0中提出了一种功能,可以视为对Deep Link的增强版本。该功能要求使用
https
协议。当对应的应用已安装时,可以直接打开应用内的页面;若应用未安装,则可以通过浏览器打开一个Web网页。在小米系统内部,会对应用进行签名校验,以防止页面被拦截等安全问题。举例如下:
<activity android:name="你的activity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https"
android:host="www.example.com"
android:path="/main" />
</intent-filter>
</activity>
DeepLink与AppLink的使用对比
接力方式 | 适用的接力场景 |
DeepLink接力 | 适用于设备间的原生应用接力,并且可以传递较为复杂的数据 |
AppLink接力 | 适用于具有Web版本的应用接力。当设备上安装了原生应用时,将打开原生应用页面;若未安装,则会打开Web网页。此外,该功能仅支持通过URI查询传递简单数据。 |
二、应用接力流程图

三、配置DeepLink与AppLink
对于应用接入方,需要在 AndroidManifest.xml
文件中配置 DeepLink 或 AppLink,以便实现接力跳转功能。
注意:目前通过应用接力启动Activity时,启动action为android.intent.action.VIEW
,需要被启动的Activity在manifest文件中配置<intent-filter>
并添加<action android:name="android.intent.action.VIEW" />
四、配置安全校验签名
应用签名作为接力过程中的安全校验数据,即下图中的S1、S2、S3、S4。
应用接力服务利用 Android 原生 API 在双端上分别获取对应应用的签名 S2 和 S3,应用内也分别配置可信任的应用签名S1、S4。最终,系统会对这双端的签名数据进行跨端交叉验证,以此确保整个流程的安全性和可控性。详见下图:

1、查看自身应用签名
配置安全校验签名时请使用sha1
1.1 下载SignShow APP
名称:SignShow.apk
地址:https://kpan.mioffice.cn/webfolder/ext/eIQB%23XQdyWw%40?n=0.8310264942119145
密码:22ww
1.2 授予“读取应用列表”权限:长按应用图标,点击“应用信息”,点击“权限管理”,点击“获取应用列表”,选择“始终允许”
1.3 在SignShow APP中输入要查询的APP包名
1.4 查看结果在 APP 界面中,将展示该应用的签名信息。用户可以通过点击相应选项将签名信息复制到剪贴板,并且该签名信息也会同步输出至 Logcat 中以便于调试和记录。

2、创建签名配置文件
- 在应用的资源目录中新建以下文件:xml/handoff_signature.xml (具体文件名可自定义)
- 按照以下格式配置改文件,其中[PACKAGE_NAME]部分替换为应用包名,[SIGNATURE_VALUE]部分替换为安全校验签名
请注意:在配置签名时,务必确保签名中的所有字母均为大写。若使用小写字母,则会导致签名验证失败,进而影响正常的接力流程。
<?xml version="1.0" encoding="utf-8"?>
<handoff-app>
<item deviceTypes="phone" packageName="[PACKAGE_NAME]" signature="[SIGNATURE_VALUE]"/>
<item deviceTypes="pad" packageName="[PACKAGE_NAME]" signature="[SIGNATURE_VALUE]">
<item deviceTypes="pc" packageName="[PACKAGE_NAME]" signature="[SIGNATURE_VALUE]"/>
</handoff-app>
3、添加签名配置
在应用的AndroidManifest.xml
中,在com.xiaomi.dist.handoff.sdk.HandoffClientService下配置相应的meta-data,添加对应的签名xml文件。如:
<service android:name="com.xiaomi.dist.handoff.sdk.HandoffClientService">
<meta-data
android:name="com.xiaomi.dist.handoff.metadata.SECURITY_CONFIG"
android:resource="@xml/handoff_signature" />
</service>
五、发布接力请求
如需发布应用接力请求,请按照以下步骤在 Activity 的 onCreate()
方法中进行操作:
- 设置对应的 DeepLink 或 AppLink。
- 发布一个接力请求。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handoff);
Handoff.from(this)
.setDeepLink(() -> mDeepLinkUri) //设置DeepLink
.build()
.publish(mHandoffCallback);
}
设置DeepLink或AppLink的方法共有三种:
setDeepLink(Supplier<Uri> DeepLink)
setDeepLink(Supplier<Uri> DeepLink, DeepLinkCallback cb)
setAppLink(Supplier<Uri> AppLink)
注意:
- 仅需设置其中之一即可满足需求,当然也可以同时设置两者。
- 方法 1 和方法 2 的区别在于,方法 2 可以通过
DeepLinkCallback cb
回调接口传递额外的数据。
更多关于这些方法的详细信息,请参考API文档中的“三、HandoffSession接力会话”部分。
注意事项:
1. 动态变更链接:
- 发布接力请求后,如果需要动态更改 DeepLink 或 AppLink,只需修改之前通过
setDeepLink
或setAppLink
方法设置的Supplier
中的返回值即可。 - 重要提示: 不要在同一个
Activity
中重复发布接力请求。
2. 确保链接有效性:
- 如果应用支持 DeepLink 或 AppLink 接力功能,务必保证在任意时刻获取到的 DeepLink 或 AppLink 的 Uri 返回值都不为空。否则,可能会导致接力失败。
3. 兼容性限制:
- 请注意,此 SDK 仅在 HyperOS 设备上有效。如果您的应用安装在 MIUI 14 及以下版本的设备上,则该功能将不会起作用。
当发布接力请求后,您需要确保在 Activity
的 onNewIntent()
方法中每次都调用以下代码来处理新的意图(Intent):
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// 将intent信息传递给接力会话,用于与会话建立联系。
mHandoffSession.onNewIntent(intent);
}
六、处理接力回调
接力机制回调接口详解:
1、DeepLinkCallback
- 用途:此回调用于处理在接力过程中涉及到的数据传递。当应用需要从一个设备传递数据到另一个设备时,会触发此回调。
- 调用场景:通常在用户从一个终端切换到另一个终端继续操作同一任务时触发。
- 示例代码:
private final DeepLinkCallback mDeepLinkCallback = new DeepLinkCallback() {
@Override
public byte[] onSaveState() {
//返回需要传输的数据
}
@Override
public void onRestoreState(byte[] stateData) {
//收到对端传输的数据
}
};
2、HandoffCallback
- 用途:此接口用于监听接力过程的状态变化,包括成功完成接力或者发生错误时的通知。
- 调用场景:在接力请求发送成功或遇到任何问题时会被调用。
- 示例代码:
private final HandoffCallback mHandoffCallback = new HandoffCallback() {
@Override
public void onHandoffDone() {
//接力完成
}
@Override
public void onError(int code, String msg) {
//出现错误
}
};