Android WebView中的Google登录无法正常工作

18

我是Android开发新手。正在尝试在Android webview中集成FB和Google+登录。FB登录可以正常工作,但Google登录不允许登录。我参考了一些链接但仍未成功。

问题是,在提供Gmail的用户名和密码后,我的网站无法登录。

一个webview覆盖在另一个webview上

Google登录在Android webview应用程序中不起作用

Google登录在Android webview应用程序中不起作用

private class MyCustomWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        String host = Uri.parse(url).getHost();
        Log.d("Loading URL", url);
        if (host.equals(target_url_prefix)) {
            // This is my web site, so do not override; let my WebView load
            // the page
            if (mWebviewPop != null) {
                mWebviewPop.setVisibility(View.GONE);
                mContainer.removeView(mWebviewPop);
                mWebviewPop = null;
            }
            return false;
        }

        if (host.contains("m.facebook.com") || host.contains("facebook.co")
                || host.contains("google.co")
                || host.contains("www.facebook.com")
                || host.contains(".google.com")
                || host.contains(".google")
                || host.contains("accounts.google.com/signin/oauth/consent")
                || host.contains("accounts.youtube.com")
                || host.contains("accounts.google.com")
                || host.contains("accounts.google.co.in")
                || host.contains("www.accounts.google.com")
                || host.contains("oauth.googleusercontent.com")
                || host.contains("content.googleapis.com")
                || host.contains("ssl.gstatic.com")
            //     || host.contains("https://accounts.google.com/signin/oauth/consent")

        ) {
            return false;
        }
        // Otherwise, the link is not for a page on my site, so launch
        // another Activity that handles URLs

        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        startActivity(intent);
        return true;
    }

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        Log.d("onReceivedSslError", "onReceivedSslError");
        super.onReceivedSslError(view, handler, error);
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        if (url.startsWith("https://m.facebook.com/v2.7/dialog/oauth")


        ) {
            if (mWebviewPop != null) {
                mWebviewPop.setVisibility(View.GONE);
                mContainer.removeView(mWebviewPop);
                mWebviewPop = null;
            }
            view.loadUrl("https://www.cbazaar.com");
            return;
        }

        super.onPageFinished(view, url);
    }
}

private class UriWebChromeClient extends WebChromeClient {

    @Override
    public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
        mWebviewPop = new WebView(mContext);
        mWebviewPop.setVerticalScrollBarEnabled(false);
        mWebviewPop.setHorizontalScrollBarEnabled(false);
        mWebviewPop.setWebViewClient(new MyCustomWebViewClient());
        mWebviewPop.setWebChromeClient(new UriWebChromeClient());
        mWebviewPop.getSettings().setJavaScriptEnabled(true);
        mWebviewPop.clearHistory();
        mWebviewPop.clearFormData();
        mWebviewPop.clearCache(true);
        mWebviewPop.getSettings().setSavePassword(true);
        mWebviewPop.getSettings().setSaveFormData(true);
        mWebviewPop.getSettings().setUserAgentString(USER_AGENT_FAKE);

        builder = new AlertDialog.Builder(MainActivity.this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT).create();

        builder.setTitle("");
        builder.setView(mWebviewPop);

        builder.setButton("close", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                mWebviewPop.destroy();
                dialog.dismiss();

            }
        });

        builder.show();
        builder.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

             /*   CookieManager cookieManager = CookieManager.getInstance();
                cookieManager.setAcceptCookie(true);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    cookieManager.setAcceptThirdPartyCookies(mWebviewPop,true);
                }
    */

        WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
        transport.setWebView(mWebviewPop);
        resultMsg.sendToTarget();

        return true;
    }


    @Override
    public void onCloseWindow(WebView window) {

        try {
            mWebviewPop.destroy();
        } catch (Exception e) {
        }

        try {
            builder.dismiss();

        } catch (Exception e) {
        }

    }

}

请展示你的代码。 - Truong Hieu
不好意思。请在您实现Google登录的代码中粘贴一些代码。 - Truong Hieu
请参考此链接链接 - Karan Chunara
TruongHieu,请查看上面的代码。 - Girish M
5个回答

19

您需要创建一个自定义的WebChromeClient并处理来自WebView的弹出窗口。每当网站需要弹出窗口时,您需要在警告对话框中加载它。

public class WebViewActivity extends AppCompatActivity {

private WebView webViewPopUp;
private AlertDialog builder;
private Context globalContext;

private String url = "https://www.bellyfulstore.com/";

private WebView webView;
private String userAgent;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_web_view);

    webView = findViewById(R.id.webView);
    webView.setWebViewClient(new WebViewClient());
    webView.loadUrl(url);

    WebSettings webSettings = webView.getSettings();
    webSettings.setJavaScriptEnabled(true);

    // Set User Agent
    userAgent = System.getProperty("http.agent");
    webSettings.setUserAgentString(userAgent + "yourAppName");

    // Enable Cookies
    CookieManager.getInstance().setAcceptCookie(true);
    if(android.os.Build.VERSION.SDK_INT >= 21)
        CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);

    // Handle Popups
    webView.setWebChromeClient(new CustomChromeClient());
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
    webSettings.setSupportMultipleWindows(true);
    globalContext = this.getApplicationContext();

    // WebView Tweaks
    webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
    webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
    webSettings.setAppCacheEnabled(true);
    webSettings.setDomStorageEnabled(true);
    webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
    webSettings.setUseWideViewPort(true);
    webSettings.setSaveFormData(true);
    webSettings.setEnableSmoothTransition(true);
    webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);



    webView.setWebViewClient(new WebViewClient() {

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            findViewById(R.id.progressBar).setVisibility(View.VISIBLE);

        }

        public void onPageFinished(WebView view, String url) {
            // do your stuff here
            findViewById(R.id.progressBar).setVisibility(View.GONE);
        }
    });
}




class CustomChromeClient extends WebChromeClient {


    @Override
    public boolean onCreateWindow(WebView view, boolean isDialog,
                                  boolean isUserGesture, Message resultMsg) {
        webViewPopUp = new WebView(globalContext);
        webViewPopUp.setVerticalScrollBarEnabled(false);
        webViewPopUp.setHorizontalScrollBarEnabled(false);
        webViewPopUp.setWebChromeClient(new CustomChromeClient());
        webViewPopUp.getSettings().setJavaScriptEnabled(true);
        webViewPopUp.getSettings().setSaveFormData(true);
        webViewPopUp.getSettings().setEnableSmoothTransition(true);
        webViewPopUp.getSettings().setUserAgentString(userAgent + "yourAppName");

        // pop the  webview with alert dialog
        builder = new AlertDialog.Builder(WebViewActivity.this).create();
        builder.setTitle("");
        builder.setView(webViewPopUp);

        builder.setButton("Close", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                webViewPopUp.destroy();
                dialog.dismiss();
            }
        });

        builder.show();
        builder.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);
        if(android.os.Build.VERSION.SDK_INT >= 21) {
            cookieManager.setAcceptThirdPartyCookies(webViewPopUp, true);
            cookieManager.setAcceptThirdPartyCookies(webView, true);
        }

        WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
        transport.setWebView(webViewPopUp);
        resultMsg.sendToTarget();

        return true;
    }

    @Override
    public void onCloseWindow(WebView window) {
        //Toast.makeText(contextPop,"onCloseWindow called",Toast.LENGTH_SHORT).show();
        try {
            webViewPopUp.destroy();
        } catch (Exception e) {
            Log.d("Destroyed with Error ", e.getStackTrace().toString());
        }

        try {
            builder.dismiss();
        } catch (Exception e) {
            Log.d("Dismissed with Error: ", e.getStackTrace().toString());
        }

    }
}

@Override
public void onBackPressed() {
    if (webView!=null){
        if (webView.canGoBack()){
            webView.goBack();
            return;
        }
    }
    super.onBackPressed();
}

}


有 Swift 版本可用吗? - Muhammad Asyraf
感谢分享这个有效的东西。但是当我添加了这段代码后,我的应用程序需要花费将近2到3分钟的时间来加载我的网页......你能告诉我如何解决这个问题吗? - Jahadul Rakib
你的回答仍然非常有效!谢谢!但是,我该如何指定只为登录按钮打开它?目前,在我的网站上,WebView 中的任何链接都会在弹出窗口中打开。感谢任何反馈! - Dan Rais
我不建议使用应用程序上下文来解决这个问题,但一般来说这是一个很好的解决方案,谢谢。 - Hitrene

15

谷歌不允许使用WebView的默认实现。因此,您需要为您的WebView设置自定义User-Agent:

webView.getSettings().setUserAgentString("YourAppName");

你可以使用任何字符串代替YourAppName


1
@GirishM,你在哪里创建/通过ID查找WebView? - Vladyslav Matviienko
@VladyslavMatviienko 它没有工作,有没有办法捕获错误? - vikas
@HarpreetSingh 那样做会导致它“不工作”吗? - Vladyslav Matviienko
没有说“不工作”,但它会向用户发出警报,这只是我的想法@VladyslavMatviienko - Harpreet Singh
添加了这行代码后,它重定向到网站的桌面视图而不是移动视图。 - sum20156
在Fully Kiosk浏览器中工作,需要在设置/高级Web设置/自定义用户代理字符串中进行配置... - backnext

9
晚来一步,但或许能帮到未来的某个人。
实际上,Google 屏蔽了通过嵌入式浏览器进行的 OAuth 请求。因此,你可以在代码中编写类似以下内容的内容:
 public static final String USER_AGENT = "Mozilla/5.0 (Linux; Android 4.1.1; Galaxy Nexus Build/JRO03C) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19";
 mWebView.getSettings().setUserAgentString(USER_AGENT);

或者您可以这样做:

mWebView.getSettings().setUserAgentString("yourAppName");

你应该可以使用谷歌登录。


-1
webSettings.setUserAgentString(webSettings.getUserAgentString().replace("; wv",""));

1
虽然这段代码片段可能是解决方案,但包括解释真的有助于提高您的帖子质量。请记住,您正在回答未来读者的问题,而这些人可能不知道您的代码建议原因。 - Shawn Hemelstrand

-6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接