【问题标题】:Android WebView with custom protocol具有自定义协议的 Android WebView
【发布时间】:2015-01-19 20:52:23
【问题描述】:

我在 WebView 中实现用户身份验证时遇到问题。

正如 API 文档所说,我需要加载 URL“http://example.com/?key=abc”,然后用户输入他的登录名和密码,然后他被重定向到网页“myapp://token#access_token=123456”。

我只需要在 WebView 中加载它并使用“123456”令牌返回我的应用程序。第一个问题是 WebView 不支持自定义协议,它给我一个错误 "ERR_UNKNOWN_URL_SCHEME"。

第二个问题是我不完全了解如何使用页面数据返回我的应用程序。

在 AndroidManifest.xml 我有这个:

 <activity
        android:name="(appname)"
        android:label="@string/app_name"
        android:configChanges="orientation">
        <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="token"/>
        </intent-filter>
    </activity>

在 Main.java 文件中我有以下代码:

            Intent i = new Intent(Main.this, LoginWebViewActivity.class);
            startActivityForResult(i, 1);

在 LoginWebActivity.java 我有以下代码:

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webviewact);
        webView = (WebView) findViewById(R.id.webView);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl("http://example.com/?key=abc");
    }

我看到了一个快速的解决方案:在外部浏览器中打开此链接,但是,我不明白我的应用程序如何从外部浏览器获取数据。

【问题讨论】:

    标签: android webview


    【解决方案1】:

    您不需要实施自定义方案。您应该将该回调 URL 传递到网页中,然后通过处理 shouldOverrideUrlLoading 在代码中查找并拦截该回调:

        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (url.startsWith("http://myapp/token#access_token=")) {
                    // Parse the token fom the URL and close the webview
                    return true;
                } else {
                    return super.shouldOverrideUrlLoading(view, url);
                }
            }
        });
    

    【讨论】:

    • 我必须实现自定义方案,因为 API 需要它(我正在使用的那个网站)
    【解决方案2】:

    这不是“网页”:

    myapp://token#access_token=123456
    

    这可能是一个 URI,如果你操作得当,你可以过滤它。您需要使用 IntentFilter 来实现您自己的 URI,如下所示:

    看到这篇文章:

    How to implement my very own URI scheme on Android

    编辑:

    解释一下 - 您正在发送“登录”请求。然后你说你正在将客户端“重定向”到

    myapp://token#access_token=123456
    

    您不能告诉客户端“重定向”到非 URL 网页。 WebView 客户端是一个“http”客户端——它不接受它无法识别的数据方案/mime 类型。所以你的“重定向”失败了。

    当您进行页面请求时,响应应该是 URI 而不是重定向。您可以解析响应数据以查看是否收到此响应(与登录失败相比),如果收到,您可以启动一个新的活动。就这么简单。

    这里有一个答案建议您覆盖shouldOverrideUrlLoading,这也是可以接受的。在这种情况下,我们假设您正在执行客户端重定向,在这种情况下,此方法将允许您捕获身份验证响应,将其解析为您需要的数据,然后您可以启动任何您想要的 URL 或活动.

    为了进一步解释,XML 数据方案仅对Intents 有用。您的 WebView 正在内部响应 - 未发送任何意图。您必须获取 HTTP 响应,对其进行解析,然后广播 Intent 以使您的代码的那部分工作。

    【讨论】:

    • 我已经实现了IntentFilter(看帖子里的代码)
    猜你喜欢
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 2012-07-10
    • 2021-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    相关资源
    最近更新 更多