从android浏览器启动自定义android应用程序


Answers:


616

<intent-filter><data>元素一起使用。例如,要处理所有指向twitter.com的链接,请将其放在您的<activity>AndroidManifest.xml

<intent-filter>
    <data android:scheme="http" android:host="twitter.com"/>
    <action android:name="android.intent.action.VIEW" />
</intent-filter>

然后,当用户在浏览器中单击指向Twitter的链接时,系统将询问他们使用哪个应用程序来完成操作:浏览器还是您的应用程序。

当然,如果要在网站和应用程序之间提供紧密的集成,则可以定义自己的方案:

<intent-filter>
    <data android:scheme="my.special.scheme" />
    <action android:name="android.intent.action.VIEW" />
</intent-filter>

然后,在您的网络应用中,您可以放置​​如下链接:

<a href="my.special.scheme://other/parameters/here">

当用户单击它时,您的应用程序将自动启动(因为它可能是唯一可以处理my.special.scheme://uris类型的应用程序)。唯一的缺点是,如果用户未安装该应用程序,则将收到一个讨厌的错误消息。而且我不确定是否有任何检查方法。


编辑:要回答您的问题,您可以使用getIntent().getData()返回一个Uri对象。然后,您可以使用Uri.*方法来提取所需的数据。例如,假设用户点击了以下链接http://twitter.com/status/1234

Uri data = getIntent().getData();
String scheme = data.getScheme(); // "http"
String host = data.getHost(); // "twitter.com"
List<String> params = data.getPathSegments();
String first = params.get(0); // "status"
String second = params.get(1); // "1234"

您可以在自己的任何位置进行上述操作Activity,但您可能会想要在其中进行onCreate()。您还可以使用params.size()获取中的路径段数Uri。请查看javadoc或android开发人员网站,Uri以获取可用于提取特定部分的其他方法。


6
非常感谢您的及时答复。但是,能否请您告诉我如何在“ my.special.scheme://”之后访问参数。
Parimal Modi 2010年

4
我已经对答案进行了编辑,以包括有关如何从Uri中提取数据的说明。如果您认为可以,请将该答案标记为已接受(仅),方法是单击其旁边的对勾标记。
Felix

9
如果未安装目标android应用程序怎么办?如何处理。
Nemo 2012年

13
像我一样,任何无法完成此计划的人都需要添加android:exported="true"Activity清单中。检查此答案stackoverflow.com/a/13044911/1276636
Sufian 2014年

4
不知道这对整个世界如何运作。只是在chrome上不起作用,它总是在浏览器中打开链接,直到您放置“ android:pathPrefix”元素。无论如何,答案没有文档中提到的类别值。如果对于某人仍然不起作用,请参阅以下内容:stackoverflow.com/a/21727055/2695276 PS:为此苦苦挣扎了好几天。
Rajat Sharma

70

CHROME截至2014年1月28日,以上所有答案均不适用于我

我的应用程序可以通过http://example.com/someresource/从环聊,gmail等应用程序中的链接正常启动,但不能从chrome浏览器中启动。

为了解决这个问题,以便它可以从CHROME正常启动,您必须像这样设置意图过滤器

<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"
        android:pathPrefix="/someresource/"
        android:scheme="http" />
    <data
        android:host="www.example.com"
        android:pathPrefix="/someresource/"
        android:scheme="http" />
</intent-filter>

注意pathPrefix元素

每当用户通过单击google搜索结果或任何其他网站的链接从chrome浏览器请求http://example.com/someresource/模式时,您的应用现在就会显示在活动选择器中


这对我有很大帮助。非常感谢!请在这里发布您的答案,以便我奖励您!stackoverflow.com/questions/21663001/...
弗拉德Schnakovszki

这是什么语言?
2014年

您好,我知道它太旧了。我在同样的情况下也感到震惊。我指定了pathPrefix,方案和主机,但是它不起作用。我只尝试了方案,然后成功了。但是当我添加主机时,它停止工作。知道是什么问题吗?
Seema 2014年

花了几天的时间,直到我得到这个答案。不知道没有pathPrefix元素时,它如何在整个世界中发挥作用。尽管按照文档进行了所有操作,但从未在Chrome上为我工作过。非常感谢。
Rajat Sharma

66

请在此处查看我的评论:在Android浏览器中建立链接以启动我的应用程序?

我们强烈建议人们不要使用自己的方案,除非他们正在定义新的全球互联网方案。


10
Hackbod是Android平台背后的Google工程师之一。遵循此建议可能是一个好主意。实际上,像在Honeycomb中这样的自定义方案支持似乎已中断。
nmr

23
对于iOS对开发人员施加的限制,我概不负责。;)
Hackbod 2012年

12
负责任?没有。但您可以考虑到这一点,因为无论您是否喜欢,这些限制都强加于您的许多开发人员
ByteMe 2012年

6
hackbod正在回答一个专门针对Android的问题。没有提及iOS,因此无需考虑它。
nilskp

4
如果假设可以在不同的网站上找到类似的链接,@hackbod会为一个方案命名空间(即href =“ com.ourdomain.myapp // whatever”)是一个好习惯。
JulienBérubé2012年

48

就我而言,我必须为设置两个类别<intent-filter>,然后它才起作用:

<intent-filter>
<data android:scheme="my.special.scheme" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>

2
此处相同,需要添加其他类别。
KPK 2012年

有人可以解释完成此操作的实际过程吗?任何链接到确切的实现,先决条件将是有帮助的。谢谢
Ankit Garg

测试开发设置。实际上,我输入了错误的域名。我的错。
Ankit Garg

评分最高的答案对我不起作用,但确实如此。谢谢。
EL45 2014年

25

例如,您有接下来的事情:

打开您的应用的链接:http : //example.com

您应用的程序包名称:com.example.mypackage

然后,您需要执行以下操作:

1)在活动中添加一个意图过滤器(可以是您想要的任何活动。有关更多信息,请参见文档)。

        <activity
        android:name=".MainActivity">

        <intent-filter android:label="@string/filter_title_view_app_from_web">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <!-- Accepts URIs that begin with "http://example.com" -->

            <data
                android:host="example.com"
                android:scheme="http" />
        </intent-filter>

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

    </activity> 

2)创建一个HTML文件来测试链接或使用此方法。

<a href="intent://example.com#Intent;scheme=http;package=com.example.mypackage;end">Open your Activity directly (just open your Activity, without a choosing dialog). </a>

<a href="http://example.com">Open this link with browser or your programm (by choosing dialog).</a>

3)使用Mobile Chrome进行测试

4)就这样。

并且不必在市场上发布应用程序来测试深层链接=)

另外,有关更多信息,请查看文档和有用的演示文稿


我必须创建html文件并上传它才能正常工作。我想知道为什么(尤其是第二个)无法直接在浏览器(chrome)中运行。
Makalele,2017年

18

还应该将其<category android:name="android.intent.category.BROWSABLE"/>添加到意图过滤器,以使活动可以正确地从链接中识别出来。


4
作为参考,添加CATEGORY_BROWSABLE意味着“浏览器可以安全地调用目标活动,以显示链接引用的数据-例如图像或电子邮件。”
greg7gkb

这是现有类别还是您要提出一个新类别?
阿尼什(Anish)2012年

它存在。显然,您应该在不同的Intent-Filter标签中拥有单独的网站托管服务,否则会导致问题。
NoBugs 2012年

2
不但可以浏览,而且还可以android.intent.category.DEFAULT-因此,可以在其他应用程序中启动链接时打开链接,例如电子邮件(不仅是浏览器)
AlikElzin-kilaka


7

请注意,实现此功能时,如果您的图标从android启动器中消失了,则必须拆分intent-filter。

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <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" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="your-own-uri" />
        </intent-filter>
    </activity>


5

Xamarin 费利克斯港的答案

在您的中MainActivity,添加以下内容(docs:Android.App.IntentFilterAttribute Class):

....
[IntentFilter(new[] { 
    Intent.ActionView }, 
    Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, 
    DataScheme = "my.special.scheme")
]
public class MainActivity : Activity
{
    ....

Xamarin将为您添加以下内容AndroidManifest.xml

<activity
    android:label="Something"
    android:screenOrientation="portrait"
    android:theme="@style/MyTheme"
    android:name="blah.MainActivity">
    <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="my.special.scheme" />
    </intent-filter>
</activity>

为了获取参数(我在MainActivity的OnCreate中进行了测试):

var data = Intent.Data;
if (data != null)
{
    var scheme = data.Scheme;
    var host = data.Host;
    var args = data.PathSegments;

    if (args.Count > 0)
    {
        var first = args[0];
        var second = args[1];
        ...
    }
}

据我所知,以上内容可以添加到任何活动中,而不仅仅是MainActivity

笔记:

  1. 当用户单击链接时,Android OS将重新启动您的应用程序(杀死前一个实例,如果有的话,然后运行新实例),这意味着该OnCreate应用程序的事件MainLauncher Activity将再次被触发。
  2. 通过此链接:<a href="my.special.scheme://host/arg1/arg2">,在以上最后一个代码中,代码段值将为:
scheme: my.special.scheme
host: host
args: ["arg1", "arg2"]
first: arg1
second: arg2

更新:如果android创建您的应用程序的新实例,您也应该添加android:launchMode="singleTask"


3

Felix处理深层链接的方法是处理深层链接的典型方法。我还建议您检查该库以处理深层链接的路由和解析:

https://github.com/airbnb/DeepLinkDispatch

您可以使用批注为特定的深层链接URI注册您的Activity,它将为您提取参数,而无需执行获取路径段,匹配之类的通常繁琐的工作。您可以像这样简单地批注和activity :

@DeepLink("somePath/{someParameter1}/{someParameter2}")
public class MainActivity extends Activity {
   ...
}

0

嘿,我找到了解决方案。我没有将类别设置为“默认”。另外,我还在针对意图数据使用Main活动。现在,我对意图数据使用了不同的活动。谢谢您的帮助。:)


听起来不太可能(尽管我认识到这是一个老问题,也许情况已经发生了变化。)来自developer.android.com/guide/components/intents-filters.html#ifs “要通过类别测试的意图是, “ Intent 对象必须与过滤器中的类别匹配。过滤器可以列出其他类别,但不能忽略该意图中的任何类别。”
Noach Magedman

0

您需要将伪主机名添加到CALLBACK_URL'app://'作为URL没有意义,因此无法解析。


0

example.php:

<?php
if(!isset($_GET['app_link'])){  ?>   
    <iframe src="example.php?app_link=YourApp://blabla" style="display:none;" scrolling="no" frameborder="0"></iframe>
    <iframe src="example.php?full_link=http://play.google.com/xyz" style="display:none;" scrolling="no" frameborder="0"></iframe>
    <?php 
}
else { ?>
    <script type="text/javascript">
    self.window.location        = '<?php echo $_GET['app_link'];?>';
    window.parent.location.href = '<?php echo $_GET['full_link'];?>';
    </script>
<?php 
}

1
这会创建两个不可见的iframe:深层链接和普通链接。如果安装了该应用程序,则深层链接iframe将启动它。如果不是,则显示普通链接。通过一些额外的工作,可以在安装应用程序后调用深度链接的地方实现延迟的深度链接。
Dominic Cerisano

0

这里查看@JRuns答案。这个想法是用您的自定义方案创建html并将其上传到某个地方。然后,如果您单击html文件上的自定义链接,您将被重定向到您的应用程序。我将这篇文章用于android。但是不要忘记为Name = "MyApp.Mobile.Droid.MainActivity"目标活动设置全名属性。


0

截至15/06/2019

我所做的是包括所有四个打开URL的可能性。

即,带有http/ https和2 www的前缀,而带有2 的前缀www

通过使用此程序,我的应用程序现在可以自动启动,而无需我选择浏览器和其他选项。

<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="https" android:host="example.in" />
    <data android:scheme="https" android:host="www.example.in" />
    <data android:scheme="http" android:host="example.in" />
    <data android:scheme="http" android:host="www.example.in" />

</intent-filter>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.