简体   繁体   中英

Problems with WebView and facebook comments login

I finished building a WebView app for my blog, but I'm struggling with the comment forms of the blog posts...

A blog post has a Facebook Comment form and Disqus form for comments, when a user logs in with his account (facebook or disqus) to comment on the blog post, the WebView goes blank, the LogCat shows the following:

06-12 01:41:23.161 25469-25469/com.lfcchile I/chromium: [INFO:CONSOLE(0)] "Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('http://www.liverpoolecho.co.uk') does not match the recipient window's origin ('http://login.liverpoolecho.co.uk').", source:  (0)
06-12 01:41:23.670 25469-25469/com.lfcchile I/chromium: [INFO:CONSOLE(0)] "Scripts may close only the windows that were opened by it.", source:  (0)
06-12 01:41:24.173 25469-25469/com.lfcchile I/chromium: [INFO:CONSOLE(157)] "Uncaught TypeError: Cannot set property 'className' of null", source: http://login.liverpoolecho.co.uk/GS/GSLogin.aspx?state=mt%3Df_ZBY0aurAv1MxAfZR5z-zz-ETcKtpdXvVcPwVbv46Q.&code=4/lKuWs2HMelOHr7GrjjGa4_LhJiXKK2U15XFuFDZ0R-Y&authuser=0&session_state=d1a06bba2ecd9f8532bc57754cc167dc55368b39..6516&prompt=consent (157)
06-12 01:50:51.942 25469-25469/com.lfcchile I/chromium: [INFO:CONSOLE(1)] "Uncaught TypeError: Cannot read property 'closed' of null", source: https://m.facebook.com/plugins/close_popup.php?reload=https%3A%2F%2Fwww.facebook.com%2Fplugins%2Fcomments.php%3Fapi_key%3D1043577742379358%26channel_url%3Dhttp%253A%252F%252Fstaticxx.facebook.com%252Fconnect%252Fxd_arbiter.php%253Fversion%253D42%2523cb%253Df27a5826d3620f%2526domain%253Dlfcchile.com%2526origin%253Dhttp%25253A%25252F%25252Flfcchile.com%25252Ff26fe3ca59041dc%2526relation%253Dparent.parent%26colorscheme%3Dlight%26href%3Dhttp%253A%252F%252Flfcchile.com%252F2016%252F05%252F24%252Ftenemos-nuevo-portero-loris-karius%252F%26locale%3Des_LA%26mobile%3Dtrue%26numposts%3D1%26sdk%3Djoey%26skin%3Dlight%26version%3Dv2.3%26refsrc%3Dhttp%253A%252F%252Flfcchile.com%252F2016%252F05%252F24%252Ftenemos-nuevo-portero-loris-karius%252F%26ret%3Doptin%26order_by%3Dtime%26hash%3DAQAX5nrCJZbrqaQQ (1)

My MainActivity

package com.lfcchile;

import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;
import android.content.pm.PackageManager;

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private WebView myWebView;
    private ProgressBar progressBar;

    //Función que almacena la URL actual para compartirla
    private void shareURL() {
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.setType("text/plain");
        shareIntent.putExtra(Intent.EXTRA_TEXT, myWebView.getUrl());
        startActivity(Intent.createChooser(shareIntent, "Comparte este enlace!"));
    }

    //Función que chequea si la App de WordPress está instalada en el dispositivo
    public void checkApp() {
        Intent intent = getPackageManager().getLaunchIntentForPackage("org.wordpress.android");
        boolean installed = appInstalledOrNot("org.wordpress.android");
        if (installed) {
            //Se abre la App
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        } else {
            //Redirecciona a Play Store para instalar la App
            Toast.makeText(getApplicationContext(), "Necesitas tener instalada la App de WordPress",
                    Toast.LENGTH_LONG).show();
            intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setData(Uri.parse("market://details?id=" + "org.wordpress.android"));
            startActivity(intent);
        }
    }

    //Función para mostrar más Apps del mismo desarrollador
    public void developerProfile() {
        final String appPackageName = getPackageName(); // getPackageName() from Context or Activity object
        try {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://developer?id=J.+Llorente")));
        } catch (android.content.ActivityNotFoundException anfe) {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/developer?id=J.+Llorente")));
        }
    }

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

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                shareURL();
            }
        });

        this.myWebView = (WebView) this.findViewById(R.id.webViewInicio);
        WebView myWebView = (WebView) this.findViewById(R.id.webViewInicio);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);

        // Propiedades del WebView
        myWebView.setWebViewClient(new MyWebViewClient());
        myWebView.getSettings().setJavaScriptEnabled(true);
        myWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        myWebView.getSettings().setDomStorageEnabled(true);
        myWebView.loadUrl("http://lfcchile.com/");

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
    }

    //Controlar lo que el botón "Atrás" hace
    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            if (this.myWebView.canGoBack())
                this.myWebView.goBack();
            else
                super.onBackPressed();
        }
    }

    //Funciones que permiten iconos en la Action Bar del MainActivity
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    //Acciones de los botones de la Action Bar
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        //Acción de botón Salir
        if (id == R.id.action_salir) {
            finish();
            Toast.makeText(getApplicationContext(), "Nos vemos pronto! YNWA!",
                    Toast.LENGTH_LONG).show();
        }

        //Acción del botón Recargar
        if (id == R.id.action_recargar) {
            myWebView.reload();
        }
        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Acciones del menú.
        int id = item.getItemId();

        if (id == R.id.nav_inicio) {
            setTitle(R.string.inicio);
            myWebView.loadUrl("http://lfcchile.com/");
        } else if (id == R.id.nav_destacado) {
            setTitle(R.string.destacado);
            myWebView.loadUrl("http://lfcchile.com/category/destacado/");
        } else if (id == R.id.nav_tabla_pl) {
            setTitle(R.string.tabla_pl);
            myWebView.loadUrl("http://lfcchile.com/tabla-pl/");
        } else if (id == R.id.nav_hillsborough) {
            setTitle(R.string.hillsborough);
            myWebView.loadUrl("http://lfcchile.com/hillsborough/");
        } else if (id == R.id.nav_sitiosinteres) {
            setTitle(R.string.sitiosinteres);
            myWebView.loadUrl("http://lfcchile.com/sitios-interes/");
        } else if (id == R.id.nav_comunidad) {
            setTitle(R.string.comunidad);
            myWebView.loadUrl("http://lfcchile.com/comunidad/");
        } else if (id == R.id.nav_wordpress) {
            checkApp();
        } else if (id == R.id.nav_playstore) {
            developerProfile();
        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    private boolean appInstalledOrNot(String uri) {
        PackageManager pm = getPackageManager();
        boolean app_installed = false;
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
            app_installed = true;
        } catch (PackageManager.NameNotFoundException e) {
            app_installed = false;
        }
        return app_installed;
    }

    //Controla las acciones al cargar la pagina y al finalizar carga
    private class MyWebViewClient extends WebViewClient {
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            progressBar.setVisibility(View.VISIBLE);
        }
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // Sitios web que se cargan dentro de la app, los demás abren el navegador del telefono
                view.loadUrl(url);
                return false;
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            progressBar.setVisibility(View.GONE);
        }
    }
}

I can't speak to Disqus, but the login process for Facebook Comments requires that you create a separate WebView -- or, a separate "window", in JavaScript terms. (I suspect Disqus is similar, given the symptom you're seeing.) The error Cannot read property 'closed' of null is due to the fact that WebSettings defaults mutli-window support to false. In the section with the comment // Propiedades del WebView , you need to add:

myWebView.getSettings().setSupportMultipleWindows(true);

However, I see that you have some other issues here, as well. For instance, for Lollipop and later, you need to allow third-party cookies, so that the Facebook token can be accessed from the WebView that hosts comments. I use this helper method. In your case, you would pass in myWebView :

public static void setAcceptThirdPartyCookies(WebView webView, boolean accept) {
    CookieManager cookieManager = CookieManager.getInstance();

    if (accept && !cookieManager.acceptCookie()) {
        cookieManager.setAcceptCookie(true);
    }
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        cookieManager.setAcceptThirdPartyCookies(webView, accept);
    }
}

You will also need to assign a subclass of WebChromeClient to myWebView , and within your subclass you must override onCreateWindow() , as documented here: https://developer.android.com/reference/android/webkit/WebSettings.html#setSupportMultipleWindows(boolean) . Within that method, you will need to create a second WebView , to host Facebook's login screen, and send the android.os.Message object passed into onCreateWindow() to the newly created target WebView .

To get a complete picture of all that is entailed, I suggest you refer to the answers to this question about handling Facebook's web login: Making facebook login work with an Android Webview .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM