在Android浏览器中建立链接以启动我的应用程序吗?


229

是否可以建立一个链接,例如:

<a href="anton://useful_info_for_anton_app">click me!</a>

使我的Anton应用启动?

我知道这适用于具有市场协议的Android Market应用程序,但是其他应用程序可以做类似的事情吗?

这是一个将启动Android Market的链接的示例:

<a href="market://search?q=pname:com.nytimes.android">click me!</a>

更新: eldarerathis提供的我接受的答案很好用,但我只想提及<intent-filter>标签的子元素顺序有些麻烦。我建议您只是<intent-filter>使用该标签中的新子元素来简化另一个操作,以避免出现我的问题。例如我AndroidManifest.xml看起来像这样:

<activity android:name=".AntonWorld"
          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>
        <data android:scheme="anton" />
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.BROWSABLE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

当我无法在手机中打开应用程序时,这解决了我的问题。
Unomono13年

9
+1表示xml标记的顺序。它绝对没有任何意义,也没有任何文档,但是我发现,当我在action和category标签下面放置数据标签时,这简直是行不通的。
亚当

鉴于所有不同的Android浏览器(Chrome,Default,Webviews,Firefox等)的复杂性,重定向到该应用程序并正确退回(如果该应用程序不存在时)也可能是一场噩梦。该branch.io服务有助于做到这一点,是免费的。
Alex Austin

@Anton .... hello先生...根据您的上述代码,我只了解处理链接中的数据...请告诉我如何创建包含我的数据的链接...请帮助我......我想创建按钮单击事件与数据链接..
拉温德拉Kushwaha

1
⚠️我遇到了其他人可能也要意识到的调试障碍:链接可从网页中的<a href="">链接以及使用adb启动时起作用,但是现在您只需在移动设备中键入URL浏览器的地址bar.⚠️
约翰内斯Brodwall

Answers:


96

我认为您将需要查看<intent-filter>Mainfest文件的元素。具体来说,请查看该<data>子元素的文档。

基本上,您需要做的就是定义自己的方案。类似于以下内容:

<intent-filter>
    <data android:scheme="anton" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" /> <--Not positive if this one is needed
    ...
</intent-filter>

然后,您应该能够使用以anton:URI方案开头的链接启动您的应用程序。


3
尝试看看这个线程。它有一个很好的例子:stackoverflow.com/questions/2958701/...
eldarerathis

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

3
这可以在以前的Android版本上完美运行,但不能在棒棒糖上运行,有解决方案吗?
2015年

1
@eldarerathis如果应用程序关闭,但如果应用程序在后台运行并且活动与附加了意图过滤器的活动不同,则无法运行,则此方法有效。在所有活动中,您如何管理这项工作?您是否将意图过滤器放入所有这些过滤器?
穆斯塔法·古文(MustafaGüven)2015年

5
这个答案已经过时了。.此功能在chrome 40之后无法使用。由于安全问题,chrome中的自定义方案已被禁用
Utsav Gupta

280

请不要使用您自己的自定义方案!URI方案是网络全局名称空间。您是否在全球范围内拥有“ anton:”计划?没有?然后不要使用它。

一种选择是拥有一个网站,并为该网站上的特定URI提供一个意图过滤器。例如,以下是Market在其网站上拦截URI的操作:

        <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="market.android.com"
                android:path="/search" />
        </intent-filter>

或者,有“意图:”方案。这使您几乎可以将任何Intent描述为URI,单击该浏览器将尝试将其启动。要构建这样的方案,最好的方法是只编写代码以构造要启动的Intent,然后打印intent.toUri(Intent.URI_INTENT_SCHEME)的结果。

您可以将操作用于此目的,以查找支持该操作的任何活动。为了安全起见,浏览器将在启动意图之前自动将BROWSABLE类别添加到意图。它也会删除出于相同原因提供的所有显式组件。

如果要确保仅启动应用程序,使用此方法的最佳方法是使用自己的作用域操作,并使用Intent.setPackage()表示Intent仅与您的应用程序包匹配。

两者之间的权衡:

  • http URI要求您拥有一个域。用户将始终获得在浏览器中显示URI的选项。它具有很好的备用属性,如果未安装您的应用程序,它们将仅登陆您的网站。

  • 意向URI要求您的应用程序已经安装并且只能在Android手机上安装。允许几乎所有意图(但始终包括BROWSABLE类别,并且不支持显式组件)。它们允许您将启动仅定向到您的应用程序,而用户没有选择转到浏览器或任何其他应用程序的选项。


32
另一方面,Market应用程序还处理market://链接:)
Felix

38
使用市场是错误的,并且已被删除。
hackbod 2011年

82
人们之所以在Android中使用自定义方案,是因为大多数项目都是与iPhone版本(或之后)并行开发的,这是使其在iPhone上正常工作的唯一方法……
LambergaR 2011年

12
同意@LambergaR。现在,我们需要找到一种在3个平台(BB,iphone,Android)的电子邮件中建立链接的方法
Maragues 2011年

7
您使用自定义方案放置在网页中的任何URI在未安装您的应用程序的任何网络浏览器上均不起作用。这对您来说似乎不合算吗?
hackbod 2011年

13

我为提升自己而表示歉意,但是我有一个jQuery插件,可以从Web链接https://github.com/eusonlito/jquery.applink启动本机应用程序

您可以轻松使用它:

<script>
$('a[data-applink]').applink();
</script>

<a href="https://facebook.com/me" data-applink="fb://profile">My Facebook Profile</a>

12

我也遇到了这个问题,看到了许多荒谬的页面。我了解到,要使您的应用程序可浏览,请更改XML元素的顺序,如下:

<activity
    android:name="com.example.MianActivityName"
    android:label="@string/title_activity_launcher">

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

    <intent-filter>                
        <data android:scheme="http" />     
        <!-- or you can use deep linking like  -->               

        <data android:scheme="http" android:host="xyz.abc.com"/>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <category android:name="android.intent.category.DEFAULT"/>

    </intent-filter>
</activity>

这对我有用,可能对您有帮助。


我以相同的顺序编写XML标签,但是在android浏览器中编写url时却无法打开选择器对话框。
Sunit Kumar Gupta

我没有看到太大的不同,如果我使用它,它工作得很好..谢谢:)
Muthu S

6

这是我的食谱:

创建一个静态HTML重定向到您请求的应用程序URL,然后将该页面放到网络上。

这样,就Android而言,您共享的链接是“真实”链接(它们将是“可点击的”)。

您“共享”常规HTTP链接www.your.server.com/foo/bar.html,该URL返回一个简单的8行HTML,该HTML重定向到您应用的URI(window.location =“ blah:// kuku”)(请注意,“ blah”不再必须是HTTP或HTTPS)。

一旦启动并运行,就可以使用上面建议的所有功能来扩展HTML。

这可与内置浏览器,Opera和Firefox(尚未测试任何其他浏览器)一起使用。Firefox询问“此链接需要使用应用程序打开”(确定,取消)。其他浏览器显然并不担心安全性,他们只是打开应用程序而没有任何问题。


大!它为我工作。因此,我们添加了html页面,并带有指向重定向到我的应用程序的自定义方案的链接。我的链接是<a href="iamnearby://register_activate">Activate</a>
S. Koshelnyk,

4

在为您的应用设置好意图和自定义url方案后,接收页面顶部的以下javascript代码对我适用于iOS和Android:

<script type="text/javascript">
// if iPod / iPhone, display install app prompt
if (navigator.userAgent.match(/(iPhone|iPod|iPad);?/i) ||
    navigator.userAgent.match(/android/i)) {
  var store_loc = "itms://itunes.com/apps/raditaz";
  var href = "/iphone/";
  var is_android = false;
  if (navigator.userAgent.match(/android/i)) {
    store_loc = "https://play.google.com/store/apps/details?id=com.raditaz";
    href = "/android/";
    is_android = true;
  }
  if (location.hash) {
    var app_loc = "raditaz://" + location.hash.substring(2);
    if (is_android) {
      var w = null;
      try {
        w = window.open(app_loc, '_blank');
      } catch (e) {
        // no exception
      }
      if (w) { window.close(); }
      else { window.location = store_loc; }
    } else {
      var loadDateTime = new Date();
      window.setTimeout(function() {
        var timeOutDateTime = new Date();
        if (timeOutDateTime - loadDateTime < 5000) {
          window.location = store_loc;
        } else { window.close(); }
      },
      25);
      window.location = app_loc;
    }
  } else {
    location.href = href;
  }
}
</script>

仅在Android浏览器上对此进行了测试。我不确定Firefox或Opera。关键是,即使Android浏览器不会在您身上抛出异常window.open(custom_url, '_blank'),它也会失败并返回null,您可以稍后进行测试。

更新:store_loc = "https://play.google.com/store/apps/details?id=com.raditaz";用于链接到Android上的Google Play。


1
loadDateTime / timeOutDateTime的意义是什么?这会以某种方式绕过弹出窗口阻止程序吗?
马特·沃尔夫

这在我的测试中似乎不起作用,即使未处理该方案,window.open(...)也会始终打开一个新窗口。
jtomson 2012年

@MattWolfe很抱歉回复晚。在iPhone(Safari)上,不会引发异常。超时可以关闭页面中重定向到应用程序后剩下的Safari中的陈旧窗口。我还没有找到一种无需浏览Safari就可以打开网址的方法,而大多数其他识别此类网址的应用程序也可以做到这一点。那是来自Facebook的“深度链接”的优点之一:通过移动Safari浏览器,您不会得到过时的剩余窗口。
皮特

@jtomson:有趣。我在模拟器和Android 2.1到3的各种设备上进行了测试(当时)。您正在测试什么设备和Android版本?
皮特

4

您可能需要考虑使用一个库来处理指向您应用的深层链接:

https://github.com/airbnb/DeepLinkDispatch

您可以像上面建议的人员一样在带注释的活动上添加意图过滤器。它将处理所有深层链接的参数路由和解析。例如,您的MainActivity可能具有以下内容:

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

它还可以处理查询参数。


1

试试我的简单技巧:

        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if(url.startsWith("classRegister:")) {                  
                Intent MnRegister = new Intent(getApplicationContext(), register.class); startActivity(MnRegister);
            }               
            view.loadUrl(url);
            return true;
        }

和我的HTML链接:

<a href="classRegister:true">Go to register.java</a>

或者你可以做的<a href =“classRegister:真正 ”> <! - “真”的类文件名值

但是此脚本适用于mailto链接:)

        if (url.startsWith("mailto:")) {
            String[] blah_email = url.split(":");
            Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
            emailIntent.setType("text/plain");
            emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{blah_email[1]});
            emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, what_ever_you_want_the_subject_to_be)");
            Log.v("NOTICE", "Sending Email to: " + blah_email[1] + " with subject: " + what_ever_you_want_the_subject_to_be);
            startActivity(emailIntent);
        }

从本质JavascriptInterface上讲,这是对解决方法的调用,如果您需要支持JavascriptInterface受到错误影响的2.3,则这是正确的解决方法。
EpicPandaForce 2015年

1

此方法不会调用要求您打开应用程序或浏览器的消歧对话框。

如果您在清单中注册以下内容

<manifest package="com.myApp" .. >
  <application ...>
    <activity ...>
      <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="gallery"
          android:scheme="myApp" />
      </intent-filter>
    </activity>
    ..

然后从您手机上的电子邮件中单击此网址

<a href="intent://gallery?directLink=true#Intent;scheme=myApp;package=com.myApp;end"> 
  Click me 
</a>

然后android会尝试查找包含com.myApp包的应用,该应用可响应您的画廊意图并具有myApp方案。万一不能,它将带您到商店,寻找com.myApp,它应该是您的应用程序。


如何进行android活动?
Mohsen Emami
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.