有没有一种方法可以在安卓和iOS中定义某种处理机制,允许我拦截以下任何一种:
myapp:///events/3/
- or -
http://myapp.com/events/3/
我想"监听"协议或主机,并打开相应的Activity/ViewController。
我也希望这些能尽可能全系统。我想这在iOS上会是一个更大的问题,但理想情况下,我可以从任何应用程序中以超链接的形式点击这两种方案中的任何一种。Gmail、Safari等。
2014年5月版,因为这似乎是一个流行的问题,我在答案中添加了很多细节:
安卓系统:
对于Android,请参阅单击自定义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="myapp" />
</intent-filter>
它附加到您想要启动的"活动"中。例如:
<activity android:name="com.MyCompany.MyApp.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="myapp" android:host="com.MyCompany.MyApp" />
</intent-filter>
</activity>
然后,在您的活动中,如果没有运行,则将使用Intent中传递的URI启动该活动。
Intent intent = getIntent();
Uri openUri = intent.getData();
如果已经在运行,onNewIntent()将在您的活动中被调用,并在intent中再次使用URI。
最后,如果你想处理UIWebView中托管在你的本地应用程序中的自定义协议,你可以使用:
myWebView.setWebViewClient(new WebViewClient()
{
public Boolean shouldOverrideUrlLoading(WebView view, String url)
{
// inspect the url for your protocol
}
});
iOS:
对于iOS,请参阅在iOS 4下使用URL(通过UIApplicationDelegate';s handleOpenURL)启动应用程序,但不适用于iOS 3.2。
通过Info.plist键定义您的URL方案,类似于:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.yourcompany.myapp</string>
</dict>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
然后定义一个处理程序函数,以便在应用程序代理中调用
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
// parse and validate the URL
}
如果您想在本机应用程序中托管的UIWebViews中处理自定义协议,您可以使用UIWebViewDelegate方法:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *urlPath = [request URL];
if (navigationType == UIWebViewNavigationTypeLinkClicked)
{
// inspect the [URL scheme], validate
if ([[urlPath scheme] hasPrefix:@"myapp"])
{
...
}
}
}
}
对于WKWebView(iOS8+),您可以使用WKNavigationDelegate和以下方法:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSURL *urlPath = navigationAction.request.URL;
if (navigationAction.navigationType == WKNavigationTypeLinkActivated)
{
// inspect the [URL scheme], validate
if ([[urlPath scheme] hasPrefix:@"myapp"])
{
// ... handle the request
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
}
//Pass back to the decision handler
decisionHandler(WKNavigationActionPolicyAllow);
}
更新:这是一个非常古老的问题,iOS和Android上的情况都发生了很大变化。我将在下面留下原始答案,但任何从事新项目或更新旧项目的人都应该考虑使用深度链接,这两个平台都支持。
在iOS上,深度链接被称为通用链接。您需要在网站上创建一个JSON文件,将您的应用程序与指向网站部分的URL关联起来。接下来,更新应用程序以接受NSUserActivity
对象,并设置应用程序以显示与给定URL对应的内容。您还需要向应用程序添加一个权限,列出应用程序可以处理的URL。在使用中,操作系统负责从您的网站下载关联文件,并在有人试图打开您的应用程序处理的某个URL时启动您的应用。
在Android上设置应用程序链接的工作原理类似。首先,您将在网站和应用程序之间建立关联,然后添加意向过滤器,让应用程序拦截打开应用程序可以处理的URL的尝试。
尽管细节明显不同,但两个平台上的方法基本相同。它使您能够将应用程序插入网站内容的显示中,无论哪个应用程序试图访问该内容。
原始答案:
对于iOS,是的,你可以做两件事:
让你的应用程序宣传它可以用给定的方案处理URL。
安装一个协议处理程序来处理您喜欢的任何方案。
第一个选项非常简单,在实现自定义URL方案中进行了描述。让系统知道你的应用程序可以处理给定的方案:
使用CFBundleURLTypes条目更新应用程序的Info.plist
在应用程序代理中实现
-application:didFinishLaunchingWithOptions:
。
第二种可能性是编写自己的协议处理程序。这只适用于您的应用程序,但您可以将其与上述技术结合使用。使用上面的方法让系统为给定的URL启动您的应用程序,然后在应用程序中使用自定义URL协议处理程序来利用iOS的URL加载系统的功能:
创建自己的
NSURLProtocol
子类。重写
+canInitWithRequest:
——通常您只需要查看URL方案,如果它与您想要处理的方案匹配,则接受它,但您也可以查看请求的其他方面。注册您的子类:
[MyURLProtocol registerClass];
覆盖
-startLoading
和-stopLoading
以分别启动和停止加载请求。
有关更多信息,请阅读上面链接的NSURLProtocol文档。这里的难度在很大程度上取决于你试图实现的内容。iOS应用程序通常会实现自定义URL处理程序,以便其他应用程序可以进行简单的请求。实现您自己的HTTP或FTP处理程序要稍微复杂一些。
就其价值而言,这正是PhoneGap在iOS上的工作方式。PhoneGap包括一个名为PGURLProtocol的NSURLProtocol子类,该子类查看应用程序试图加载的任何URL的方案,并在它识别的方案之一时接管。PhoneGap的开源表亲是Cordova——你可能会发现看看它很有帮助。
对于问题中的第二个选项:
http://myapp.com/events/3/
iOS 9中引入了一种新技术,称为通用链接,如果链接是https://,则可以拦截指向您网站的链接
https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/UniversalLinks.html