我的Android应用程序中有一个WebView,其中包含一个嵌入Soundcloud(来自Embedly)。这个嵌入有两个按钮:"在Soundcloud上播放"和#34;在浏览器中收听"。
"播放Soundcloud"按钮包含格式为intent://tracks:257659076#Intent;scheme=soundcloud;package=com.soundcloud.android;end
我的WebView使用自定义的WebViewClient(因为我需要截取一些不同内容的URL)。
protected class WebViewClient extends android.webkit.WebViewClient {
public WebViewClient() { }
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
PackageManager packageManager = context.getPackageManager();
// Create an Intent from the URL.
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
// Find out if I have any activities which will handle the URL.
List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0);
// If we have an app installed that can handle the URL, then use it.
if (resolveInfoList != null && resolveInfoList.size() > 0) {
Intent viewUrlIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
context.startActivity(viewUrlIntent);
}
else {
// Do something else.
}
return true;
}
}
点击&#34;在浏览器中收听&#34;在嵌入本身播放轨道并且工作正常。点击&#34;在Soundcloud上播放&#34;将在上面的WebViewClient中调用shouldOverrideUrlLoading
(如预期的那样)。但是,我找到活动的代码无法找到任何可以处理此Soundcloud网址的内容。
如果我没有在WebView上设置我的WebViewClient(因此它只做自己的事情),那么&#34;播放Soundcloud&#34;按钮将按预期工作并启动Soundcloud应用程序。
我设法通过解析网址来获取跟踪ID,然后使用Soundcloud明确接受的格式构建新网址(感谢this SO后)。 Soundcloud应用程序将接受格式为"soundcloud://tracks:[TRACK_ID]"
的网址。
要么我正在做整个&#34;找出哪些活动可以处理这个URL&#34;事情错了,或者(?!)WebView使用的默认WebViewClient明确地处理了这个问题?!似乎难以置信。
答案 0 :(得分:1)
我只是在这里扩展临时(废话)解决方案,所以这不是一个完美的答案,但可能仍然可以帮助那些绝对需要使它正常工作的人,也可以使用私人曲目。
如果轨道是公共轨道,则replace方法有效,但对于私有轨道,则该方法无效,这可能是因为意图URL中缺少秘密令牌。
不幸的是,嵌入播放器不包含我需要生成的所有必要URL片段,除了iframe
内部,由于跨域策略我无法访问该URL。因此,除了iframe
代码之外,我还需要共享链接。
我最终要做的是确保所包含的HTML页面具有作为JS变量的共享链接。然后,我使用Java读取该变量,并使用该URL创建一个新的Intent。之所以可行,是因为官方应用程序还注册了所有soundcloud.com URL。
因此对于私人曲目,这将转到HTML页面:
<script>var soundCloudURL = "https://soundcloud.com/my-profile/my-track/my-secret-token";</script>
然后在您的Android应用程序中,您将得到以下内容:
@Override
public boolean shouldOverrideUrlLoading (WebView view, String url) {
if (uri.getScheme().contains("intent")) {
openSoundCloudPlayer();
return true;
}
}
private void openSoundCloudPlayer() {
appWebView.evaluateJavascript("(function() { return soundCloudUrl })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String soundCloudUrl) {
// JS null is converted into a string "null", not Java null.
if (soundCloudUrl != "null") {
// Take out the quotes from the string
soundCloudUrl = soundCloudUrl.replace("\"", "");
Uri newUri = Uri.parse(soundCloudUrl);
Intent intent = new Intent(Intent.ACTION_VIEW, newUri);
startActivity(intent);
}
}
});
}