Android Web Intent 问题

2024-05-17

G'day,

免责声明:我不是 Android 开发人员,我正在对我所描述的问题进行质量检查。我用来描述这个问题的技术术语可能是错误的。

我正在测试一个 Android 应用程序,该应用程序在其清单中描述它可以使用 type 的地址处理 Web 意图https://www.example.com/app/(.*)。它应该处理这些 URL 的方式是获取第一个匹配组$1并向https://api.example.com/$1如果响应是 HTTP200,它会在应用程序内呈现响应。如果没有,它应该在用户设备上安装的任何浏览器应用程序中打开 URL(通过发送打开 URL 的意图)。如果用户的设备上没有安装浏览器应用程序,我们会显示错误提示,指出他们没有安装可以处理此 URL 的浏览器。

现在,这工作正常,除非用户将此应用程序标记为默认处理 URL,例如https://www.example.com/app/(.*)当它第一次尝试打开像这样的 URL 时https://www.example.com/app/(.*)。然后,即使用户的系统上安装了浏览器应用程序,当他们打开需要在浏览器中打开的链接时,唯一的选择似乎是我们原来的应用程序,我们必须显示错误消息(看起来像就像系统上没有安装其他可以处理此 URL 的浏览器应用程序一样)。

解决这个问题的一种方法是,当我们遇到需要在浏览器应用程序中打开的 URL 但唯一的选择是我们自己的应用程序时,显示一条消息,要求用户清除此应用程序的默认设置 - 但这是糟糕的用户体验。对于这个问题还有其他解决方法吗?

用于理解问题的示例代码:https://gist.github.com/GVRV/5879fcf0b1838b495e3a2151449e0da3 https://gist.github.com/GVRV/5879fcf0b1838b495e3a2151449e0da3

编辑1:添加示例代码链接


要解决此问题并保持系统对意图的默认处理,您需要 2 个额外的活动和 1 个<activity-alias>:

  1. 创建一个新的不可见的空活动。我将其称为 IntentFilterDelegationActivity。此活动负责从以下位置接收 URL 意图activity-alias(在下一步中定义)。显现:

    <activity
        android:name=".intent_filter.IntentFilterDelegationActivity"
        android:excludeFromRecents="true"
        android:exported="true"
        android:launchMode="singleInstance"
        android:noHistory="true"
        android:taskAffinity=""
        android:theme="@style/Theme.Transparent"/>
    

Code:

public class IntentFilterDelegationActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        findAndStartMatchingActivity(getIntent());
        finish();
    }
}
  1. 创建一个<activity-alias>。活动别名负责将您的 URL 意图委托给您的IntentFilterDelegationActivity。只需要一个清单条目:

    <activity-alias
        android:name="${packageName}.IntentFilterDelegation"
        android:enabled="true"
        android:exported="true"
        android:targetActivity=".intent_filter.IntentFilterDelegationActivity">
        <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="www.example.com"/>
        </intent-filter>
    </activity-alias>
    
  2. 现在您可以做到这一点:您可以停用activity-alias在启动您自己的 URL 意图之前并在启动后激活别名。这会导致 android 您的应用程序不会被列为可以处理 URL 意图的应用程序。要实现激活和停用,您需要一个额外的活动。我叫它ForceOpenInBrowserActivity。 显现:

    <activity
        android:name=".activity.ForceOpenInBrowserActivity"
        android:excludeFromRecents="true"
        android:launchMode="singleInstance"
        android:noHistory="true"
        android:taskAffinity=""
        android:theme="@style/Theme.Transparent"/>
    

Code:

        public class ForceOpenInBrowserActivity extends Activity
    {
        public static final String URI = IntentUtils.getIntentExtraString(ForceOpenInBrowserActivity.class, "URI");

        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);

            Uri uri = fetchUriFromIntent();
            if (uri != null)
            {
                startForcedBrowserActivity(uri);
            }
            else
            {
                finish();
            }
        }

        @Nullable
        private Uri fetchUriFromIntent()
        {
            Uri uri = null;

            Intent intent = getIntent();
            if (intent != null)
            {
                uri = intent.getParcelableExtra(URI);
            }

            return uri;
        }

        private void startForcedBrowserActivity(Uri uri)
        {
            disableActivityAlias(this);

            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            // After starting another activity, this activity will be destroyed
            // android:noHistory="true" android:excludeFromRecents="true"
            startActivity(intent);
        }

        /**
         * Re-enable intent filters when returning to app.
         * Note: The intent filters will also be enabled when starting the app.
         */
        @Override
        protected void onStop()
        {
            super.onStop();
            enableActivityAlias();
        }

        public void disableActivityAlias()
        {
            String packageName = getPackageName();
            ComponentName componentName = new ComponentName(packageName, packageName + ".IntentFilterDelegation"); // Activity alias
            getPackageManager().setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
        }


        public void enableActivityAlias()
        {
            String packageName = getPackageName();
            ComponentName componentName = new ComponentName(packageName, packageName + ".IntentFilterDelegation");
            getPackageManager().setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
        }
    }
  1. 现在您可以将任何必须在外部浏览器中打开的 URL 意图发送到ForceOpenInBrowserActivity:

    @NonNull
    public static Intent createForceBrowserIntent(Context context, @NonNull Uri uri)
    {
        Intent intent = new Intent(context, ForceOpenInBrowserActivity.class);
        intent.setAction(Intent.ACTION_VIEW);
        intent.putExtra(ForceOpenInBrowserActivity.URI, uri);
        return intent;
    }
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android Web Intent 问题 的相关文章

  • 查找回收器视图中的第一个可见项目是否是列表的第一项

    我有一个包含 13 个数据项的回收器视图 我想知道列表中的第一项是否可见 我知道像这样的方法findFirstVisibleItemPosition and findLastVisibleItemPosition但他们没有说明第一个可见项目
  • Android studio 在日志猫中“清除全部”,更改日志级别过滤器时日志仍然会回来

    在 LogCat 中 当我单击 全部清除 按钮时 它似乎清除了所有日志 但是 如果我更改日志级别并返回到之前的日志级别 则所有日志都会返回 例如 我正在查看 Verbose 我选择 全部清除 日志清除 我切换到 调试 我切换回 详细 现在所
  • 更改工具栏中汉堡图标的大小?

    我有两个问题 可能很奇怪 但无论如何 我有带有应用程序标题的工具栏 如何将其更改为非徽标的图片 下一个问题 是否可以设置 更改工具栏中汉堡图标的大小 我在下面的下一个代码的帮助下制作了经典的导航抽屉 我也使用了 ActionBarDrawe
  • Mailgun POST /messages API 总是抛出 401 禁止

    我正在尝试使用改造库在 Android 中发送 Mailgun POST messages API 请求 以下是改装要求 HTTP POSThttps api key xxx v3 sandboxxxx messages https api
  • MI设备中即使应用程序被杀死,如何运行后台服务

    您好 我正在使用 alaram 管理器运行后台服务 它工作正常 但对于某些 mi 设备 后台服务无法工作 我使用了服务 但它无法工作 如何在 mi 中运行我的后台服务 MI UI有自己的安全选项 所以你需要的不仅仅是上面提到的粘性服务 你需
  • 无法将 Tesseract OCR 模块添加到 Android Studio

    我按照此处找到的分步指南进行操作 https www codeproject com Articles 840623 Android Character Recognition https www codeproject com Artic
  • layout.xml 的用途是什么?

    人们为什么使用layout xml在他们的resources like
  • Android 手机应用意图

    我想在手机上启动手机应用程序作为意图 我正在使用这个代码 startActivity getPackageManager getLaunchIntentForPackage com android phone 但该函数抛出一个空指针异常 因
  • Cordova 地理定位不适用于 Android

    我想在 Android 上使用地理定位 我用 Apache Cordova 编写应用程序 地理定位在 android 电脑模拟器和 android 手机上均不起作用 I try http cordova apache org docs en
  • Locale.getDefault().getCountry() 返回空字符串

    我正在尝试使用国家 地区代码获取用户语言 例如en US es es 但是当我使用Locale getDefault getCountry 它返回空字符串 虽然它给了我正确的语言Locale getDefault getLanguage N
  • 如何覆盖日期选择器的高度和宽度以填充父布局

    我有一个活动包含一个日期选择器 我想设置DatePicker适合屏幕 我试过这个答案 https stackoverflow com questions 6674667 how to customize date pickers width
  • 手动启用时 Firebase Crashlytics 不报告崩溃

    Crashlytics 在没有选择加入报告的情况下也能正常工作 但一旦我根据规定设置了选择加入报告 它就会停止报告任何内容tutorial https firebase google com docs crashlytics customi
  • 有没有办法在Android上创建一个三角形按钮?

    有没有办法创建一个三角形的按钮 我知道我可以将三角形图像作为背景 但这将使三角形之外的区域可单击 有没有办法固定按钮角 X 和 Y 以便我可以将其变成三角形 您可以覆盖OnTouch http developer android com r
  • Android开发:未定义方法

    大家好 我是 Android 和 Eclipse 的新手 我刚刚遵循了developer android com 上的教程 现在我在添加操作栏 http developer android com training basics actio
  • 如何在android中录制音频时暂停背景音乐

    我正在 Android 中开发一个音频记录应用程序 因此 如果设备音乐播放器中已播放任何背景音乐 则应在开始录制之前暂停该背景音乐 并且每当录制停止或暂停时 背景音乐都应恢复 播放录制的音频时也应该如此 有人可以帮我解决这个问题吗 提前致谢
  • 带有空白白屏的 WebView

    我在 DialogFragment 中有一个 webview 它使用以下方式显示文档和 PDF它可以进行几次尝试 但如果用户尝试频繁打开和关闭对话框 webview 将显示空白屏幕 我已经尝试了所有的线程link1 https stacko
  • Android:单一活动,多个视图

    我不是 Android 专业人士 尽管我开发了一个包含 50 多个活动的应用程序 这使得该应用程序非常庞大 经过8周的开发 现在出现了一些问题 导致应用程序难以维护和升级 我正在处理的主要问题是 我无法将对象引用传递给活动的构造函数 事实上
  • 如何更改锁屏自定义文本(所有者信息)?

    我写了程序代码 String message This is test Settings System putString context getContentResolver Settings Secure LOCK PATTERN EN
  • 如何使 tablayout 文本大小相等?

    这就是我所做的 我为文本创建了一种样式
  • 绘制大位图时 nSyncAndDrawFrame 速度极慢

    我想用多个大位图优化视差滚动视图 在我的 Nexus 5 上 一切都很顺利 Traceview 转储如下所示 doFrame 方法大约需要 18 毫秒才能完成 但是 当使用我的 Nexus 7 或 Android 6 模拟器 Genymot

随机推荐

  • 在 python 3 中使用子进程

    我使用 subprocess 模块在 python 3 中运行 shell 命令 这是我的代码 import subprocess filename somename py in practical i m using a real fil
  • 保证静态对象的静态(常量)初始化

    最重要的问题是 程序员如何确保他的非局部静态变量是通过静态初始化而不是通过动态初始化来初始化的 由于总是进行零初始化 因此应该查看常量初始化 3 6 2 2 对象 o 的常量初始值设定项是一个常量表达式 只不过它也可以调用 constexp
  • 批处理脚本 FOR 循环仅设置输出的第一个字母 wsl --list -q

    我正在编写一个批处理脚本 将文件从 Windows 目录复制到 WSL 发行版 其中一部分是选择将文件复制到哪个发行版 如果我使用命令wsl list q如果给我以下输出 Ubuntu 22 04 Ubuntu 18 04 我正在尝试使用此
  • 从 Python 下载/安装 Windows 更新

    我正在编写一个脚本来自动安装 Windows 更新 我可以将其部署在多台计算机上 这样我就不必担心手动更新它们 我想用 Python 编写这个 但找不到任何关于如何完成此操作的信息 我需要知道如何搜索更新 下载更新并从 python 脚本安
  • 从一种数字系统转换为另一种数字系统后会有多少位数字

    主要问题 有多少位数字 让我解释 我有一个二进制数 11000000 十进制数是192 转换为十进制后 它有多少位 以十进制表示 在我的示例中 它是 3 位数字 但是 这不是问题 我在互联网上搜索并找到了一种用于整数部分的算法和一种用于小数
  • 如何防止 gulp-notify 破坏 Windows 中的 gulp-watch?

    我正在使用吞咽通知 https www npmjs org package gulp notify插入 这是我如何在 gulpfile js 中实现它的示例 您可以看到我也在使用 gutil 和 livereload 我不知道它们是否发挥任
  • 没有调用addToBackStack,片段仍然添加到backstack,为什么?

    我正在制作我的片段更换器助手类 但我遇到了一些问题 我称之为FragmentChanger 它有一个fragmentContainer 这是一个ViewGroup 其中包含我想展示的所有片段 我已经做了我自己的replace Fragmen
  • 如何在 R 中将字符串解析为层次结构或树

    有没有办法将表示组的字符串解析为 R 中的层次结构 假设我的小组结构如下 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 3 1 1 3 1 1 1 3 2 1 1 3 3 1 2 1 2 1 1 2 1 1 1 2 1 2 1
  • Android ListView setSelection() 似乎不起作用

    我有一个ListActivity实现onListItemClick 并调用doSomething 类的功能 后者包含l setSelection position where l is the ListView object 现在有一个on
  • 如何在调用 LogManager.shutdown() 后重新启动 log4j2?

    我有一种重新配置 log4j2 的方法 如下所示 LogManager shutdown SHUTDOWN log4j2 InputStream in getClass getResourceAsStream my2ndLog4j2 xml
  • GraphQL 预期可迭代,但未找到字段 xxx.yyy 的迭代

    我目前正在尝试使用 NodeJS 进行 GraphQL 但我不知道为什么以下查询会出现此错误 library name user name email 我不确定是否type of my resolveLibrary是对的 因为在任何例子中我
  • C# 数据表来保存表格(无限嵌套)

    我相对较新C 但来自C C 背景 我需要一个类似于的数据类型 类 DataTable 但允许存储的列保存 简单 类型 int float boolean string 以及相同类型的数据 以便一个列可以保存另一个表 该表也具有存储表等的列
  • 用例 - 帮助 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我是编写用例的新手 我听说用例是非技术表达 我有以下任务 我必须为其编写用例 我降低了对你理解的要求 ABC公司的注册客户使用凭据登录系统以检索
  • Wix - 自定义安装目录

    我使用的是 Wix 3 x 用户应该能够选择目标目录 我的Setup wxs目前是这样的 http pastebin com uH1EjbDQ http pastebin com uH1EjbDQ 询问用户自定义目标目录的最简单方法是什么
  • NSTimer 不触发选择器

    在带有 ARC 的 ios5 0 中 在我的 rootviewcontroller 中 我调用由应用程序委托持有的安全管理器对象中的方法 在该方法中 我设置计时器如下 NSTimer timer NSTimer scheduledTimer
  • .Net core 中的 log4net AdoNetAppender 不支持?

    我正在尝试在我们的 dot net core 1 1 2 应用程序中实现 log4net 2 0 8 ConsoleAppender 工作正常 但 AdoNetAppender 抛出错误 无法加载类型 log4net Appender Ad
  • 如何在 Antlr4 中为零参数函数编写语法

    我的函数具有参数语法 如下面的词法分析器和解析器 MyFunctionsLexer g4 lexer grammar MyFunctionsLexer FUNCTION FUNCTION NAME A Za z0 9 DOT COMMA L
  • 打印星号的 ASCII 菱形

    我的程序打印出这样的钻石 但只有当参数或菱形的每一面为4 例如如果我输入6 底部三角形的间距是错误的 我一直在试图找出答案 当参数改变时 底部的三角形不会改变 只有顶部的三角形会改变 它只适用于输入4 public static void
  • Java:在 eclipse 中导出到 .jar 文件

    我正在尝试将 Eclipse 中的程序导出到 jar 文件 在我的项目中 我添加了一些图片和 PDF s 当我导出到 jar 文件时 似乎只有main已编译并导出 我的意愿是如果可能的话将所有内容导出到 jar 文件 因为这样我想将其转换为
  • Android Web Intent 问题

    G day 免责声明 我不是 Android 开发人员 我正在对我所描述的问题进行质量检查 我用来描述这个问题的技术术语可能是错误的 我正在测试一个 Android 应用程序 该应用程序在其清单中描述它可以使用 type 的地址处理 Web