有没有一种在Android和iOS中定义某种处理机制的方法,使我可以拦截以下任意一项:
myapp:///events/3/
- or -
http://myapp.com/events/3/
我想要“监听”协议或主机,并打开相应的Activity / ViewController。
如果可能的话,我希望它们尽可能成为系统范围。我想象这在iOS上可能会成为更大的问题,但理想情况下,我希望能够从任何应用程序(Gmail、Safari等)中以超链接的形式单击这两个方案之一。
有没有一种在Android和iOS中定义某种处理机制的方法,使我可以拦截以下任意一项:
myapp:///events/3/
- or -
http://myapp.com/events/3/
我想要“监听”协议或主机,并打开相应的Activity / ViewController。
如果可能的话,我希望它们尽可能成为系统范围。我想象这在iOS上可能会成为更大的问题,但理想情况下,我希望能够从任何应用程序(Gmail、Safari等)中以超链接的形式单击这两个方案之一。
编辑于2014年5月,由于这似乎是一个热门问题,我在答案中添加了许多细节:
Android:
对于Android,请参考当自定义URI被点击时启动我的Activity的Intent Filter。
你可以使用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" />
</intent-filter>
这个附加在你想要启动的Activity上。例如:
<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>
然后,在您的Activity中,如果它没有正在运行,那么该Activity将使用Intent中传递的URI启动。
Intent intent = getIntent();
Uri openUri = intent.getData();
如果应用已经在运行中,在新的Intent中将再次调用您的Activity中的onNewIntent()方法,其中包含URI。
最后,如果您希望处理嵌入到原生应用程序中的UIWebView中的自定义协议,可以使用以下方法:
myWebView.setWebViewClient(new WebViewClient()
{
public Boolean shouldOverrideUrlLoading(WebView view, String url)
{
// inspect the url for your protocol
}
});
iOS:
对于iOS,请参考在iOS 4下使用NSURL启动APP,但在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"])
{
...
}
}
}
}
对于iOS8+中的WKWebView,你可以使用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);
}
NSUserActivity
对象,并设置应用程序以显示对应于给定URL的内容。您还需要向应用添加一个授权,列出应用程序可以处理的URL。在使用中,操作系统会负责从您的网站下载关联文件,并在有人尝试打开您的应用程序处理的URL之一时启动您的应用程序。
在安卓上设置应用链接的方法类似。首先,您需要建立您的网站和应用之间的关联,然后添加意图过滤器,让您的应用程序拦截打开您的应用程序可以处理的URL的尝试。
虽然细节显然不同,但在两个平台上的方法基本相同。它使您能够将您的应用程序插入到您的网站内容的显示中,无论哪个应用程序尝试访问该内容。
翻译后的回答:
对于iOS,你可以做两件事情:
让你的应用程序广告宣传它可以处理具有给定方案的URL。
安装协议处理程序来处理你喜欢的任何方案。
第一种选择非常简单,并在实现自定义URL方案中进行了描述。要让系统知道您的应用程序可以处理给定的方案:
更新应用程序的Info.plist文件,其中包含CFBundleURLTypes条目
在您的应用程序委托中实现-application:didFinishLaunchingWithOptions:
方法。
第二种可能性是编写自己的协议处理程序。这仅适用于您的应用程序内部,但您可以将其与上述技术结合使用。使用上面的方法使系统为给定的URL启动您的应用程序,然后在您的应用程序中使用自定义URL协议处理程序来利用iOS的URL加载系统的功能:
创建一个继承NSURLProtocol
的子类。
重写+canInitWithRequest:
-- 通常只需查看URL方案并接受与您想要处理的方案匹配的请求,但也可以查看请求的其他方面。
注册您的子类:[MyURLProtocol registerClass];
重写-startLoading
和-stopLoading
分别开始和停止加载请求。
阅读上面链接的NSURLProtocol文档以获取更多信息。这里的难度水平在很大程度上取决于您要实现的内容。iOS应用程序通常会实现自定义URL处理程序,以便其他应用程序可以进行简单的请求。实现自己的HTTP或FTP处理程序需要更多的工作。
这里提一下,PhoneGap在iOS上的工作原理正是如此。PhoneGap包含一个名为PGURLProtocol的NSURLProtocol子类,它会检查应用程序尝试加载的任何URL的方案,并在识别出其中一个方案时接管该URL。 PhoneGap的开源版本是Cordova - 你可能会发现它有帮助。http://myapp.com/events/3/