Android浏览器Facebook重定向并不总是触发URL的意图

Oli*_*ain 6 redirect android facebook intentfilter android-intent

我是一个真正的泡菜,迫切需要一些关于我遇到的关键问题的帮助.

我花了几个月的时间编写一个HTML5应用程序/网站以及一个原生的Android应用程序,它只是HTML5网站的WebView包装器.该应用程序的核心功能之一是用户可以将应用程序特定的URL共享到Facebook和Twitter等,以便他们的朋友可以关注共享URL,这将在我们的浏览器中打开我的应用程序的HTML5版本,或者如果它们是最重要的在Android上,他们已经安装了我的原生Android应用程序,他们被提议在我的应用程序中打开.

这是一个相当长的复杂问题,所以为了简化,我会在这篇文章中一致地使用某些特定术语:

  • "MyApp用户"是安装了原生Android应用的Android设备用户
  • "非MyApp用户"是未安装原生Android应用的Android设备用户
  • "股票浏览器用户"是使用股票浏览器的股票Android用户
  • "非股票浏览器用户"使用非股票浏览器的Android用户(注意三星Galaxy SII股票"互联网"应用程序被视为非股票)
  • 在Android上选择"应用程序对话框",出现操作系统对话框,询问用户他们想要打开action/intent/url/document的应用程序,以及他们是否要默认使用此应用程序

我的AndroidManifest.xml包含以下内容......

<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="myapp.com" android:pathPrefix="/" />
</intent-filter>
Run Code Online (Sandbox Code Playgroud)

在任何正常情况下测试时,这都可以完美运行.例如,如果"MyApp用户"跟随到http://myapp.com/sharedpage的直接链接,则会出现"选择应用程序对话框".太棒了,我确实正确配置了我的AndroidManifest.xml.

然而事情并不总是在关键的Facebook共享场景中工作.它并不总是有效,因为Facebook的原生Android应用程序和Facebook的移动网站(http://m.facebook.com)都没有直接链接到共享URL,而是通过Facebook重定向页面链接.例如,如果共享http://myapp.com/sharedpage,Facebook将最终提供以下URL:

http://m.facebook.com/l.php?u=http%3A%2F%2Fmyapp.com%2Fsharedpage&h=EAQGpLtuF&enc=AZMXYZg7XwQ39zlWkKSGnLw62lEbtbMeWFmRwRZINoOcg0UgZe3fUVPgqQzV1nuTipSVnquV3a3ovqu7HQFUf3bb3ZJ1gYG8dEOJXzPf6RJGflf9_x8w-6CCXu8G2VZqgfD7lx6EbLTSKLnF56_o5khHybycPUlhpdfLsk6M9muer4jMOmPK6_kfjTq2gvnYNNpStcF0ilJD6nacPqx_1xsdYkUMpKYWbJfSo7qqv1S5xT5KRaLPxl8zmAkYc0FhwyTdn-tUGwRBbbdM4QCd2Z75Tb_VeJG3LvbDwFAbp6G3kH3LOSxVtTd5MST4pUW8xmhNeTUVBVXV16OD27QcsSWOlEfL72fxn11PDE5s4WWsXMnwhDJLUAWOAna7lziBnWzjZdlQK_amI9nhcegaOLDLNFCp125rZS3jxFXf7gtF9g0BsmnPZ2Gjxkc6UgQXhEYldllq9nwpShGbnZDlSg0_&s=1

如果"MyApp用户"跟随其中一个Facebook链接,则可能会发生以下两种情况之一,具体取决于他们使用的浏览器...

MyApp股票浏览器用户:

如果用户安装了Android安装并使用了Android浏览器,那么事情就会很好,因为发生了以下事件......

MyApp非浏览器用户:

但是如果用户......

  1. 已安装并使用非现货Android浏览器,例如Dolphin HD/mini,Opera Mobile/Mini等,或
  2. 有一个制造商定制的Android版本(例如在三星Galaxy SII等),因此有一个定制的浏览器

......然后这是主要问题,因为发生了以下事件......

  • Intent将触发FB l.php URL
  • FB URL在NON-STOCK BROWSER中打开
  • FB l.php已加载并启动REDIRECT到http://myapp.com/sharedpage
  • 意图未被非库存浏览器激活,"选择应用程序对话框"未显示,用户不会被提示在我的应用程序中打开URL
  • http://myapp.com/sharedpage URL被加载并在非股票浏览器分页呈现

客户端重定向

为了确认导致问题的重定向,我创建了一个名为"clientSideRedirector.htm"的非常简单的HTML页面.

<html><body><script>
   window.location.href = "http://myapp.com/sharedpage";
</script></body></html>
Run Code Online (Sandbox Code Playgroud)

如果我的应用程序/非库存浏览器用户打开http://myapp.com/clientSideRedirector.htm,则不会出现"应用程序选择对话框".失败.

如果我的应用程序/股票浏览器用户打开http://myapp.com/clientSideRedirector.htm,则会出现"应用程序选择对话框".

这似乎与我们在Facebook共享/重定向中看到的情况相符.

服务器端(302)重定向

我还以为我会尝试服务器端重定向,所以我创建了一个.NET dotNetRedirect.ashx页面:

public class ShareRedirect : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
            context.Response.Redirect("http://myapp.com/sharedpage");
    }
    public bool IsReusable { get { return false; } }
} 
Run Code Online (Sandbox Code Playgroud)

这对客户端重定向有一个非常有趣和不同的结果.
如果My-App用户打开http://myapp.com/dotNetRedirect.htm,则"应用程序选择对话框"会显示用户浏览器.所以这种类型的重定向似乎工作!


试图解决方案A.

(双重重定向:Facebook l.php重定向到服务器端重定向到应用程序URL)

我认为这可能是我的Facebook共享问题的解决方案.如果我将http://myapp.com/dotNetRedirect.ashx网址分享到Facebook,那么Facebook可能会重定向到dotNetRedirect.htm页面,然后服务器端重定向将强制"选择应用程序对话框"提示打开.

不幸的是,这不起作用,在非库存浏览器中,如果第一次重定向不触发意图/"选择应用程序对话框",则会出现进一步的重定向也不会.大量去内脏.


试图解决方案B.

(使用自定义方案)

已经用尽了服务器端的想法,我以为我会调查使用自定义URI方案来触发"应用程序选择对话框".

AndroidManifest.xml中:

<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="myapp" />
</intent-filter>
Run Code Online (Sandbox Code Playgroud)

redirect.htm

<html><body><script>
   window.location.href = "myapp.com://sharedpage";
</script></body></html>
Run Code Online (Sandbox Code Playgroud)

这确实有效,即使使用非库存浏览器,也会通过DB l.php URL显示"选择应用程序对话框".然而,它并不是一个真正可行的解决方案,因为"非MyApp用户"在重定向到myapp.com://sharedpage网址时会留下"网页不可用"页面.]


还有其他人有任何其他明智的想法或建议吗?

Oli*_*ain 5

我在搜索中做了一些进一步的开发,发现执行"假点击"是在大多数场景中有效的解决方案(但不是全部).

如果用户希望共享URL http://myapp.com/sharedpage,那么我实际上将以下URL发布到Facebook http://myapp.com/share.htm?redirectUrl=sharedpage

share.htm只是一个javascript重定向页面,可立即重定向到相应的页面.它很聪明,但在Android上而不是仅仅使用window.location.replace它时会使用带有链接的虚假点击来强制在某些设备/某些浏览器上触发意图.代码如下所示.

<!DOCTYPE HTML>
<html>
<body>
    <script type="text/javascript">
        var redirectUrlRelativeToThisPage = ""; // Read off the querystring here
        var isAndroidDevice = (/android/gi).test(navigator.userAgent);

        if (isAndroidDevice) {
            // Android device. If the user isn't using a stock browser then window.location.redirect() doesn't always
            // trigger an Intent (and prompt to open Native app) so instead attempt to fake click a hyperlink with the
            // URL as this works more reliably (but not always).
            var linkToFakeClick = document.createElement("a");
            linkToFakeClick.href = redirectUrlRelativeToThisPage;
            var fakeMouseClickEvent = document.createEvent("MouseEvents");
            fakeMouseClickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
            linkToFakeClick.dispatchEvent(fakeMouseClickEvent);
        }
        // If we got here either we're not on an Android device or the fake click didn't work so just redirect normally
        window.location.replace(redirectUrlRelativeToThisPage);
    </script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

除了上面的示例代码,如果它适合您的场景,您还可以合并(如果假冒点击不起作用)两个不同的"我做/没有安装应用程序"按钮链接到自定义scheme URL(强制意图)和通常的URL.