【问题标题】:Make a link in the Android browser start up my app?在 Android 浏览器中创建一个链接来启动我的应用程序?
【发布时间】:2011-03-29 01:08:59
【问题描述】:

是否可以做如下链接:

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

导致我的 Anton 应用启动?

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

以下是启动 Android 电子市场的链接示例:

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

更新: 我接受 eldarerathis 提供的答案效果很好,但我只想提一下,&lt;intent-filter&gt; 标记的子元素的顺序有一些问题。我建议您只需使用该标签中的新子元素创建另一个&lt;intent-filter&gt;,以避免我遇到的问题。例如我的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>

【问题讨论】:

  • 这解决了我无法在手机中打开应用程序的问题。
  • +1 用于提及 xml 标签的顺序。这绝对没有意义,也没有在任何地方记录,但我发现当我在操作和类别标签下方有数据标签时,它根本不起作用。
  • 重定向到应用程序并在应用程序不存在时正确回退也可能是一场噩梦,因为所有不同 Android 浏览器(Chrome、Default、Webviews、Firefox 等)的复杂性)。 branch.io 服务有助于做到这一点并且是免费的。
  • @Anton ....您好先生...通过您上面的代码,我只知道处理来自链接的数据...您能告诉我如何创建一个链接包含我的数据...请帮助我...我想在按钮单击事件上创建带有数据的链接..
  • ⚠️我遇到了其他人可能也想知道的调试障碍:链接从网页中的 链接以及使用 adb 启动时起作用,但现在当您只需在移动浏览器地址栏中输入 URL。⚠️

标签: android


【解决方案1】:

请不要像这样使用您自己的自定义方案!!! 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:”方案。这允许您将几乎任何 Intent 描述为 URI,浏览器将在单击时尝试启动该 URI。要构建这样的方案,最好的方法是只编写代码来构建您要启动的Intent,然后打印intent.toUri(Intent.URI_INTENT_SCHEME)的结果。

您可以使用具有此意图的操作来查找支持该操作的任何活动。出于安全原因,浏览器会在启动前自动将 BROWSABLE 类别添加到意图中;出于同样的原因,它还会删除您提供的任何显式组件。

如果你想确保它只启动你的应用程序,最好的使用方法是使用你自己的作用域操作并使用 Intent.setPackage() 表示 Intent 将只匹配你的应用程序包。

两者之间的权衡:

  • http URI 要求您拥有自己的域。用户将始终可以选择在浏览器中显示 URI。它具有非常好的后备属性,如果您的应用未安装,它们只会登陆您的网站。

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

【讨论】:

  • 另一方面,市场应用也处理market://链接:)
  • 使用 market: 是错误的,正在删除。
  • 人们在Android中使用自定义方案的原因是因为大多数项目都是与iPhone版本(或之后)并行开发的,这是使它在那里工作的唯一方法......
  • 同意@LambergaR。现在我们需要找到一种方法来让电子邮件中的链接在 3 个平台(BB、iphone、Android)上工作
  • 您在网页中使用自定义方案放置的任何 URI 将无法在任何未安装您的应用程序的 Web 浏览器上运行。你不觉得这很糟糕吗?
【解决方案2】:

我想你会想看看你的清单文件的&lt;intent-filter&gt; 元素。具体来说,请查看&lt;data&gt; 子元素的文档。

基本上,您需要做的是定义自己的方案。大致如下:

<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 方案开头的链接启动您的应用程序。

【讨论】:

  • 尝试看看这个线程。它有一个很好的例子:stackoverflow.com/questions/2958701/…
  • 作为参考,添加 CATEGORY_BROWSABLE 意味着“浏览器可以安全地调用目标 Activity 以显示链接引用的数据——例如,图像或电子邮件消息。”
  • 这在以前的 android 版本上完美运行,但在棒棒糖上不行,有什么解决方案吗?
  • @eldarerathis 如果应用程序关闭但如果应用程序在后台运行并且活动与附加意图过滤器的活动不同,我无法处理它。您如何管理它以在所有活动中发挥作用?您是否将意图过滤器放入所有这些中?
  • 此答案已过时..这在 chrome 40 后将不起作用。由于安全问题,自定义方案已在 chrome 中禁用
【解决方案3】:

我很抱歉推销自己,但我有一个 jQuery 插件可以从网络链接启动本地应用程序 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>

【讨论】:

    【解决方案4】:

    我也遇到过这个问题,看到很多荒谬的页面。我了解到要使您的应用程序可浏览,请更改 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 时无法打开选择器对话框。
    • 我没有看到太大的不同,如果我使用这个,它工作得很好。谢谢:)
    【解决方案5】:

    这是我的食谱:

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

    这样,就 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 页面,该链接重定向到我的应用程序。我的链接是&lt;a href="iamnearby://register_activate"&gt;Activate&lt;/a&gt;
    【解决方案6】:

    一旦你为你的应用设置了意图和自定义 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。

    【讨论】:

    • loadDateTime/timeOutDateTime 的意义何在?这是否以某种方式绕过弹出窗口阻止程序或其他什么?
    • 这在我的测试中似乎不起作用,window.open(...) 将始终打开一个新窗口,即使该方案未处理。
    • @MattWolfe 抱歉回复晚了。在 iPhone (Safari) 上不会引发异常。超时用于关闭页面重定向到应用程序后剩余的 Safari 中的陈旧窗口。我还没有找到一种方法可以在不通过 Safari 的情况下打开 url,而大多数其他识别此类 url 的应用程序都会做同样的事情。这是来自 Facebook 的“深度链接”的优势之一:您不会通过移动 Safari 获得那个陈旧的剩余窗口。
    • @jtomson:很有趣。我在模拟器和从 Android 2.1 到 3(当时)的各种设备上进行了测试。您在什么设备和 Android 版本上进行测试?
    【解决方案7】:

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

    https://github.com/airbnb/DeepLinkDispatch

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

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

    它也可以处理查询参数。

    【讨论】:

      【解决方案8】:

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

      如果您在 Manifest 中注册以下内容

      <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 包来查找响应您的 gallery 意图并具有 myApp 方案的应用程序。如果不能,它会将您带到商店,寻找 com.myApp,这应该是您的应用程序。

      【讨论】:

      • 如何进入安卓活动?
      • 清单中指定的 将打开,因为它是附加了 的那个
      • 如何在手机上发短信?
      【解决方案9】:

      试试我的简单技巧:

              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>
      

      或者你可以为类文件名设置

      但是这个脚本适用于 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,这是正确的解决方法。
      【解决方案10】:

      只是想通过浏览器打开应用程序?您可以使用以下代码实现它:

      HTML:

      <a href="intent:#Intent;action=packageName;category=android.intent.category.DEFAULT;category=android.intent.category.BROWSABLE;end">Click here</a>
      

      清单:

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

      这个意图过滤器应该在 Launcher Activity 中。

      如果您想在浏览器链接点击时传递数据,请参考this link

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-02-21
        • 1970-01-01
        • 2011-06-05
        • 2012-06-20
        • 1970-01-01
        相关资源
        最近更新 更多