在Android浏览器中build立一个链接启动我的应用程序?
是否有可能build立一个链接,如:
<a href="anton://useful_info_for_anton_app">click me!</a>
导致我的安东应用程序启动?
我知道这适用于市场协议的Android电子市场应用程序,但是其他应用程序可以做类似的事情吗?
以下是启动Android Market的链接示例:
<a href="market://search?q=pname:com.nytimes.android">click me!</a>
更新:我接受eldarerathis提供的答案很好,但我只想提一下,我对<intent-filter>
标签的子元素的顺序有些问题。 我build议你简单地使用该标签中的新子元素进行另一个<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>
我想你会想看看你的Mainfest文件的<intent-filter>
元素。 具体来说,看看<data>
子元素的文档。
基本上,你需要做的是定义你自己的scheme。 有些东西是:
<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:
URIscheme开始的链接。
请不要使用你自己的定制scheme! URIscheme是一个networking全局名称空间。 你是否拥有世界范围内的“安东尼”计划? 没有? 那么不要使用它。
一种select是build立一个网站,并为该网站上的一个特定URI设置一个意图filter。 例如,这就是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,浏览器在点击的时候会尝试启动它。 要构build这样一个scheme,最好的方法是编写代码来构build你想要启动的Intent,然后打印intent.toUri(Intent.URI_INTENT_SCHEME)的结果。
您可以使用此意图的操作来查找支持该操作的任何活动。 出于安全原因,浏览器会在启动之前自动将BROWSABLE类别添加到意图中; 它也将剥离你提供的任何明确的组件,出于同样的原因。
使用这个最好的方法,如果你想确保它只启动你的应用程序,使用你自己的作用域操作,并使用Intent.setPackage()来表示意图只会匹配你的应用程序包。
两者之间的权衡:
-
http URI需要你有一个你自己的域名。 用户将始终可以select在浏览器中显示URI。 它有非常好的回退属性,如果你的应用程序没有安装,他们会简单地登陆你的网站。
-
意图URI要求您的应用程序已经安装,只有在Android手机上。 几乎允许任何意图(但总是包含BROWSABLE类别,不支持显式组件)。 他们允许你直接启动到只有你的应用程序,而无需用户的select,而不是去浏览器或任何其他应用程序。
我也面对这个问题,看到很多荒唐的页面。 我了解到,为了让您的应用可浏览,请更改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>
这对我有用,可能会帮助你。
我为推广自己道歉,但我有一个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>
一旦你有你的应用程序设置的意图和自定义urlscheme,这个接收页面顶部的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浏览器上testing过。 我不确定Firefox或Opera。 关键是即使Android浏览器不会在window.open(custom_url, '_blank')
上抛出一个很好的exception,它会失败并返回null
,您可以稍后testing。
更新:使用store_loc = "https://play.google.com/store/apps/details?id=com.raditaz";
链接到Android上的Google Play。
这是我的食谱:
创build一个静态HTML,redirect到您请求的应用程序的URL,把该网页上。
这样,就Android而言,您分享的链接是“真实”的链接(它们将是“可点击的”)。
“共享”一个常规的HTTP链接,www.your.server.com/foo/bar.html这个URL返回一个简单的8行HTML,redirect到你的应用程序的URI(window.location =“blah:// kuku”)(注意'blah'不一定是HTTP或HTTPS)。
一旦启动并运行,就可以像上面所build议的那样用所有奇特的function来扩充HTML。
这与内置的浏览器,Opera和Firefox(没有testing任何其他浏览器)的作品。 Firefox询问“这个链接需要用应用程序打开”(ok,取消)。 其他浏览器显然不担心安全性,他们只是打开应用程序,没有问题。
你可能想考虑一个库来处理你的应用程序的深层链接:
https://github.com/airbnb/DeepLinkDispatch
您可以像上面build议的人一样在注释的Activity上添加意图filter。 它将处理所有深层链接的参数的路由和parsing。 例如,你的MainActivity可能有这样的东西:
@DeepLink("somePath/{useful_info_for_anton_app}") public class MainActivity extends Activity { ... }
它也可以处理查询参数。
试试我简单的把戏:
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:true”> < – “true”值
但是这个脚本适用于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); }