【问题标题】:Android open intent:// protocol in WebViewAndroid在WebView中打开intent://协议
【发布时间】:2016-02-24 17:33:41
【问题描述】:

当我将 url 加载到 WebView 并尝试打开链接时,其中一些会显示如下错误页面:

net::ERR_UNKNOWN_URL_SCHEME intent://maps.yandex.ru?utm_medium=tab...

如何打开此链接,或者至少检查是否安装并运行了适当的应用程序?

我尝试通过实现自定义 WebViewClient 来覆盖 url 加载:

@Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (!url.startsWith("http")) {
            getActivity().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url)));
            return true;
        }
        return false;
    }

但在这种情况下,应用程序会因 ActivityNotFoundException 而崩溃。

02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=intent://maps.yandex.ru?utm_medium=tab-maps&text=магазин&utm_source=serp&yandexuid=2258091361456330110 }
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1798)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at android.app.Instrumentation.execStartActivity(Instrumentation.java:1512)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at android.app.Activity.startActivityForResult(Activity.java:3930)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at android.app.Activity.startActivityForResult(Activity.java:3890)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:784)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at android.app.Activity.startActivity(Activity.java:4213)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at android.app.Activity.startActivity(Activity.java:4181)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at ru.uxapps.voicesearch.FWeb$CustomWebViewClient.shouldOverrideUrlLoading(FWeb.java:70)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at com.android.webview.chromium.WebViewContentsClientAdapter.shouldOverrideUrlLoading(WebViewContentsClientAdapter.java:325)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at org.chromium.android_webview.AwContentsClientBridge.shouldOverrideUrlLoading(AwContentsClientBridge.java:266)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:37)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at android.os.Looper.loop(Looper.java:148)
02-24 20:58:51.886 31255-31255/ru.uxapps.voicesearch W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5417)
02-24 20:58:51.887 31255-31255/ru.uxapps.voicesearch W/System.err:     at java.lang.reflect.Method.invoke(Native Method)

即使安装了所需的应用程序,应用程序也会崩溃。但是如果在 Chrome 中打开这个链接,它会显示 maps.yandex.ru 网站,或者如果安装了应用程序会打开。

是否有适用于所有 intent:// 链接的通用 解决方案? 感谢您的建议。

【问题讨论】:

  • “但在这种情况下,应用程序会因 ActivityNotFoundException 而崩溃”——请编辑您的问题并发布完整的堆栈跟踪。你有安装这个应用程序吗? “或者至少检查是否安装了适当的应用程序” - 鉴于Uri,您应该能够获得maps.yandex.ru 值(getHost(),如果我不得不猜测),然后使用PackageManager 看看是否它就在那里。
  • @CommonsWare 感谢您的关注,我已经更新了答案。我正在寻找使所有意图://链接正常工作的通用解决方案。
  • 看看如何构建正确的intent uri:developer.chrome.com/multidevice/android/intents
  • @gsgsgs 问题是如何通过意图 uri 运行活动

标签: android android-intent webview


【解决方案1】:

我找到了解决方案。 This questionthis documentation 帮助我了解情况。

因此,我编写了一个遵循此逻辑的链接处理程序:

  1. 在同一个 WebView 中打开 http 和 https
  2. 尝试处理已知方案(电话:等)
  3. 如果找不到已知活动,则解析意图:方案并尝试运行适当的应用程序
  4. 如果未安装所需的应用程序,则尝试将提供的后备 URL 加载到当前 WebView 中
  5. 如果未提供后备网址,则重定向到市场并要求安装所需的应用

代码是:

mWebView.setWebViewClient(new CustomWebViewClient());

//...

private class CustomWebViewClient extends WebViewClient {

    @Override
    public boolean shouldOverrideUrlLoading(WebView webView, String url) {
        if (url.startsWith("http")) return false;//open web links as usual
        //try to find browse activity to handle uri
        Uri parsedUri = Uri.parse(url);
        PackageManager packageManager = getActivity().getPackageManager();
        Intent browseIntent = new Intent(Intent.ACTION_VIEW).setData(parsedUri);
        if (browseIntent.resolveActivity(packageManager) != null) {
            getActivity().startActivity(browseIntent);
            return true;
        }
        //if not activity found, try to parse intent://
        if (url.startsWith("intent:")) {
            try {
                Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
                if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
                    getActivity().startActivity(intent);
                    return true;
                }
                //try to find fallback url
                String fallbackUrl = intent.getStringExtra("browser_fallback_url");
                if (fallbackUrl != null) {
                    webView.loadUrl(fallbackUrl);
                    return true;
                }
                //invite to install
                Intent marketIntent = new Intent(Intent.ACTION_VIEW).setData(
                        Uri.parse("market://details?id=" + intent.getPackage()));
                if (marketIntent.resolveActivity(packageManager) != null) {
                    getActivity().startActivity(marketIntent);
                    return true;
                }
            } catch (URISyntaxException e) {
                //not an intent uri
            }
        }
        return true;//do nothing in other cases
    }

}

也许它需要一些清理,但它可能会有所帮助。如果您知道更简单的方法,请告诉我,我仍在寻找最佳解决方案。

【讨论】:

  • 嗨,更新到解决方案。我找到了这样的网址:“intent://details?id=com.grofers.customerapp&referrer=conv=963542262&adsplayload=CAEYFCAB&gclid=EAIaIQobChMIlZONp6f84AIVUBBoCh1k3A8-EAEYASAAEgJp8vD_BwE#Intent;scheme=market;package=com.android.vending;end;”,所以提取'package' 参数会导致错误的应用。我假设如果意图链接中存在“id”参数,则应将其提取,否则 - 'package'
  • 我找到了免费的意图,但它对我很有帮助,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多