应用无法处理Deep Link时如何优雅地回到网站 [英] How to gracefully fall back to website when Deep Link can't be handled by app

查看:91
本文介绍了应用无法处理Deep Link时如何优雅地回到网站的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况:


  1. 您拥有一个广泛的移动网站,m.somewhere.com

  2. 在Google Play上,您有一个Android应用程序,该应用程序复制了m.somewhere.com的主要功能,但不是全部。

  3. 您的客户/雇主/投资者要求您为应用可以处理的网址实施深层链接。

TL; DR-您如何

TL;DR - how do you implement this?

到目前为止我的方法:

第一个本能:仅匹配某些网址并为其启动。问题:AndroidManifest意向过滤器中缺乏表达阻止了此操作(例如 http://weiyang.wordpress.ncsu.edu/2013/04/11/a-limitation-in-intent-filter-of-android-application/

First instinct: match only certain urls and launch for them. Problem: paucity of expression in the AndroidManifest intent-filter prevents this (e.g. http://weiyang.wordpress.ncsu.edu/2013/04/11/a-limitation-in-intent-filter-of-android-application/).

作为问题的一部分,假设位于m.somewhere.com的服务器知道任何以数字结尾的url都会到达网站上的某个页面,并且营销人员一直在与seo交往,所以例如

As a subset of the problem, suppose the server at m.somewhere.com knows that any url that ends in a number goes to a certain page on the site, and the marketing guys are constantly futzing with the seo, so e.g.

我要针对以下应用启动该应用程序:

I want to launch the app for:

http://m.somewhere.com/find/abc-12345
https://m.somewhere.com/shop/xyz-45678928492

但不是

http://m.somewhere.com/find/abc-12345-xyz
https://m.somewhere.com/about-us

没有路径,pathPrefix或pathPattern的组合将解决此问题。

no combination of path, pathPrefix, or pathPattern will handle this.

最佳做法n stackoverflow(将URI与< data>就像http://example.com/AndroidManifest中的某事)似乎要捕获所有内容,然后处理onCreate()的情况并意识到您不应该处理此特定网址:

Best practice on stackoverflow (Match URIs with <data> like http://example.com/something in AndroidManifest) seems to be to catch everything, and then handle the situation when you get to onCreate() and realize you shouldn't have handled this particular url:

Android清单:

Android Manifest:

...
<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="http"
          android:host="m.somewhere.com"
          android:pathPattern=".*"/>
</intent-filter>
...    

Activity onCreate():

Activity onCreate():

Intent i = getIntent()
String action = i.getAction();
Uri uri = i.getData();
if (Intent.ACTION_VIEW.equals(action) && cantHandleUrl(uri)) {
    // TODO - fallback to browser.
}

我已经编写了与上述类似的程序,但它导致一个非常糟糕的最终用户体验:

I have programmed something similar to the above that is working, but it leads to a very bad end-user experience:


  1. 在浏览m.somewhere.com时,每次点击URL都会打h在应用启动后又回退。

  2. 有一个令人讨厌的习惯,即选择器屏幕会弹出并点击m.somewhere.com上的每个链接,询问用户他们选择了哪个想要使用(并且Android应用程序与浏览器一起列出,但是单击Android App只会再次启动选择器屏幕)。如果我不小心,我的应用程序将陷入无限重启的循环中(如果用户选择始终),即使我不小心,用户也似乎忽略了他们的始终选择。

能做什么?

(编辑:在WebView中显示网站在应用程序中无法处理未处理的页面)。

( Displaying the site in a WebView in the app for unhandled pages is NOT an option).

推荐答案

最新答案,但对以后的读者:如果您支持至少 API级别15 ,然后有一种更直接的(减少黑客攻击)的方式,可以通过浏览器查找您不想使用的URL,而无需禁用/重新启用URL

Late answer, but for future readers: if you're supporting a minimum of API level 15 then there's a more direct (less hacky) way of falling back to a browser for URLs you realize you don't want to handle, without resorting to disabling/re-enabling URL catching components.

nbarraille的答案是有创意的,可能是您唯一的选项,如果您需要支持低于15的API,但如果不需要,则可以使用 Intent.makeMainSelectorActivity() 直接启动用户的默认值浏览器,可绕过Android的 ResolverActivity 应用程序选择对话框。

nbarraille's answer is creative and possibly your only option if you need to support APIs lower than 15, but if you don't then you can make use of Intent.makeMainSelectorActivity() to directly launch the user's default browser, allowing you to bypass Android's ResolverActivity app selection dialog.

因此,无需像这样典型地重新广播URL Intent:

So instead of re-broadcasting the URL Intent the typical way like this:

// The URL your Activity intercepted
String data = "example.com/someurl"
Intent webIntent = new Intent(Intent.ACTION_VIEW, data);
webIntent.addCategory(Intent.CATEGORY_BROWSABLE);
startActivity(webIntent);



执行此操作



您将广播此内容代替意图:

Do this

You would broadcast this Intent instead:

Intent defaultBrowser = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, Intent.CATEGORY_APP_BROWSER);
defaultBrowser.setData(data);
startActivity(defaultBrowser);

这将告诉Android加载浏览器应用程序和数据网址。即使安装了多个浏览器应用程序,这也应绕过选择器对话框。而且,没有选择器对话框,您不必担心应用程序陷入拦截/重新广播同一Intent的无限循环。

This will tell Android to load the browser app and data URL. This should bypass the chooser dialog even if they have more than one browser app installed. And without the chooser dialog you don't have to worry about the app falling into an infinite loop of intercepting/re-broadcasting the same Intent.

您必须可以在用户的​​浏览器中打开URL(您不想处理的URL)。如果您还想给其他非浏览器应用程序打开链接的机会,则此解决方案将不起作用,因为没有选择器对话框。

You have to be okay with opening the URL (the one you didn't want to handle) in the user's browser. If you wanted to give other non-browser apps a chance to open the link as well, this solution wouldn't work since there is no chooser dialog.

据我所知,使用此解决方案的唯一怪癖是,当用户单击您的深层链接之一时,他们将选择在应用程序中打开或他们的浏览器等。当他们选择您的应用并且您的内部应用逻辑意识到它是一个不想拦截的URL时,就会立即向用户显示浏览器。因此,他们选择了您的应用,但显示了浏览器。

As far as I can tell, the only quirk from using this solution is that when the user clicks one of your deep links, they'll get to choose to open in your app or their browser, etc. When they choose your app and your internal app logic realizes it's a URL it doesn't want to intercept, the user gets shown the browser right away. So they choose your app but get shown the browser instead.

注意:当我在此答案中说广播 时,我的意思是通用术语,而不是实际的Android系统功能。

NOTE: when I say "broadcast" in this answer, I mean the general term, not the actual Android system feature.

这篇关于应用无法处理Deep Link时如何优雅地回到网站的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆