使用intent-filter从URL打开Android应用程序无法正常工作

38
我有一个安卓应用程序,人们使用它作为网站的替代品。因此,当用户遇到指向该网站的URL时,我希望给他们提供“在我的应用程序中打开该URL”的选项,而不是在浏览器中打开。换句话说,我想让弹出窗口出现,让他们选择我的应用程序和浏览器(以及可能的其他应用程序)之间的区别。
我从各种来源了解到,我需要在我的应用程序中添加一个意图过滤器,该过滤器具有筛选正确形式的URL的“数据”过滤器。
所涉及的网站是http://members.iracing.com,因此我已添加了以下意图过滤器:
    <activity
        android:name=".MainActivity"
        android:label="@string/title_activity_main" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="http" />
            <data android:host="members.iracing.com" />
        </intent-filter>
    </activity>

我尝试过各种形式的数据筛选器,比如使用一个带有两个属性的单一“data”节点:

        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="http" android:host="members.iracing.com"/>
        </intent-filter>

这根本不起作用。我不知道还有什么可以告诉你的了。我在我的网站上托管了一个简单的HTML页面,其中包含一些链接到该网站上的各个页面(所有页面都以“http://members.iracing.com/...”开头),当我单击其中任何一个时,它们只是在浏览器中打开,而不会询问我要使用哪个应用程序。我尝试在模拟器上和在我的物理设备上安装应用程序后进行操作,但都没有起作用。我甚至在一个全新的空白Android项目中尝试了这个操作,结果还是没有反应。
然后我意识到该网站需要身份验证,如果您未登录,则会将其重定向到https://members.iracing.com/membersite/login.jsp的登录页面,因此我尝试将方案替换为“https”。我甚至尝试将主机更改为“www.members.iracing.com”,最后我甚至尝试了所有这些事情的组合(不确定是否应该这样做,但嘿,我现在很绝望.....)
       <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="http" />
            <data android:scheme="https" />
            <data android:host="members.iracing.com" />
            <data android:host="www.members.iracing.com" />
        </intent-filter>

依然无法成功。我不确定重定向是否相关,但是浏览器显然首先到达非重定向站点,然后才重定向到登录页,但我在任何时候都没有选择在我的应用程序中打开它的选项。此外,如果我在浏览器中手动登录,就没有重定向,但仍然无法正常工作。

我是否漏掉了一些明显的东西?我为什么不能让它工作,我无法调试它,除了尝试我能想到的每种可能组合(我试过了...)。感谢您提供任何帮助!


http://developer.android.com/guide/components/intents-filters.html => 我认为您可能需要一个MIME类型和一个权限。https://dev59.com/7HA85IYBdhLWcg3wD_O8 => 您可能需要删除该类别。 - njzk2
1
此外,在应用程序的设置中管理事项时,请检查您的浏览器是否未被选为默认的 HTTP 应用程序。 - njzk2
请注意,现在Android Studio提供了内置编辑器。https://developer.android.com/studio/write/app-link-indexing.html - Dani
3个回答

66

我觉得我应该在这里发布这篇文章,因为我花了很多时间研究为什么我的意图过滤器没有起作用。事实证明,它一直在工作,但匹配必须是完全相同的。因此,如果您为http://myexample.com注册意图,并单击http://myexample.com/blah,它将无法正常工作。

添加以下内容即可解决问题:

<data android:pathPattern="/.*" />

因此,意图过滤器看起来像:

<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:host="example.com" />
            <data android:scheme="https" />
            <data android:pathPattern="/.*" />
</intent-filter>

37

在你的<intent filter>中使用这三个。

<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

这些是意图过滤器中唯一需要的内容吗?因为我正在尝试在模拟器上使用twitter.com,但它无法启动twitter应用程序。 - Jake
3
这会拦截任何网站吗? - Luis
为了指定特定的站点,您需要添加以下标签 <data android:host="callback" android:scheme="x-oauthflow-schema" /> 以及上面的标签。 - Anuj
@Jake,你不能使用这个来启动其他应用程序。OP正在尝试启动自己的应用程序。 - tir38

10

@nurieta,你的答案对我太有帮助了,谢谢!

顺便给你一个建议,因为我正在处理可能的查询字符串,我通过在 .java 文件中添加一些代码来处理它,以确定是只打开应用程序还是将您发送到应用程序中的特定位置。我的应用程序只是运行 JQuery 移动应用程序的 WebView。

    if(getIntent().getData()!=null){//check if intent is not null
        Uri data = getIntent().getData();//set a variable for the Intent
        String scheme = data.getScheme();//get the scheme (http,https)
        String fullPath = data.getEncodedSchemeSpecificPart();//get the full path -scheme - fragments

        combine = scheme+"://"+fullPath; //combine to get a full URI
    }

    String url = null;//declare variable to hold final URL
    if(combine!=null){//if combine variable is not empty then navigate to that full path
        url = combine;
    }
    else{//else open main page
        url = "http://www.example.com";
    }
    webView.load(url);

2
应该是 scheme+":"+fullPath; 吧? - lf215
代码对我来说非常好用。我不得不删除if语句,因为我遇到了一个问题,它总是为空。 - A P
更简单的方法是使用getIntent().getData().toString()。 - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接