Oli*_*ain 6 redirect android facebook intentfilter android-intent
我是一个真正的泡菜,迫切需要一些关于我遇到的关键问题的帮助.
我花了几个月的时间编写一个HTML5应用程序/网站以及一个原生的Android应用程序,它只是HTML5网站的WebView包装器.该应用程序的核心功能之一是用户可以将应用程序特定的URL共享到Facebook和Twitter等,以便他们的朋友可以关注共享URL,这将在我们的浏览器中打开我的应用程序的HTML5版本,或者如果它们是最重要的在Android上,他们已经安装了我的原生Android应用程序,他们被提议在我的应用程序中打开.
这是一个相当长的复杂问题,所以为了简化,我会在这篇文章中一致地使用某些特定术语:
我的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:
如果"MyApp用户"跟随其中一个Facebook链接,则可能会发生以下两种情况之一,具体取决于他们使用的浏览器...
MyApp股票浏览器用户:
如果用户安装了Android安装并使用了Android浏览器,那么事情就会很好,因为发生了以下事件......
MyApp非浏览器用户:
但是如果用户......
......然后这是主要问题,因为发生了以下事件......
客户端重定向
为了确认导致问题的重定向,我创建了一个名为"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网址时会留下"网页不可用"页面.]
还有其他人有任何其他明智的想法或建议吗?
我在搜索中做了一些进一步的开发,发现执行"假点击"是在大多数场景中有效的解决方案(但不是全部).
如果用户希望共享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.