Android 从WebView打开本机Soundcloud应用程序中的Soundcloud URL 脚本

Android 从WebView打开本机Soundcloud应用程序中的Soundcloud URL 脚本,android,android-webview,soundcloud,webviewclient,Android,Android Webview,Soundcloud,Webviewclient,我的Android应用程序中有一个WebView,其中包含一个Soundcloud嵌入(来自Embedly)。此嵌入有两个按钮:“在Soundcloud上播放”和“在浏览器中收听” “在Soundcloud上播放”按钮包含格式为intent://tracks:257659076#Intent;方案=声云;package=com.soundcloud.android;结束 代码 我的WebView使用自定义WebViewClient(因为我需要截取一些不同内容的URL) 受保护类WebViewCl

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

“在Soundcloud上播放”按钮包含格式为
intent://tracks:257659076#Intent;方案=声云;package=com.soundcloud.android;结束

代码 我的WebView使用自定义WebViewClient(因为我需要截取一些不同内容的URL)

受保护类WebViewClient扩展了android.webkit.WebViewClient{
公共WebViewClient(){}
@凌驾
公共布尔值shouldOverrideUrlLoading(WebView视图,字符串url){
PackageManager PackageManager=context.getPackageManager();
//从URL创建意图。
Intent Intent=newintent(Intent.ACTION_视图,Uri.parse(url));
//了解我是否有处理URL的任何活动。
List resolveInfoList=packageManager.QueryInputActivities(intent,0);
//如果我们安装了一个可以处理URL的应用程序,那么就使用它。
if(resolveInfoList!=null&&resolveInfoList.size()>0){
Intent viewUrlIntent=新的Intent(Intent.ACTION_视图,Uri.parse(url));
上下文。起始触觉(viewUrlIntent);
}
否则{
//做点别的。
}
返回true;
}
}
问题 单击“在浏览器中收听”将在“嵌入”中播放曲目,效果良好。单击“在Soundcloud上播放”将调用上述WebViewClient中的
shouldOverrideUrlLoading
(如预期)。但是,我的查找活动的代码找不到任何可以处理此Soundcloud URL的内容

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

临时(垃圾)解决方案 通过解析URL以获取曲目ID,然后使用Soundcloud明确接受的格式构建一个新的URL(感谢SO post),我已经成功地做到了我希望它做到的事情。格式为
“s的URLoundcloud://tracks:[TRACK_ID]“
将被Soundcloud应用程序接受

但是为什么呢?
要么我在做“找出哪些活动可以处理这个URL”的事情,要么可能(?!)WebView使用的默认WebViewClient显式地处理这个问题?!似乎难以置信。

我只是在这里扩展临时(垃圾)解决方案,所以这远不是一个完美的答案,但可能仍然有助于绝对需要让它工作的人,也有私人轨道

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

不幸的是,嵌入播放器没有包含我需要生成的URL的所有必要部分,除了
iframe
内部,由于跨源策略,我无法访问该URL。因此,除了
iframe
代码之外,我还需要共享链接

我最后要做的是确保包含HTML页面的共享链接作为JS变量。然后,我使用Java读取该变量,并使用该URL创建一个新的意图。这是可行的,因为官方应用程序也会注册所有soundcloud.com URL

因此,对于私人曲目,请转到HTML页面:

var soundCloudURL=”https://soundcloud.com/my-profile/my-track/my-secret-token";
然后在你的Android应用程序中,你会有如下内容:

@覆盖
公共布尔值shouldOverrideUrlLoading(WebView视图,字符串url){
if(uri.getScheme()包含(“意图”)){
openSoundCloudPlayer();
返回true;
}
}
私有void openSoundCloudPlayer(){
evaluateJavascript((函数(){return soundCloudUrl})(;”,new ValueCallback(){
@凌驾
public void onReceiveValue(字符串soundCloudUrl){
//JS null被转换为字符串“null”,而不是Java null。
if(soundCloudUrl!=“null”){
//从字符串中去掉引号
soundCloudUrl=soundCloudUrl.replace(“\”,”);
urinewuri=Uri.parse(soundCloudUrl);
意图=新意图(Intent.ACTION\u视图,newUri);
星触觉(意向);
}
}
});
}

我有完全相同的问题,这是一个痛苦的问题!这似乎是SoundCloud没有修复的错误。你能分享你在临时解决方案中使用的链接吗?当然可以@Barakuda,我在那里编辑了这个问题(临时(垃圾)解决方案部分)。
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;
    }
}
<script>var soundCloudURL = "https://soundcloud.com/my-profile/my-track/my-secret-token";</script>
@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);
            }
        }
    });
}