添加深度链接支持
深度链接 将用户引导至应用内的特定内容。当用户在已安装您的应用的设备上点击深度链接时,应用会直接打开预期的内容,例如产品页面或特定体验。
Singular 跟踪链接同时支持标准深度链接(用于已安装的应用)和延迟深度链接(用于新安装)。如需详细信息,请参阅 深度链接 FAQ 和 Singular Links FAQ 。
要求
前提条件
完成 Singular Links 前提条件 以为您的应用启用深度链接。
实现 Singular Links 处理程序
SingularLinkHandler 提供了一种回调机制,用于在应用打开时从 Singular 跟踪链接中检索深度链接、延迟深度链接和 passthrough 参数。
可用参数:
- 深度链接 (_dl): 点击链接的用户在您应用内的目标 URL
- 延迟深度链接 (_ddl): 点击链接后安装应用的用户的目标 URL
- Passthrough (_p): 通过跟踪链接传递的自定义数据,用于提供额外的上下文
SDK 配置
配置 AndroidManifest
在 SDK 能够解析深度链接之前,您的 activity 必须声明一个 intent 过滤器,以便 Android 将传入的
ACTION_VIEW
intent 路由到该 activity。在
AndroidManifest.xml
中将该过滤器添加到 launcher activity(或应接收深度链接的任意 activity),并替换为您自己的 scheme 和 host。
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Custom URI scheme deep link -->
<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="yourapp" />
</intent-filter>
<!-- HTTPS Singular Link (replace with your branded subdomain) -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="yourcompany.sng.link" />
<data android:pathPrefix="/A"/>
<data android:pathPrefix="/B"/>
<data android:pathPrefix="/E"/>
<data android:pathPrefix="/F"/>
</intent-filter>
</activity>
如果没有这些 intent 过滤器,操作系统不会将深度链接 intent 传递给您的 activity,
SingularLinkHandler
回调也不会触发。带有
android:autoVerify="true"
的 HTTPS scheme 的 App Links 还需要在目标域名上托管一个
/.well-known/assetlinks.json
文件。
将 SingularLinkHandler 添加到 Config
在 SDK 初始化期间配置 SingularLinkHandler,以处理传入的深度链接和延迟深度链接数据。
private fun initSingularSDK() {
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
.withSingularLink(intent) { params ->
val deeplink = params.deeplink
val passthrough = params.passthrough
val isDeferred = params.isDeferred
Log.d("SingularLink", "Deeplink: ${deeplink ?: "null"}")
Log.d("SingularLink", "Passthrough: ${passthrough ?: "null"}")
Log.d("SingularLink", "Is Deferred: $isDeferred")
// Handle deep link routing
deeplink?.let { url ->
handleDeepLink(url, isDeferred)
}
}
try {
Singular.init(applicationContext, config)
Log.d("Singular", "SDK initialized successfully")
} catch (e: Exception) {
Log.e("Singular", "SDK initialization failed: ${e.message}")
}
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
// Configure onNewIntent to handle Warm start deeplinks
intent?.let {
setIntent(intent)
initSingularSDK()
}
}
private void initSingularSDK() {
SingularConfig config = new SingularConfig("SDK_KEY", "SDK_SECRET")
.withSingularLink(getIntent(), new SingularLinkHandler() {
@Override
public void onResolved(SingularLinkParams params) {
String deeplink = params.getDeeplink();
String passthrough = params.getPassthrough();
boolean isDeferred = params.isDeferred();
Log.d("SingularLink", "Deeplink: " + (deeplink != null ? deeplink : "null"));
Log.d("SingularLink", "Passthrough: " + (passthrough != null ? passthrough : "null"));
Log.d("SingularLink", "Is Deferred: " + isDeferred);
// Handle deep link routing
if (deeplink != null) {
handleDeepLink(deeplink, isDeferred);
}
}
});
try {
Singular.init(getApplicationContext(), config);
Log.d("Singular", "SDK initialized successfully");
} catch (Exception e) {
Log.e("Singular", "SDK initialization failed: " + e.getMessage());
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// Configure onNewIntent to handle Warm start deeplinks
if (intent != null) {
setIntent(intent);
initSingularSDK();
}
}
注意: SingularLinkHandler 仅在应用通过 Singular Link 打开时触发。如需更多信息,请参阅 Singular Links FAQ 。
withSingularLink
在调用时未提供
shortlinkTimeoutSec
参数时,默认使用 10 秒的短链接解析超时。若要覆盖此设置,请使用三参数重载
withSingularLink(Intent intent, SingularLinkHandler handler, long shortlinkTimeoutSec)
。当 intent 的操作为
ACTION_VIEW
时,SDK 还会将该会话标记为通过深度链接打开,这会影响归因。
处理程序行为
了解 SingularLinkHandler 的执行
SingularLinkHandler 的行为根据应用是新安装还是已安装而有所不同。
新安装(延迟深度链接)
在新安装场景下,应用启动时不存在 Open URL。Singular 会完成归因,以判断跟踪链接中是否包含深度链接或延迟深度链接的值。
延迟深度链接流程:
- 用户点击一个配置了深度链接值的 Singular 跟踪链接
- 用户首次安装并打开应用
- Singular SDK 将首个会话发送到 Singular 服务器
- 归因完成,并从跟踪链接中识别出深度链接
-
深度链接值通过
deeplink参数返回到 SingularLinkHandler,并带有isDeferred = true
测试延迟深度链接:
- 从测试设备上卸载该应用(如果当前已安装)
- 在设备上重置您的 Google Advertising ID (GAID)
- 在设备上点击 Singular 跟踪链接(确保其已配置深度链接值)
- 安装并打开该应用
归因应能成功完成,并且延迟深度链接的值将被传递给 SingularLinkHandler。
Pro Tip:
在使用具有不同包名的开发版本(例如,
com.example.dev
而不是
com.example.prod
)测试深度链接时,请专门为开发应用的包名配置跟踪链接。点击测试链接后,请通过 Android Studio 或 APK 将开发版本直接安装到设备上,而不是从应用商店下载生产应用。
已安装(即时深度链接)
当应用已安装时,点击 Singular Link 会使用 Android App Links 技术立即打开应用。
即时深度链接流程:
- 用户点击一个 Singular 跟踪链接
- Android 操作系统提供一个包含完整 Singular 跟踪链接的 Open URL
- 在 SDK 初始化期间,Singular 解析 Android Intent
-
Singular 提取
deeplink和passthrough的值 -
这些值通过 SingularLinkHandler 返回,并带有
isDeferred = false
Passthrough 参数
使用 passthrough 参数从跟踪链接点击中捕获额外的数据。
如果跟踪链接中包含
passthrough (_p)
参数,则 SingularLinkHandler 的
passthrough
参数会包含相应的数据。可使用它捕获活动Meta数据、用户分群数据或您在应用中所需的任何自定义信息。
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
.withSingularLink(intent) { params ->
// Extract passthrough data
params.passthrough?.let { passthroughData ->
try {
// Parse and use custom data
val jsonData = JSONObject(passthroughData)
val campaignId = jsonData.optString("campaign_id")
val userSegment = jsonData.optString("segment")
Log.d("SingularLink", "Campaign ID: $campaignId")
Log.d("SingularLink", "User Segment: $userSegment")
} catch (e: JSONException) {
Log.e("SingularLink", "Error parsing passthrough data", e)
}
}
}
SingularConfig config = new SingularConfig("SDK_KEY", "SDK_SECRET")
.withSingularLink(getIntent(), new SingularLinkHandler() {
@Override
public void onResolved(SingularLinkParams params) {
// Extract passthrough data
String passthroughData = params.getPassthrough();
if (passthroughData != null) {
try {
// Parse and use custom data
JSONObject jsonData = new JSONObject(passthroughData);
String campaignId = jsonData.optString("campaign_id");
String userSegment = jsonData.optString("segment");
Log.d("SingularLink", "Campaign ID: " + campaignId);
Log.d("SingularLink", "User Segment: " + userSegment);
} catch (JSONException e) {
Log.e("SingularLink", "Error parsing passthrough data");
}
}
}
});
转发所有查询参数
通过附加
_forward_params=2
参数,从跟踪链接 URL 中捕获所有查询参数。
当
_forward_params=2
被添加到跟踪链接时,所有查询参数都将包含在 SingularLinkHandler 的
deeplink
参数中,使您能够访问包含所有参数的完整 URL。
跟踪链接示例:
https://yourapp.sng.link/A1b2c/abc123?_dl=myapp://product/123&_forward_params=2&utm_source=facebook&promo=SALE2024
SingularLinkHandler 将接收到:
deeplink = "myapp://product/123?utm_source=facebook&promo=SALE2024"