从网页中触发Android原生的分享Intent

1869次阅读  |  发布于5年以前

原文链接 : Triggering a native Share intent on Android from the web

这是很久之前的事了,在我访问了班加罗尔(印度南部城市)的FlipKart以及进行了一场关于是否存在一种从web触发Android分享Intent方式的内部交流。很多小伙伴都想要这样的功能,但是它给很多人的感觉是无法实现。那么它究竟怎样才能实现呢......

对于web的Intent我还是有很多美好的记忆以及它们能够做些什么...好吧,其实我曾经也为这方面的失败而在很多个夜晚泪流满面~

Android Intent系统成功地模仿了Web Intent,与Android一样,Web Intent的主要使用场景就是提供一种良好的分享体验。虽然有很多的社交组件在你的页面上,但是只有其中一个会平台会被用户选择。在页面中你定义了一个按钮,当用户点击这个按钮时就会触发分享操作,此时系统或者浏览器就会检测提供分享功能的服务,并且做出对用户的回应。不得不说这简直就是一个屌炸天的想法,即使想出这个方法的人是

不幸的是, Web Intents项目没有能够存活下来,而Android的Intent却坚持了下来,并且成为内置的应用间分享的形式。Android Intent最强悍它能够被解析成为类似URL的scheme,这个scheme能够被Chrome和其他浏览器支持。然而,在web上使用它的场景只是通过打开一个网页来让用户下载一个native的App。例如 intent:paul.kinlan.me#Intent;scheme=https;package=com.chrome.beta;end 会在Android版的Chrome打开一个站点。

有意思的是你不能直接启动系统中的其他app。这个app必须告诉系统它能够从web中被打开,这需要在intent-filter中声明 <category android:name="android.intent.category.BROWSABLE" />

完整的例子是你需要在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" />
</intent-filter>

如果你了解Android,那么你应该知道ACTION_SEND是一个非常流行的Action,它被用于在应用间分享数据。

事实上,当用户在Chrome应用中进行分享时Chrome自己会触发一个ACTION_SEND,如果你在你的Android Manifest中定义了如下的声明,那么你的应用就会出现在备选应用列表中。

<!-- Used to handle Chrome then menu then share.-->
<intent-filter>
    <action android:name="android.intent.action.SEND" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="text/plain" />
    <data android:mimeType="image/*" />
</intent-filter>  

那么问题来了。如果我们制造一个类似的Intent url,那么能直接从web中直接触发类似的分享操作吗?

可以说能,也可以说不能。要实现这样的功能,这个app必须申明另外一个特性,<category android:name="android.intent.category.BROWSABLE" />,现在我们的Android manifest看起来是如下这样的 :

<!-- Used to handle Chrome then menu then share.-->
<intent-filter>
    <action android:name="android.intent.action.SEND" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:mimeType="text/plain" />
    <data android:mimeType="image/*" />
</intent-filter>  

现在,我们的app就可以从web直接从Android的Chrome打开native的分享Dialog了。

让我们来构建一个分享按钮吧。

1. 创建一个最基本的分享

通过ACTION_SEND来触发分享操作。注意 : 这里我们没有数据会被发送,它只是列出了可以接受数据的app。此时Intent url为 :

intent:#Intent;action=android.intent.action.SEND;type=text/plain;end

2. 为这个分享添加一个链接

通过EXTRA_TEXT字段为Intent添加一些数据,例如 : S.android.intent.extra.TEXT=https%3A%2F%2Fpaul.kinlan.me%2F,此时Intent url为 :

intent:#Intent;action=android.intent.action.SEND;type=text/plain;S.android.intent.extra.TEXT=https%3A%2F%2Fpaul.kinlan.me%2F;end

3. 添加主题

我们可以再添加一些额外的信息,例如可以指定一个主题,对应的示例为 : S.android.intent.extra.SUBJECT=Amazing ,此时Intent url为 :

intent:#Intent;action=android.intent.action.SEND;type=text/plain;S.android.intent.extra.TEXT=https%3A%2F%2Fpaul.kinlan.me%2F;S.android.intent.extra.SUBJECT=Amazing;end

4. 当没有可以响应的App时反馈给网页

经常出现没有能够响应用户的行为的app。在这种情况下我们想通过一个回调告诉发起该请求的网页,使得用户仍然能够完成这个操作。这项功能可以通过一个名为S.browser_fallback_url的属性设置。示例Intent url为 :

intent:#Intent;action=android.intent.action.SEND;type=text/plain;S.android.intent.extra.TEXT=https%3A%2F%2Fpaul.kinlan.me%2F;S.android.intent.extra.SUBJECT=Amazing;S.browser_fallback_url=https:%3A%2F%2Ftwitter.com%2Fintent%2Ftweet;end

先有鸡还是先有蛋

从技术上来说,我们掌握了所有的技术点。我们最大的挑战不是URL本身,而是那些社交平台的app以及其他我们需要交互的app可以被更新(译者注 : 指的是通过Intent发布消息)。一旦他们这样做了,我们就可以通过这种方式通过web实现良好的分享体验。

我的理想解决方案是如果一两个app更新了他们的manifest,那么如下两个大玩家就会更新对应的share url。我们知道的两个app是如下两个 :

如果你想让你的app出现在上面的列表中,你只需要添加对应的Category,并且让我知道。否则你就好好待着,然后观看这个Demo视频

拓展阅读

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8