当应用程序无法处理深层链接时如何优雅地回退到网站

2024-03-11

情况:

  1. 您有一个内容广泛的移动网站 m.somewhere.com
  2. 在 Google Play 上,您有一个 Android 应用程序,它复制了 m.somewhere.com 的主要功能,但不是全部。
  3. 您的客户/雇主/投资者要求您为应用程序可以处理的那些网址实现深度链接。

TL;DR - 你如何实现这个?

到目前为止我的方法:

第一直觉:仅匹配某些 url 并启动它们。问题:AndroidManifest 意图过滤器中的表达式缺乏会阻止这种情况发生(例如http://weiyang.wordpress.ncsu.edu/2013/04/11/a-limitation-in-intent-filter-of-android-application/ http://weiyang.wordpress.ncsu.edu/2013/04/11/a-limitation-in-intent-filter-of-android-application/).

作为问题的一个子集,假设 m.somewhere.com 的服务器知道任何以数字结尾的 url 都会转到网站上的某个页面,并且营销人员不断地进行搜索引擎优化,因此例如

我想启动该应用程序:

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

path、pathPrefix 或 pathPattern 的组合无法处理此问题。

stackoverflow 上的最佳实践(将 URI 与 AndroidManifest 中的 相匹配,例如 http://example.com/something https://stackoverflow.com/questions/24876676/match-uris-with-data-like-http-example-com-something-in-androidmanifest) 似乎是捕获所有内容,然后在到达 onCreate() 时处理这种情况,并意识到您不应该处理这个特定的 url:

安卓清单:

...
<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>
...    

活动 onCreate():

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

我编写了与上面类似的程序,该程序正在运行,但它会导致非常糟糕的最终用户体验:

  1. 浏览 m.somewhere.com 时,每次点击 url 时都会出现卡顿 当应用程序启动然后回退时。
  2. 有一个令人讨厌的习惯,即每次点击 m.somewhere.com 链接时都会弹出选择器屏幕,询问用户他们想要使用哪个(Android 应用程序与浏览器一起列出,但点击 Android 应用程序)应用程序只是再次启动选择器屏幕)。如果我不小心,我的应用程序就会陷入无限重新启动循环(如果用户选择“始终”),即使我很小心,用户也会觉得他们的“始终”选择被忽略了。

可以做什么?

(编辑:在应用程序的 Web 视图中显示未处理页面的站点不是一个选项)。


迟到的答案,但对于未来的读者:如果你支持至少API 级别 15然后,有一种更直接(更少黑客行为)的方法,可以退回到浏览器来查找您不想处理的 URL,而无需禁用/重新启用 URL 捕获组件。

恩巴雷耶的回答 https://stackoverflow.com/a/34957893/708906很有创意,如果您需要支持低于 15 的 API,则可能是您唯一的选择,但如果您不这样做,那么您可以使用Intent.makeMainSelectorActivity() https://developer.android.com/reference/android/content/Intent.html#makeMainSelectorActivity(java.lang.String,%20java.lang.String)直接启动用户的默认浏览器,让您绕过Android的ResolverActivity应用程序选择对话框。

不要这样做

因此,不要像这样重新广播 URL Intent 的典型方式:

// 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

您可以广播此 Intent:

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

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

Caveat

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

Pitfalls

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

注意:当我说“播送”在这个答案中,我指的是通用术语,而不是实际的 Android 系统功能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当应用程序无法处理深层链接时如何优雅地回退到网站 的相关文章

  • Android 中多个蓝牙连接的自定义 UUID

    我有一个 Android 设备作为服务器连接到多个蓝牙 Android 客户端 我了解 UUID 的概念以及它的独特之处 我的问题是 我可以为连接到我的服务器的所有客户端使用相同的 UUID 吗 如果没有 我如何以编程方式为我的客户端生成
  • AdapterContextMenuInfo 始终为 null

    我尝试通过 android 开发文档中的书来做到这一点 this didn t create a menu i don t know why registerForContextMenu getListView setListAdapter
  • 如何正确释放Android MediaPlayer

    我正在尝试向我的 Android 应用程序添加一个按钮 当点击该按钮时它会播放 MP3 我已经让它工作了 但没有办法释放 mediaPlayer 对象 因此即使在我离开活动后它仍然会继续播放 如果我在react 方法之外初始化MediaPl
  • Gradle 构建错误:无法从 https://repo1.maven.org/maven2/io/fabric/tools/gradle/maven-metadata.xml 加载 Maven 元数据

    我在 Android studio 中遇到 gradle 构建错误 如下所示 Error A problem occurred configuring project MyApp Could not resolve all dependen
  • 如何使用 Google Maps for Android V2 处理地图移动结束?

    我想在地图中心更改后立即对地址进行地理编码 如何使用新的 Android 版 Google 地图 V2 处理地图移动 我说的是用户用手指拖动地图的情况 查看新的地图 API Override public void onMapReady G
  • Android应用程序组件销毁和重新创建的详细信息

    有人可以向我提供一些具体的 值得信赖的 最好是简洁的 信息 内容如下 系统销毁和 如果适用 重新创建组件的顺序 片段 活动 活动的线程 异步任务 计时器 静态数据 类何时卸载 其他类中的线程 异步任务 定时器 主机 TabActivity
  • Dialog.setTitle 不显示标题

    我正在尝试向我的对话框添加自定义标题 但是每当我运行我的应用程序时 它都不会显示标题 我创建对话框的代码是 final Dialog passwordDialog new Dialog this passwordDialog setCont
  • 以编程方式将文本颜色设置为主要 Android 文本视图

    如何设置我的文本颜色TextView to android textColorPrimary以编程方式 我已经尝试了下面的代码 但它将 textColorPrimary 和 textColorPrimary Inverse 的文本颜色始终设
  • 在 Cordova 应用程序中获取额外功能

    我们有两个 Android 应用程序 一个使用本机 Java 实现 另一个使用 Ionic 编写 Ionic 应用程序启动我的应用程序 这是使用灯插件 https github com lampaa com lampa startapp 我
  • java.lang.IllegalStateException:应用程序 PagerAdapter 更改了适配器的内容,而没有调用 PagerAdapter#notifyDataSetChanged android

    我正在尝试使用静态类将值传递给视图 而不是使用意图 因为我必须传递大量数据 有时我会收到此错误 但无法找出主要原因是什么 Error java lang IllegalStateException The application s Pag
  • 在 android 中建立与 MySQL 的池连接

    我需要从我的 Android 应用程序访问 MySQL 数据库 现在所有的工作都通过 DriverManager getConnection url 等等 但我必须从多个线程访问数据库 所以我必须使用连接池 问题1 是 com mysql
  • 从 BroadcastReceiver 类调用活动方法

    我知道我可以做一个内部接收器类来调用接收器中的任何方法 但我的主要活动太大了 要做的事情也很多 因此 我需要一个扩展广播接收器的类 但它不是内部类 并且可以从我的主要活动中调用一种方法 我不知道是否可能 但我的活动是家庭活动和 single
  • okhttp 获取失败响应

    我已经在我的 android 客户端中实现了 okhttp 来进行网络调用 当我收到失败响应时 我会收到失败代码以及与该代码相关的文本作为消息 但我没有收到服务器发送给我的自定义失败响应 在我实施的代码中的失败响应中 我收到的消息只是 错误
  • logcat 中 mSecurityInputMethodService 为 null

    我写了一点android应显示智能手机当前位置 最后已知位置 的应用程序 尽管我复制了示例代码 并尝试了其他几种解决方案 但似乎每次都有相同的错误 我的应用程序由一个按钮组成 按下按钮应该log经度和纬度 但仅对数 mSecurityInp
  • Android 中如何通过彩信发送图片?

    我正在开发多媒体应用程序 我正在通过相机捕获一张图像 并希望将该图像和文本发送到其他号码 但我不知道如何通过彩信发送图像 MMS 只是一个 http post 请求 您应该使用执行请求额外的网络功能 final ConnectivityMa
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • Android Studio 缓慢的增量构建

    我已经完成了许多步骤来完善我们的构建系统 those https stackoverflow com questions 16775197 building and running app via gradle and android st
  • Android 中的处理程序与异步调用

    目前我正在使用处理程序来调用 Web 服务方法以使其在后台运行 问题是它需要更多的时间来给出响应 在性能方面似乎更昂贵 现在我计划使用异步调用 哪一个是最好的 Android 中的处理程序和异步调用有什么区别 请帮我想出一个最好的解决方案
  • 找不到符号 NOTIFICATION_SERVICE?

    package com test app import android app Notification import android app NotificationManager import android app PendingIn
  • CamcorderProfile.videoCodec 返回错误值

    根据docs https developer android com reference android media CamcorderProfile html 您可以使用CamcorderProfile获取设备默认视频编解码格式 然后将其

随机推荐

  • 如何在IOS的UIView中仅使文本/标题覆盖的部分透明

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在尝试创建一个UIView with text the text可能会不断变化 在其之上 我只想要text其中的一部分UIView透明
  • 模拟对象上的异步回调不等待

    我试图模拟单元测试的复杂情况 mockController new Mock
  • 无法连接到 (LocalDB)\MSSQLLocalDB -> 用户“User-PC\User”登录失败

    当我尝试通过 SQL Server Management Studio 连接 LocalDB MSSQLLocalDB 时 出现错误 我还尝试使用默认数据库作为 master 登录 错误是相同的 Here is the Server det
  • JavaScript 中的嵌套层数是否有限制?

    假设您有一个非常复杂的算法 需要数十个 for 循环 JavaScript 对循环的嵌套深度有限制还是没有限制 深层嵌套 for 循环的最佳实践是什么 我尝试在 MDN 上搜索 但找不到我要找的内容 Edit 我正在寻找是否有内置限制 例如
  • Java - 接口扩展自身

    我已经使用这个网站大约 6 个月了 是时候问我的第一个问题了 因为我找不到这个问题的答案 至少不是我能理解的答案 在这段代码中 为什么这个接口要扩展自身 public interface PositionedVertex
  • DecorView子框架布局

    有人可以向我解释一下 为什么我的布局上的 DecorView 的子级是 FrameLayout 而我还没有定义它 这是xml布局
  • 观察者模式是否违反了单一责任原则?

    如果使用观察者设计模式的应用程序具有subject具有以下职责的类 1 管理和通知观察者 即提供注册和注销函数并调用所有观察者通知函数 和 2 它最初的责任 即班级在成为班级之前正在做什么subject 这个类是否违反了单一职责原则 它显然
  • jsPDF 不完整或损坏的 PNG 文件

    使用 jsPDF 添加常规 png 图像没有问题 但现在我从服务器发送生成的图像 并且浏览器控制台在渲染 PDF 文件时显示此错误 PNG 文件不完整或损坏 显然图像不是不完整或损坏的 因为我可以看到服务器的响应并且图像很好 另外 为了避免
  • 函数参数列表中的三个点是什么意思?

    我遇到了这样的函数定义 char abc char f 三个点是什么意思 这些类型的函数称为可变参数函数 维基百科链接 https en wikipedia org wiki Variadic function 他们使用省略号 即三个点 来
  • Linux perf 中的运行时间和报告的周期计数

    我在 4 核 Intel CPU 每个核心 1 个线程 上运行了单线程矩阵乘法 但 perf 中的数字没有意义 Performance counter stats for system wide 31 728 397 287 cpu cyc
  • 使用 Poco 和 Boost C++ 的多个 Http 服务器

    我正在尝试使用 Poco Net 和 Boost 库创建多个 Http 服务器 但在 Poco 文件内部出现以下错误应用程序 cpp Assertion violation pInstance 0 in file src Applicati
  • 无法安装渐进式网络应用程序网站:没有可显示的图标

    我正在构建一个渐进式网络应用程序 我从样板开始创建反应应用程序 https github com facebookincubator create react app 然后我添加了一个网络应用程序清单 应用程序 公共 manifest js
  • Selenium Webdriver C# 无需等待页面加载

    我有以下场景 我想导航到一个页面 然后 一旦出现按钮就单击它 不等待页面加载 我不想等待初始页面加载 因为这需要很长时间 我的程序目前卡住 直到页面加载然后单击按钮 我基本上想导航到链接 然后无需等待页面并继续我的代码 无论如何还有这个吗
  • Bootstrap 手风琴箭头颜色 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我怎样才能改变颜色崩溃了手风琴箭头 我尝试了更多解决方案 但我设法仅更改按钮的文本颜色 恒定的颜色是蓝色 与深色背景根本不兼容 例子
  • ListView 性能缓慢

    我有一个习惯ListView我在那里展示了一些从本地数据库检索到的武器 我总共有 88 行 每行每次设置一个文本和一个图像getView 叫做 这ListView快速滚动时会出现滞后 垃圾收集器会变得疯狂 每秒删除一些 1M 对象 我不明白
  • 为什么这个正则表达式在 JavaScript 中的计算结果为 false?

    我正在寻找一个 0 9 数字的字符串 没有其他字符 这是用 假 值提醒我 var regex new RegExp d 0 9 alert regex test 123456789 这些返回 true 我明白为什么 和 表示整个字符串需要匹
  • Cookie 与子域 Nodejs httponly Cookie 共享

    我正在使用快速会话模块来维护会话 我有两个应用程序 我想与此应用程序共享cookie 父应用程序在 example com 中运行 子应用程序在 child example com 中运行 我使用它在子应用程序中设置的express ses
  • 禁止在第一个字符位置键入 0(零)

    我正在使用 Jquery 数字插件 该插件只允许在输入中键入数字值 tbQuan numeric 除了这个插件正在做的事情之外 我还需要在第一个字符位置禁用键入 0 零 任何帮助 将不胜感激 尝试这个 input keypress func
  • 可以像这样在 ASP.NET Core 中制作 SEO 友好的 Url

    我想问你们是否可以为我的项目做一些这样的路由 action title 我想知道这是否可能 这个网址也必须是主键吗 由于没有传递 ID 来知道这是哪篇博文 谢谢 您可以使用属性路由轻松地做到这一点 Route blogs public cl
  • 当应用程序无法处理深层链接时如何优雅地回退到网站

    情况 您有一个内容广泛的移动网站 m somewhere com 在 Google Play 上 您有一个 Android 应用程序 它复制了 m somewhere com 的主要功能 但不是全部 您的客户 雇主 投资者要求您为应用程序可