使用不直接提供 APK 的自定义 URL 处理延迟深度 link
Handle deferred deep link with a custom URL that does not directly provides an APK
我正在使用 Branch.io
为我的 Android 应用实施延迟深度 link
我正在处理用户单击 link 但未安装该应用程序的用例(我的 link 在安装该应用程序时已经可用)。
目前,我的应用程序未托管在 Play 商店中,而是托管在 Fabric 中。因此,我已经设置了我的深度 link 以将用户重定向到 url,例如:https://betas.to/... 这样他最终可以下载 Beta,然后下载应用程序。
不幸的是,我无法使以下用例正常工作:
-> 用户从 Android 设备(没有应用程序)点击深度 link
-> 用户访问 Fabric 网页以提供他的电子邮件进行测试
-> 用户打开 Fabric 电子邮件
-> 用户下载测试版(可选)
-> 用户下载 Beta 版应用
-> 应用程序启动,并考虑延迟深度 link
最后一步出现问题:不再考虑初始深度 link。我猜这是因为应用程序最终没有从link打开。
我能否期望此流程以某种方式起作用?如果不是,我想知道我在 Branch 仪表板中提供的 URL 是否必须 直接 指向 APK 文件。
更新 1
我刚刚意识到在测试我的延迟深度 link(在 Branch deferred deeplink testing procedure 之后)时我遇到了与分支相关的错误。仅当我在单击 link 后从 Android Studio 安装应用程序时才会发生此错误。
我觉得有什么东西阻止 Branch 正确捕获应用程序安装事件。
这是我得到的:
Rejecting re-init on previously-failed class
java.lang.Class:
java.lang.NoClassDefFoundError: Failed resolution of:
Lcom/android/installreferrer/api/InstallReferrerStateListener;
at void io.branch.referral.InstallListener.captureInstallReferrer(android.content.Context,
long, io.branch.referral.InstallListener$IInstallReferrerEvents)
(InstallListener.java:54)
at void io.branch.referral.Branch.registerAppInit(io.branch.referral.Branch$BranchReferralInitListener,
io.branch.referral.ServerRequest$PROCESS_WAIT_LOCK) (Branch.java:2318)
at void io.branch.referral.Branch.initializeSession(io.branch.referral.Branch$BranchReferralInitListener)
(Branch.java:2272)
at void io.branch.referral.Branch.initUserSessionInternal(io.branch.referral.Branch$BranchReferralInitListener,
android.app.Activity, boolean) (Branch.java:1255)
at boolean io.branch.referral.Branch.initSession(io.branch.referral.Branch$BranchReferralInitListener,
android.app.Activity) (Branch.java:917)
at boolean io.branch.referral.Branch.initSessionWithData(android.net.Uri,
android.app.Activity) (Branch.java:1037)
at void io.branch.referral.Branch.startSession(android.app.Activity)
(Branch.java:2522)
at void io.branch.referral.Branch.access00(io.branch.referral.Branch,
android.app.Activity) (Branch.java:73)
at void io.branch.referral.Branch$BranchActivityLifeCycleObserver.onActivityStarted(android.app.Activity)
(Branch.java:2458)
at void android.app.Application.dispatchActivityStarted(android.app.Activity)
(Application.java:231)
at void android.app.Activity.onStart() (Activity.java:1271)
at void android.support.v4.app.FragmentActivity.onStart() (FragmentActivity.java:564)
at void android.support.v7.app.AppCompatActivity.onStart() (AppCompatActivity.java:177)
at void com...MyActivity.onStart()
(MyActivity.java:48)
at void android.app.Instrumentation.callActivityOnStart(android.app.Activity)
(Instrumentation.java:1256)
at void android.app.Activity.performStart() (Activity.java:6972)
at android.app.Activity android.app.ActivityThread.performLaunchActivity(android.app.ActivityThread$ActivityClientRecord,
android.content.Intent) (ActivityThread.java:2937)
at void android.app.ActivityThread.handleLaunchActivity(android.app.ActivityThread$ActivityClientRecord,
android.content.Intent, java.lang.String) (ActivityThread.java:3045)
at void android.app.ActivityThread.-wrap14(android.app.ActivityThread,
android.app.ActivityThread$ActivityClientRecord,
android.content.Intent, java.lang.String) (ActivityThread.java:-1)
at void android.app.ActivityThread$H.handleMessage(android.os.Message)
(ActivityThread.java:1642)
at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:102)
at void android.os.Looper.loop() (Looper.java:154)
at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6776)
at java.lang.Object java.lang.reflect.Method.invoke!(java.lang.Object, java.lang.Object[])
(Method.java:-2)
at void com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run()
(ZygoteInit.java:1496)
at void com.android.internal.os.ZygoteInit.main(java.lang.String[])
(ZygoteInit.java:1386) Caused by: java.lang.ClassNotFoundException:
Didn't find class
"com.android.installreferrer.api.InstallReferrerStateListener" on
path: DexPathList[[zip file
"/data/app/com.myapp.debug-1/base.apk"],nativeLibraryDirectories=[/data/app/com.myapp.debug-1/lib/arm,
/data/app/com.myapp.debug-1/base.apk!/lib/armeabi-v7a,
/system/lib, /vendor/lib]]
at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String)
(BaseDexClassLoader.java:56)
at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean)
(ClassLoader.java:380)
at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String)
(ClassLoader.java:312)
at void io.branch.referral.InstallListener.captureInstallReferrer(android.content.Context,
long, io.branch.referral.InstallListener$IInstallReferrerEvents)
(InstallListener.java:54)
at void io.branch.referral.Branch.registerAppInit(io.branch.referral.Branch$BranchReferralInitListener,
io.branch.referral.ServerRequest$PROCESS_WAIT_LOCK) (Branch.java:2318)
at void io.branch.referral.Branch.initializeSession(io.branch.referral.Branch$BranchReferralInitListener)
(Branch.java:2272)
at void io.branch.referral.Branch.initUserSessionInternal(io.branch.referral.Branch$BranchReferralInitListener,
android.app.Activity, boolean) (Branch.java:1255)
at boolean io.branch.referral.Branch.initSession(io.branch.referral.Branch$BranchReferralInitListener,
android.app.Activity) (Branch.java:917)
at boolean io.branch.referral.Branch.initSessionWithData(android.net.Uri,
android.app.Activity) (Branch.java:1037)
at void io.branch.referral.Branch.startSession(android.app.Activity)
(Branch.java:2522)
at void io.branch.referral.Branch.access00(io.branch.referral.Branch,
android.app.Activity) (Branch.java:73)
at void io.branch.referral.Branch$BranchActivityLifeCycleObserver.onActivityStarted(android.app.Activity)
(Branch.java:2458)
at void android.app.Application.dispatchActivityStarted(android.app.Activity)
(Application.java:231)
at void android.app.Activity.onStart() (Activity.java:1271)
at void android.support.v4.app.FragmentActivity.onStart() (FragmentActivity.java:564)
at void android.support.v7.app.AppCompatActivity.onStart() (AppCompatActivity.java:177)
at void com.....MyActivity.onStart()
(MyActivity.java:48)
at void android.app.Instrumentation.callActivityOnStart(android.app.Activity)
(Instrumentation.java:1256)
at void android.app.Activity.performStart() (Activity.java:6972)
at android.app.Activity android.app.ActivityThread.performLaunchActivity(android.app.ActivityThread$ActivityClientRecord,
android.content.Intent) (ActivityThread.java:2937)
at void android.app.ActivityThread.handleLaunchActivity(android.app.ActivityThread$ActivityClientRecord,
android.content.Intent, java.lang.String) (ActivityThread.java:3045)
at void android.app.ActivityThread.-wrap14(android.app.ActivityThread,
android.app.ActivityThread$ActivityClientRecord,
android.content.Intent, java.lang.String) (ActivityThread.java:-1)
at void android.app.ActivityThread$H.handleMessage(android.os.Message)
(ActivityThread.java:1642)
at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:102)
at void android.os.Looper.loop() (Looper.java:154)
at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6776)
at java.lang.Object java.lang.reflect.Method.invoke!(java.lang.Object, java.lang.Object[])
(Method.java:-2)
at void com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run()
(ZygoteInit.java:1496)
at void com.android.internal.os.ZygoteInit.main(java.lang.String[])
(ZygoteInit.java:1386)
下一行是:
BranchSDK: Failed resolution of: Lcom/android/installreferrer/api/InstallReferrerClient;
这里是 Branch 的 Brian。
如果安装应用程序时常规深度 linking 有效,则延迟深度 linking 也应该有效。请确保您在 onStart 方法中初始化 Branch 并覆盖 onNewIntent:
此外,我会通过单击分支 link 并通过 Android Studio 在设备上构建应用程序来测试延迟深度 linking:
自定义URL不需要直接指向APK文件。如果您仍然 运行 遇到问题,请写信给 integrations@branch.io.
TLDR; 你应该总是在 activity :
Branch.getInstance().initSession(BranchReferralInitListener callback, @NonNull Uri data, Activity activity)
即使你有一个空 URI
自从 Branch API 用 @NonNull 注释了这个参数,我就糊涂了。
我检查了源代码并确认 Branch 正确处理了空值。当null为passed-in时,Branch会自动检测是冷启动,还是deferred deeplink.
这是相关的 piece of code from their github :
// In case of a cold start by clicking app icon or bringing app to foreground Branch link click is always false.
if (intent.getData() == null || (!isActivityCreatedAndLaunched && isIntentParamsAlreadyConsumed(activity))) {
// Considering the case of a deferred install. In this case the app behaves like a cold start but still Branch can do probabilistic match.
// So skipping instant deep link feature until first Branch open happens
if (!prefHelper_.getInstallParams().equals(PrefHelper.NO_STRING_VALUE)) {
JSONObject nonLinkClickJson = new JSONObject();
try {
nonLinkClickJson.put(Defines.Jsonkey.Clicked_Branch_Link.getKey(), false);
nonLinkClickJson.put(Defines.Jsonkey.IsFirstSession.getKey(), false);
prefHelper_.setSessionParams(nonLinkClickJson.toString());
isInstantDeepLinkPossible = true;
} catch (JSONException e) {
e.printStackTrace();
}
}
}
缺少的 class (com.android.installreferrer.InstallReferrerClient
) 是 Branch 的依赖项,但不会自动包含在内。您必须自己将其添加到您的构建中。
implementation 'com.android.installreferrer:installreferrer:1.0'
在 Branch's gradle file 中查看。
它是在 version 2.17 中添加的,但文档似乎没有跟上。
阅读提交后,此堆栈跟踪可能有点误导。该库捕获 ClassNotFound 异常并记住 class 不可用。它还有助于打印异常。
但是,install referrer package 涉及跨安装跟踪引荐来源网址,因此与您的重现步骤相符。
我正在使用 Branch.io
为我的 Android 应用实施延迟深度 link我正在处理用户单击 link 但未安装该应用程序的用例(我的 link 在安装该应用程序时已经可用)。 目前,我的应用程序未托管在 Play 商店中,而是托管在 Fabric 中。因此,我已经设置了我的深度 link 以将用户重定向到 url,例如:https://betas.to/... 这样他最终可以下载 Beta,然后下载应用程序。
不幸的是,我无法使以下用例正常工作:
-> 用户从 Android 设备(没有应用程序)点击深度 link
-> 用户访问 Fabric 网页以提供他的电子邮件进行测试
-> 用户打开 Fabric 电子邮件
-> 用户下载测试版(可选)
-> 用户下载 Beta 版应用
-> 应用程序启动,并考虑延迟深度 link
最后一步出现问题:不再考虑初始深度 link。我猜这是因为应用程序最终没有从link打开。
我能否期望此流程以某种方式起作用?如果不是,我想知道我在 Branch 仪表板中提供的 URL 是否必须 直接 指向 APK 文件。
更新 1
我刚刚意识到在测试我的延迟深度 link(在 Branch deferred deeplink testing procedure 之后)时我遇到了与分支相关的错误。仅当我在单击 link 后从 Android Studio 安装应用程序时才会发生此错误。 我觉得有什么东西阻止 Branch 正确捕获应用程序安装事件。
这是我得到的:
Rejecting re-init on previously-failed class java.lang.Class: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/android/installreferrer/api/InstallReferrerStateListener; at void io.branch.referral.InstallListener.captureInstallReferrer(android.content.Context, long, io.branch.referral.InstallListener$IInstallReferrerEvents) (InstallListener.java:54) at void io.branch.referral.Branch.registerAppInit(io.branch.referral.Branch$BranchReferralInitListener, io.branch.referral.ServerRequest$PROCESS_WAIT_LOCK) (Branch.java:2318) at void io.branch.referral.Branch.initializeSession(io.branch.referral.Branch$BranchReferralInitListener) (Branch.java:2272) at void io.branch.referral.Branch.initUserSessionInternal(io.branch.referral.Branch$BranchReferralInitListener, android.app.Activity, boolean) (Branch.java:1255) at boolean io.branch.referral.Branch.initSession(io.branch.referral.Branch$BranchReferralInitListener, android.app.Activity) (Branch.java:917) at boolean io.branch.referral.Branch.initSessionWithData(android.net.Uri, android.app.Activity) (Branch.java:1037) at void io.branch.referral.Branch.startSession(android.app.Activity) (Branch.java:2522) at void io.branch.referral.Branch.access00(io.branch.referral.Branch, android.app.Activity) (Branch.java:73) at void io.branch.referral.Branch$BranchActivityLifeCycleObserver.onActivityStarted(android.app.Activity) (Branch.java:2458) at void android.app.Application.dispatchActivityStarted(android.app.Activity) (Application.java:231) at void android.app.Activity.onStart() (Activity.java:1271) at void android.support.v4.app.FragmentActivity.onStart() (FragmentActivity.java:564) at void android.support.v7.app.AppCompatActivity.onStart() (AppCompatActivity.java:177) at void com...MyActivity.onStart() (MyActivity.java:48) at void android.app.Instrumentation.callActivityOnStart(android.app.Activity) (Instrumentation.java:1256) at void android.app.Activity.performStart() (Activity.java:6972) at android.app.Activity android.app.ActivityThread.performLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent) (ActivityThread.java:2937) at void android.app.ActivityThread.handleLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:3045) at void android.app.ActivityThread.-wrap14(android.app.ActivityThread, android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:-1) at void android.app.ActivityThread$H.handleMessage(android.os.Message) (ActivityThread.java:1642) at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:102) at void android.os.Looper.loop() (Looper.java:154) at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6776) at java.lang.Object java.lang.reflect.Method.invoke!(java.lang.Object, java.lang.Object[]) (Method.java:-2) at void com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run() (ZygoteInit.java:1496) at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:1386) Caused by: java.lang.ClassNotFoundException: Didn't find class "com.android.installreferrer.api.InstallReferrerStateListener" on path: DexPathList[[zip file "/data/app/com.myapp.debug-1/base.apk"],nativeLibraryDirectories=[/data/app/com.myapp.debug-1/lib/arm, /data/app/com.myapp.debug-1/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib]] at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:56) at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:380) at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312) at void io.branch.referral.InstallListener.captureInstallReferrer(android.content.Context, long, io.branch.referral.InstallListener$IInstallReferrerEvents) (InstallListener.java:54) at void io.branch.referral.Branch.registerAppInit(io.branch.referral.Branch$BranchReferralInitListener, io.branch.referral.ServerRequest$PROCESS_WAIT_LOCK) (Branch.java:2318) at void io.branch.referral.Branch.initializeSession(io.branch.referral.Branch$BranchReferralInitListener) (Branch.java:2272) at void io.branch.referral.Branch.initUserSessionInternal(io.branch.referral.Branch$BranchReferralInitListener, android.app.Activity, boolean) (Branch.java:1255) at boolean io.branch.referral.Branch.initSession(io.branch.referral.Branch$BranchReferralInitListener, android.app.Activity) (Branch.java:917) at boolean io.branch.referral.Branch.initSessionWithData(android.net.Uri, android.app.Activity) (Branch.java:1037) at void io.branch.referral.Branch.startSession(android.app.Activity) (Branch.java:2522) at void io.branch.referral.Branch.access00(io.branch.referral.Branch, android.app.Activity) (Branch.java:73) at void io.branch.referral.Branch$BranchActivityLifeCycleObserver.onActivityStarted(android.app.Activity) (Branch.java:2458) at void android.app.Application.dispatchActivityStarted(android.app.Activity) (Application.java:231) at void android.app.Activity.onStart() (Activity.java:1271) at void android.support.v4.app.FragmentActivity.onStart() (FragmentActivity.java:564) at void android.support.v7.app.AppCompatActivity.onStart() (AppCompatActivity.java:177) at void com.....MyActivity.onStart() (MyActivity.java:48) at void android.app.Instrumentation.callActivityOnStart(android.app.Activity) (Instrumentation.java:1256) at void android.app.Activity.performStart() (Activity.java:6972) at android.app.Activity android.app.ActivityThread.performLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent) (ActivityThread.java:2937) at void android.app.ActivityThread.handleLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:3045) at void android.app.ActivityThread.-wrap14(android.app.ActivityThread, android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:-1) at void android.app.ActivityThread$H.handleMessage(android.os.Message) (ActivityThread.java:1642) at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:102) at void android.os.Looper.loop() (Looper.java:154) at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6776) at java.lang.Object java.lang.reflect.Method.invoke!(java.lang.Object, java.lang.Object[]) (Method.java:-2) at void com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run() (ZygoteInit.java:1496) at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:1386)
下一行是:
BranchSDK: Failed resolution of: Lcom/android/installreferrer/api/InstallReferrerClient;
这里是 Branch 的 Brian。
如果安装应用程序时常规深度 linking 有效,则延迟深度 linking 也应该有效。请确保您在 onStart 方法中初始化 Branch 并覆盖 onNewIntent:
此外,我会通过单击分支 link 并通过 Android Studio 在设备上构建应用程序来测试延迟深度 linking:
自定义URL不需要直接指向APK文件。如果您仍然 运行 遇到问题,请写信给 integrations@branch.io.
TLDR; 你应该总是在 activity :
Branch.getInstance().initSession(BranchReferralInitListener callback, @NonNull Uri data, Activity activity)
即使你有一个空 URI
自从 Branch API 用 @NonNull 注释了这个参数,我就糊涂了。
我检查了源代码并确认 Branch 正确处理了空值。当null为passed-in时,Branch会自动检测是冷启动,还是deferred deeplink.
这是相关的 piece of code from their github :
// In case of a cold start by clicking app icon or bringing app to foreground Branch link click is always false.
if (intent.getData() == null || (!isActivityCreatedAndLaunched && isIntentParamsAlreadyConsumed(activity))) {
// Considering the case of a deferred install. In this case the app behaves like a cold start but still Branch can do probabilistic match.
// So skipping instant deep link feature until first Branch open happens
if (!prefHelper_.getInstallParams().equals(PrefHelper.NO_STRING_VALUE)) {
JSONObject nonLinkClickJson = new JSONObject();
try {
nonLinkClickJson.put(Defines.Jsonkey.Clicked_Branch_Link.getKey(), false);
nonLinkClickJson.put(Defines.Jsonkey.IsFirstSession.getKey(), false);
prefHelper_.setSessionParams(nonLinkClickJson.toString());
isInstantDeepLinkPossible = true;
} catch (JSONException e) {
e.printStackTrace();
}
}
}
缺少的 class (com.android.installreferrer.InstallReferrerClient
) 是 Branch 的依赖项,但不会自动包含在内。您必须自己将其添加到您的构建中。
implementation 'com.android.installreferrer:installreferrer:1.0'
在 Branch's gradle file 中查看。
它是在 version 2.17 中添加的,但文档似乎没有跟上。
阅读提交后,此堆栈跟踪可能有点误导。该库捕获 ClassNotFound 异常并记住 class 不可用。它还有助于打印异常。
但是,install referrer package 涉及跨安装跟踪引荐来源网址,因此与您的重现步骤相符。