【问题标题】:How to implement my very own URI scheme on Android如何在 Android 上实现我自己的 URI 方案
【发布时间】:2011-01-27 17:44:54
【问题描述】:

假设我想定义一个 URI,例如:

myapp://path/to/what/i/want?d=This%20is%20a%20test

必须由我自己的应用程序或服务处理。请注意,该方案是"myapp" 而不是"http""ftp"。这正是我的意图:为 Android 操作系统全局定义我自己的 URI 架构。这可能吗?

这有点类似于某些程序已经在执行的操作,例如 Windows 系统,例如 Skype (skype://) 或任何 torrent 下载程序 (torrent://)。

【问题讨论】:

标签: android android-intent browser uri intentfilter


【解决方案1】:

这是很有可能的;您在 AndroidManifest.xml 中使用 <data> 元素定义 URI 方案。您设置了一个意图过滤器并填写了<data> 元素,您将能够创建自己的方案。 (More on intent filters and intent resolution here.)

这是一个简短的例子:

<activity android:name=".MyUriActivity">
    <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" android:host="path" />
    </intent-filter>
</activity>

根据隐式意图的工作方式,您还需要定义至少一个动作和一个类别;在这里,我选择了 VIEW 作为动作(尽管它可以是任何东西),并确保添加 DEFAULT 类别(因为这是所有隐式意图所必需的)。另请注意我是如何添加 BROWSABLE 类别的 - 这不是必需的,但它允许您的 URI 可以从浏览器中打开(一个漂亮的功能)。

【讨论】:

  • 我花了一段时间才弄清楚要链接到“android:path”变量必须指定协议之后的所有内容的特定路径,即。格式必须为“youtube.com/myvideo”
  • 效果很好,但是如何从 MyUriActivity 的 url 中读取 GET 参数“d”的值?
  • 不适合我我有多个 Intent 过滤器用于同一活动。一个用于主发射器。第二个用于打开特定文件第三个如上所述前两个工作正常但不是第三个。
  • 你可以看看这里的问题stackoverflow.com/q/29116574/3828908
  • English language version 以上链接以防万一有人需要。
【解决方案2】:

补充@DanielLew 答案,要获取参数的值,您必须这样做:

URI 示例:myapp://path/to/what/i/want?keyOne=valueOne&amp;keyTwo=valueTwo

在你的活动中:

Intent intent = getIntent();
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
  Uri uri = intent.getData();
  String valueOne = uri.getQueryParameter("keyOne");
  String valueTwo = uri.getQueryParameter("keyTwo");
}

【讨论】:

  • 如果链接类似于http://www.host.com/directory/value怎么办?我们怎样才能得到这个value
  • 没关系,得到答案here
  • 如何在不使用元数据的情况下,在代码中读取AndroidManifest.xml中的数据标签。我也需要在 oauth 调用中将确切的方案、路径和主机发送到服务器。我不想重复回调声明!
  • @BugsHappen 它是最后一个 URI 路径段。使用uri.getLastPathSegment();
【解决方案3】:

我强烈建议您不要定义自己的方案。这违反了 URI 方案的 Web 标准,该标准试图严格控制这些名称是有充分理由的——以避免不同实体之间的名称冲突。一旦您在网站上放置了指向您的方案的链接,您就将这个小名字放入了整个 Internet 的命名空间中,并且应该遵循这些标准。

如果您只想拥有指向您自己的应用的链接,我建议您按照我在此处描述的方法:

How to register some URL namespace (myapp://app.start/) for accessing your program by calling a URL in browser in Android OS?

【讨论】:

  • 感谢您的提醒,但我只会在封闭的环境中使用它来尝试证明一个概念。如果这个实验离开测试阶段,我肯定会考虑批准整个协议。
  • 好的...但是为什么不做正确的事呢?这不是什么重要的工作。
  • Youtube 执行@hackbod 的建议,但是从 facebook 打开 Youtube 链接会打开浏览器而不是 Youtube 应用程序。这个机制是不是太“微妙”了?
  • 我倾向于定义自己的方案,以便我可以使用相同的 Web 逻辑来启动我的 iOS 应用程序或我的 Android 应用程序。只是我的 2 美分
  • @hackbod 我认为他们在编写 rfc 时并没有想到 android。虽然我 100% 同意您没有必要创建一个新方案,但我认为原因正是这样:甚至没有必要实现目标。而现在.. 当你喜欢 facebook、whatsapp 或其他大型、成熟的技术工具时——“不要创建新的 URI 方案”——规则当然不再适用于你。当您的名称已经与全球范围内的公司绑定时,方案名称不会发生冲突。
【解决方案4】:

Diego 的另一种替代方法是使用库:

https://github.com/airbnb/DeepLinkDispatch

您可以通过 Activity 上的注解轻松声明要处理的 URI 和要提取的参数,例如:

@DeepLink("path/to/what/i/want")
public class SomeActivity extends Activity {
  ...
}

另外,查询参数也将传递给 Activity。

【讨论】:

    【解决方案5】:

    正如多年前提出的问题,Android 在这个 URI 方案上发展了很多。
    从最初的 URI 方案,到深度链接,再到现在的 Android 应用链接。

    Android 现在建议使用 HTTP URL,而不是定义您自己的 URI 方案。因为 Android 应用链接使用 HTTP URL 链接到您拥有的网站域,所以没有其他应用可以使用您的链接。你可以从here查看深度链接和Android App链接的对比

    现在您可以使用 Android Studio 选项轻松添加 URI 方案:工具 > 应用链接助手。 详情请参考Android文档:https://developer.android.com/studio/write/app-link-indexing.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      • 1970-01-01
      • 1970-01-01
      • 2017-09-08
      • 2023-02-05
      相关资源
      最近更新 更多