【问题标题】:Open Soundcloud URL in native Soundcloud app from WebView从 WebView 在本机 Soundcloud 应用程序中打开 Soundcloud URL
【发布时间】:2016-11-30 00:32:57
【问题描述】:

场景

我的 Android 应用中有一个 WebView,其中包含一个 Soundcloud 嵌入(来自 Embedly)。此嵌入有两个按钮:“在 Soundcloud 上播放”和“在浏览器中收听”。

“在 Soundcloud 上播放”按钮包含格式为 intent://tracks:257659076#Intent;scheme=soundcloud;package=com.soundcloud.android;end 的 URL

代码

我的 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;
    }
}

问题

单击“在浏览器中收听”会在嵌入本身中播放曲目并且工作正常。单击“在 Soundcloud 上播放”将调用上面 WebViewClient 中的shouldOverrideUrlLoading(如预期的那样)。但是,我查找活动的代码找不到可以处理此 Soundcloud URL 的任何内容。

如果我没有在 WebView 上设置我的 WebViewClient(所以它只是做自己的事情),“在 Soundcloud 上播放”按钮将按预期工作并启动 Soundcloud 应用程序。

临时(废话)解决方案

通过解析 URL 以获取曲目 ID,然后使用 Soundcloud 绝对接受的格式(感谢this SO 帖子)构建一个新 URL,我已经成功地做到了这一点。 Soundcloud 应用将接受 "soundcloud://tracks:[TRACK_ID]" 格式的 URL。

但是为什么?

要么我做错了整个“找出哪些活动可以处理这个 URL”,要么(?!)WebView 使用的默认 WebViewClient 明确地处理了这个?!似乎难以置信。

【问题讨论】:

  • 我也有同样的问题,很痛苦!看来这是 SoundCloud 没有修复的错误。您可以分享您在临时解决方案中使用的链接吗?
  • 当然@Barakuda,我已经在那里编辑了问题(临时(废话)解决方案部分)。

标签: android android-webview soundcloud webviewclient


【解决方案1】:

我只是在这里扩展临时(废话)解决方案,所以这远不是一个完美的答案,但仍然可以帮助那些绝对需要让它工作的人,包括私人曲目。

如果轨道是公共的,则 replace 方法有效,但对于私有轨道,这不起作用,可能是因为意图 URL 中缺少秘密令牌。

不幸的是,嵌入播放器不包含我需要生成的所有必要的 URL 部分,除了在 iframe 内,由于跨域策略我无法访问。所以除了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);
            }
        }
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    相关资源
    最近更新 更多