Die Facebook-Anmeldung mit einer Android-Webansicht zum Laufen bringen

Lesezeit: 19 Minuten

Ich versuche gerade, den Facebook-Login auf einem WebView in Android zu implementieren. Das Problem tritt auf, nachdem ich auf meiner HTML-Seite auf die Facebook-Schaltfläche geklickt und den Benutzernamen und das Passwort im Facebook-Dialog eingegeben habe. Die URL-Umleitung gibt mir nur eine schwarze Seite.

   @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    WebView webview = new WebView(this);        
    webview.setWebChromeClient(new WebChromeClient());  
    webview.getSettings().setPluginState(PluginState.ON);
    webview.getSettings().setJavaScriptEnabled(true); 
    webview.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
    webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
    webview.setWebViewClient(new WebViewClient());
    webview.loadUrl("http://peoplehunt.crowdscanner.com/hunt"); 
    setContentView(webview);

Dies ist die reguläre Facebook-Javascript-API auf meiner HTML-Seite und diese Funktion wird aufgerufen, wenn auf die Facebook-Schaltfläche geklickt wird.

$("#login_facebook").click(function() {

                    FB.login(function(response) {
                            //This function should be called
                            if (response.authResponse) {
                            FB.api('/me?fields=name,email,picture,id&type=large', function(response) {
                                    //console.log("email "+response.email);
                                    $("#submitHandle").hide();
                                    $("#loader").show();
                                    //console.log('Good to see you, ' + response.picture + '.');
                                    var theUsername = response.name;
                                    theUsername = theUsername.replace(/ /g, '_')+"_"+response.id+"@meetforeal.com";
                                    //console.log(theUsername);
                                    $("input[name=email]").val(encodeURIComponent(response.email));
                                    $("input[name=lastName]").val(encodeURIComponent(response.name));
                                    $("input[name=avatarImage]").val(response.picture);
                                    $("input[name=userName]").val(encodeURIComponent(theUsername));
                                    $("#msg_twitter").fadeIn("slow");
                                    $("#submitHandle").show();
                                    $("#loader").hide();
                                    $("#user").attr("action","/crowdmodule/auth/registerattendeefacebook");
                                    $("#user").submit();
                            });
                            } else {
  //console.log('User cancelled login or did not fully authorize.');
 }
}, {scope: 'email'});

Irgendwelche Ideen, wie man die Antwort nach der Weiterleitung auf der Facebook-Dialogseite zurückbekommt? DANKE.

Die Facebook Anmeldung mit einer Android Webansicht zum Laufen bringen
Kennen Sie

Ich hatte das gleiche Problem mit meiner Android-Anwendung. Die Ursache des Problems ist, dass FB Login Javascript eine neue Seite in einem neuen Fenster öffnet. Dann versucht es, es zu schließen und einige Javascript-Authentifizierungscodes zurückzusenden, nachdem die Anmeldung erfolgreich war. WebView ist normalerweise “nur ein Fenster”, sodass es keinen Ort gibt, an den es zurückkehren kann, daher der leere Bildschirm.

Bitte folgen Sie dem fließenden Beispiel aus meinen Arbeitscodes.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099cc"
tools:context=".MyActivity" 
android:id="@+id/webview_frame">

<WebView
    android:id="@+id/webview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
/>

Die Webansicht der ID “webview” ist die Hauptansicht für meine Inhalte. Unten sind meine Aktivitätscodes.

public class MyActivity extends Activity {

/* URL saved to be loaded after fb login */
private static final String target_url="http://www.example.com";
private static final String target_url_prefix="www.example.com";
private Context mContext;
private WebView mWebview;
private WebView mWebviewPop;
private FrameLayout mContainer;
private long mLastBackPressTime = 0;
private Toast mToast;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_urimalo);
    // final View controlsView =
    // findViewById(R.id.fullscreen_content_controls);
    CookieManager cookieManager = CookieManager.getInstance(); 
    cookieManager.setAcceptCookie(true); 
    mWebview = (WebView) findViewById(R.id.webview);
    //mWebviewPop = (WebView) findViewById(R.id.webviewPop);
    mContainer = (FrameLayout) findViewById(R.id.webview_frame);
    WebSettings webSettings = mWebview.getSettings();
    webSettings.setJavaScriptEnabled(true);
    webSettings.setAppCacheEnabled(true);
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
    webSettings.setSupportMultipleWindows(true);
    mWebview.setWebViewClient(new UriWebViewClient());
    mWebview.setWebChromeClient(new UriChromeClient());
    mWebview.loadUrl(target_url);

    mContext=this.getApplicationContext();

}


private class UriWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        String host = Uri.parse(url).getHost();
        //Log.d("shouldOverrideUrlLoading", 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.equals("m.facebook.com"))
        {
            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);
    }
}

class UriChromeClient 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 UriWebViewClient());
        mWebviewPop.getSettings().setJavaScriptEnabled(true);
        mWebviewPop.getSettings().setSavePassword(false);
        mWebviewPop.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT));
        mContainer.addView(mWebviewPop);
        WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
        transport.setWebView(mWebviewPop);
        resultMsg.sendToTarget();

        return true;
    }

    @Override
    public void onCloseWindow(WebView window) {
        Log.d("onCloseWindow", "called");
    }

}
}

Der Schlüssel für dieses Problem ist onCreateWindow. Ein neues Fenster wird erstellt und in das Frame-Layout eingefügt und bei Erfolg entfernt. Ich habe die Entfernung bei shouldOverrideUrlLoading hinzugefügt.

  • Der if Zustand sein soll host.equals("m.facebook.com") || host.equals("www.facebook.com") Um dem Fall zu entsprechen, lädt es zuerst www, bevor es auf die mobile Version umgeleitet wird.

    – Jeffrey Neo

    21. Januar 14 um 08:32 Uhr

  • Ich habe dasselbe versucht, aber ich bekomme immer noch die leere Seite, irgendwelche Lösungen?

    – Sandoche

    17. Dezember 14 um 22:05 Uhr

  • Dies brachte mir Probleme bei der Verwendung von Links, die enthalten waren target="_blank" – mContainer, der in einigen Situationen null war, löste eine Nullzeiger-Ausnahme aus. Um dies zu lösen, musste ich einfach die folgende Zeile ersetzen: mContainer.addView(mWebviewPop); mit : if (mContainer != null) mContainer.addView(mWebviewPop);

    – drcursor

    29. Juli 15 um 10:20 Uhr


  • Ich habe noch nicht auf älteren Android-Geräten getestet, aber auf API 21+ müssen Sie Folgendes hinzufügen: if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { cookieManager.getInstance().setAcceptThirdPartyCookies(myWebView, true); }

    – Chris

    4. Mai 16 um 14:58 Uhr


  • Ich habe diesen Code befolgt. Aber kein Glück. Die FB-Anmeldeseite wird angezeigt. Nachdem Sie die Anmeldeinformationen eingegeben und auf Login geklickt haben, blieb es dort hängen.

    – Vivek Sinha

    3. April 18 um 13:54 Uhr

Hier ist ein Beispiel-Android-Projekt:
Github: Android_Popup_Webview_handler_example

Dies ist ein Android Studio-Projekt, das zeigt, wie Popups in Android Webview behandelt werden. Die meisten Open-Source-Browser unterstützen das Öffnen von Popups nicht.

Popups sind besonders wichtig bei der OAuth-Anmeldung, die auf vielen Websites verwendet wird (z. www.feedly.com). Die Popups in diesem Projekt werden in einem Dialog geöffnet und können durch eine Schließen-Schaltfläche oder durch Drücken von Zurück geschlossen werden oder wenn sich das Popup-Fenster selbst schließt (wie es bei den meisten Anmeldeauthentifizierungsabläufen der Fall ist).

  • Die Facebook-Anmeldung funktioniert in diesem Fall. Die Google-Anmeldung hat ein Problem mit einem unzulässigen User-Agent.

    – Vivek Sinha

    4. April 18 um 6:33 Uhr

  • @vivek Sinha, das hängt mit einem anderen Problem zusammen. Ab April 2017 hat Google die Anmeldung über Webview eingestellt.

    – Haider

    7. April 18 um 22:31 Uhr

Die Facebook Anmeldung mit einer Android Webansicht zum Laufen bringen
Julian

Um diese Frage am besten zu beantworten, müssen Sie nur die onPageFinished-Methode der von Ihnen verwendeten WebViewClient-Klasse implementieren.

public void onPageFinished(WebView view, String url) {
    // First, get the URL that Facebook's login button is actually redirecting you to.
    // It should be something simulator to https://www.facebook.com/dialog/return/arbiter?relation=opener&close=true
    String webUrl = webView.getUrl();
    // Pass it to the LogCat so that you can then use it in the if statement below.
    Log.d.println(TAG, webUrl);

    if (url.startsWith("The url that you copied from the LogCat")) {
        // Check whether the current URL is the URL that Facebook's redirecting you to.
        // If it is - that's it - do what you want to after the logging process has finished.
        return;
    }

    super.onPageFinished(view, url);
} 

Es funktionierte gut für mich. Hoffe es hilft dir auch 🙂

1644095768 609 Die Facebook Anmeldung mit einer Android Webansicht zum Laufen bringen
praneetloke

Überschreiben shouldOverrideUrlLoading() in deinem WebViewClient. Suchen nach shouldOverrideUrlLoading Hier. Außerdem gibt es einen Parameter, den Sie an die Anmelde-API von Facebook übergeben können. Ich denke, es ist redirect_uri. Das sollte Ihnen helfen zu erkennen, wann die Anmeldung erfolgreich war und in Ihrem shouldOVerrideUrlLoading()müssten Sie nur die geladene URL erkennen, und wenn es sich um die von Ihnen angegebene Umleitungs-URI handelt, geben Sie in dieser Methode einfach true zurück und schließen Sie die Webansicht oder was auch immer Sie möchten, wenn die Anmeldung erfolgreich ist.

Die obige Antwort ist zu alt und funktioniert nicht mit der neuesten Facebook-SDK-Version 2.7. Nachdem ich 4 Stunden damit verbracht habe, habe ich einige Änderungen daran festgestellt. Der folgende Code funktioniert gut mit dem neuesten SDK.

Unten erwähnt ist die XML-Layout-Datei.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099cc"
tools:context=".MainActivity"
android:id="@+id/webview_frame">

<WebView
    android:id="@+id/webView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    />

</FrameLayout>

Dies ist das Code-Snippet für Android-Aktivitäten

    public class MainActivity extends AppCompatActivity {

    private WebView webView;
    private WebView mWebviewPop;
    private FrameLayout mContainer;
    private Context mContext;

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


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

        //Get outer container
        mContainer = (FrameLayout) findViewById(R.id.webview_frame);

        webView = (WebView)findViewById(R.id.webView);

        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setAppCacheEnabled(true);
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setSupportMultipleWindows(true);

        //These two lines are specific for my need. These are not necessary
        if (Build.VERSION.SDK_INT >= 21) {
            webSettings.setMixedContentMode( WebSettings.MIXED_CONTENT_ALWAYS_ALLOW );
        }

        //Cookie manager for the webview
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);

        webView.setWebViewClient(new MyCustomWebViewClient());
        webView.setWebChromeClient(new UriWebChromeClient());
        webView.loadUrl("https://www.YourWebsiteAddress.com");


        mContext=this.getApplicationContext();
    }


    @Override
    public void onBackPressed() {
        if(webView.isFocused() && webView.canGoBack()) {
            webView.goBack();
        } else {
            super.onBackPressed();
        }
    }

private class MyCustomWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            String host = Uri.parse(url).getHost();

            if( url.startsWith("http:") || url.startsWith("https:") ) {

                if(Uri.parse(url).getPath().equals("/connection-compte.html")) {
                    Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.YourWebsiteAddress.com"));
                    startActivity(browserIntent);

                    return true ;
                }

                if (host.equals(target_url_prefix)) {
                    if (mWebviewPop != null) {
                        mWebviewPop.setVisibility(View.GONE);
                        mContainer.removeView(mWebviewPop);
                        mWebviewPop = null;
                    }
                    return false;
                }
                if (host.equals("m.facebook.com") || host.equals("www.facebook.com") || host.equals("facebook.com")) {
                    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;
            }
            // Otherwise allow the OS to handle it
            else if (url.startsWith("tel:")) {
                Intent tel = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
                startActivity(tel);
                return true;
            }
            //This is again specific for my website
            else if (url.startsWith("mailto:")) {
                Intent mail = new Intent(Intent.ACTION_SEND);
                mail.setType("application/octet-stream");
                String AdressMail = new String(url.replace("mailto:" , "")) ;
                mail.putExtra(Intent.EXTRA_EMAIL, new String[]{ AdressMail });
                mail.putExtra(Intent.EXTRA_SUBJECT, "");
                mail.putExtra(Intent.EXTRA_TEXT, "");
                startActivity(mail);
                return true;
            }
            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.YourWebsiteAddress.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.getSettings().setJavaScriptEnabled(true);
            mWebviewPop.getSettings().setSavePassword(false);
            mWebviewPop.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT));
            mContainer.addView(mWebviewPop);
            WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
            transport.setWebView(mWebviewPop);
            resultMsg.sendToTarget();

            return true;
        }

        @Override
        public void onCloseWindow(WebView window) {
            Log.d("onCloseWindow", "called");
        }

    }

}

  • Können Sie erklären /connection-compte.html? Schicken Sie Ihren Benutzer dorthin, nachdem die Anmeldung von Facebook erfolgreich war?

    – Peitsche

    19. Mai 17 um 7:08 Uhr

1644095768 318 Die Facebook Anmeldung mit einer Android Webansicht zum Laufen bringen
Gemeinschaft

Meine Antwort ähnelt im Wesentlichen einigen anderen hier, da ich eine zweite erstelle WebView um die Facebook-Anmeldeseite zu hosten, anstatt zu versuchen, das Problem mit Weiterleitungen zu lösen. Ich habe mich jedoch für die Platzierung des Logins entschieden WebView in seiner eigenen Fragmentund geben Sie es ist gewidmet WebViewClient und WebChromeClient Unterklassen. Ich denke, das macht es ein wenig einfacher zu sehen, welche Rolle jede Komponente spielt und welche Objekte welche Einstellungen und Verhaltensweisen benötigen.

nutze ich auch WebChromeClient.onCloseWindow() um zu erkennen, wann das JavaScript von Facebook das Anmeldefenster schließen möchte. Dies ist viel robuster als der Ansatz, den ich ursprünglich verfolgt habe, aus einer anderen Antwort.

In deinem Activity Layout haben Sie die “primäre” WebViewder die Kommentare hostet, und einen Container für die FacebookWebLoginFragment. Die Anmeldung Fragment wird spontan erstellt, wenn es benötigt wird, und dann entfernt, wenn Facebooks Anmelde-JavaScript das Schließen seines Fensters anfordert.

Mein Activity Layout sieht so aus:

<include layout="@layout/toolbar_common" />

<FrameLayout
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
        android:id="@+id/web_view_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:overScrollMode="never"
        />
    <!-- Used for Facebook login associated with comments -->
    <FrameLayout
        android:id="@+id/facebook_web_login_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:overScrollMode="never"
        android:visibility="gone"
        />
</FrameLayout>

In deinem Activity, benötigen Sie Code, um das Facebook-Web-Anmeldefragment anzuzeigen und auszublenden. Ich verwende den Otto-Ereignisbus, daher habe ich Ereignishandler wie die folgenden. (Nichts hier ist spezifisch für dieses Problem; ich füge diesen Code nur ein, um Ihnen einen Eindruck davon zu vermitteln, wie die Anmeldung Fragment fügt sich in die Gesamtstruktur ein.)

@Subscribe
public void onShowFacebookWebLoginEvent(ShowFacebookWebLoginEvent event) {
    FacebookWebLoginFragment existingFragment = getFacebookWebLoginFragment();
    if (existingFragment == null) {
        mFacebookWebLoginFragmentContainer.setVisibility(View.VISIBLE);
        createFacebookWebLoginFragment(event);
    }
}

@Subscribe
public void onHideFacebookWebLoginEvent(HideFacebookWebLoginEvent event) {
    FacebookWebLoginFragment existingFragment = getFacebookWebLoginFragment();
    if (existingFragment != null) {
        mFacebookWebLoginFragmentContainer.setVisibility(View.GONE);
        FragmentManager fm = getSupportFragmentManager();
        fm.beginTransaction()
                .remove(existingFragment)
                .commit();
    }
}

@Nullable
private FacebookWebLoginFragment getFacebookWebLoginFragment() {
    FragmentManager fm = getSupportFragmentManager();
    return (FacebookWebLoginFragment) fm.findFragmentById(R.id.facebook_web_login_fragment_container);
}

private void createFacebookWebLoginFragment(ShowFacebookWebLoginEvent event) {
    FragmentManager fm = getSupportFragmentManager();
    FacebookWebLoginFragment fragment = (FacebookWebLoginFragment) fm.findFragmentById(R.id.facebook_web_login_fragment_container);
    if (fragment == null) {
        fragment = FacebookWebLoginFragment.newInstance(event.getOnCreateWindowResultMessage());
        fm.beginTransaction()
                .add(R.id.facebook_web_login_fragment_container, fragment)
                .commit();
    }
}

Während FacebookWebLoginFragment vorhanden ist, sollte ihm die Berechtigung erteilt werden, das Drücken der Zurück-Taste des Geräts zu handhaben. Dies ist wichtig, da der Facebook-Login-Flow die Möglichkeit beinhaltet, von der Login-Seite weg zu navigieren, und der Benutzer erwartet, dass der Zurück-Button ihn zum Login zurückbringt. Also in meinem ActivityIch habe das:

@Override
public void onBackPressed() {
    boolean handled = false;
    FacebookWebLoginFragment facebookWebLoginFragment = getFacebookWebLoginFragment();
    if (facebookWebLoginFragment != null) {
        handled = facebookWebLoginFragment.onBackPressed();
    }
    if (!handled) {
        WebViewFragment fragment = getWebViewFragment();
        if (fragment != null) {
            handled = fragment.onBackPressed();
        }
    }
    if (!handled) {
        finish();
    }
}

Das Layout für FacebookWebLoginFragment ist ganz einfach:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="match_parent">
    <WebView
        android:id="@+id/web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</FrameLayout>

Hier ist die FacebookWebLoginFragment Code. Beachten Sie, dass es sich auf eine Unterklasse von stützt WebChromeClient um zu erkennen, wann das Facebook-Login-JavaScript bereit ist, das Fenster zu schließen (dh das Fragment zu entfernen). Beachten Sie auch, dass es keine direkte Kommunikation zwischen diesem Login gibt WebView und die primäre WebView, das die Benutzeroberfläche für Kommentare enthält; Das Auth-Token wird über ein Drittanbieter-Cookie weitergegeben, weshalb Sie sicherstellen müssen, dass die Unterstützung von Drittanbieter-Cookies auf Ihrem primären Cookie aktiviert ist WebView.

import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;

import butterknife.Bind;
import butterknife.ButterKnife;

/**
 * Hosts WebView used by Facebook web login.
 */
public class FacebookWebLoginFragment extends BaseFragment {
    private static final String LOGTAG = LogHelper.getLogTag(FacebookWebLoginFragment.class);

    @Bind(R.id.web_view) WebView mFacebookLoginWebView;

    private WebChromeClient mFacebookLoginWebChromeClient;
    private Message onCreateWindowResultMessage;

    public static FacebookWebLoginFragment newInstance(Message onCreateWindowResultMessage) {
        FacebookWebLoginFragment fragment = new FacebookWebLoginFragment();
        fragment.onCreateWindowResultMessage = onCreateWindowResultMessage;
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.frag_facebook_web_login, container, false);
        ButterKnife.bind(this, rootView);
        return rootView;
    }

    @Override
    public void onViewCreated(View v, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(v, savedInstanceState);

        mFacebookLoginWebView.setVerticalScrollBarEnabled(false);
        mFacebookLoginWebView.setHorizontalScrollBarEnabled(false);
        mFacebookLoginWebView.setWebViewClient(new FacebookLoginWebViewClient());
        mFacebookLoginWebView.getSettings().setJavaScriptEnabled(true);
        mFacebookLoginWebView.getSettings().setSavePassword(false);
        mFacebookLoginWebView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT));

        mFacebookLoginWebChromeClient = makeFacebookLoginWebChromeClient();
        mFacebookLoginWebView.setWebChromeClient(mFacebookLoginWebChromeClient);

        WebView.WebViewTransport transport = (WebView.WebViewTransport) onCreateWindowResultMessage.obj;
        transport.setWebView(mFacebookLoginWebView);
        onCreateWindowResultMessage.sendToTarget();
        onCreateWindowResultMessage = null; // This seems to eliminate a mysterious crash
    }

    @Override
    public void onDestroy() {
        mFacebookLoginWebChromeClient = null;
        super.onDestroy();
    }

    /**
     * Performs fragment-specific behavior for back button, and returns true if the back press
     * has been fully handled.
     */
    public boolean onBackPressed() {
            if (mFacebookLoginWebView.canGoBack()) {
                mFacebookLoginWebView.goBack();
            } else {
                closeThisFragment();
            }
            return true;
    }

    private void closeThisFragment() {
        EventBusHelper.post(new HideFacebookWebLoginEvent());
    }

    class FacebookLoginWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // Only allow content from Facebook
            Uri uri = Uri.parse(url);
            String scheme = uri.getScheme();
            if (scheme != null && (TextUtils.equals(scheme, "http") || TextUtils.equals(scheme, "https"))) {
                if (UriHelper.isFacebookHost(uri)) {
                    return false;
                }
            }
            return true;
        }
    }

    private WebChromeClient makeFacebookLoginWebChromeClient() {
        return new WebChromeClient() {
            @Override
            public void onCloseWindow(WebView window) {
                closeThisFragment();
            }
        };
    }
}

Das Schwierigste ist nun, die notwendigen Änderungen an Ihrem bestehenden vorzunehmen WebViewda es wahrscheinlich ist, dass Sie bereits eine beträchtliche Menge an Code um ihn herum haben, und Sie müssen einen Sinn dafür finden, was geändert werden muss.

Stellen Sie zunächst sicher, dass Sie JavaScript aktiviert haben und dass es mehrere Fenster unterstützt.

WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportMultipleWindows(true);

Sie machen nicht muss anrufen setJavaScriptCanOpenWindowsAutomatically(true).

Wenn Sie sich einige der anderen Antworten ansehen, denken Sie vielleicht, dass Sie mit dem herumspielen müssen WebViewClient das ist dir zugewiesen WebViewund überschreiben shouldOverrideUrlLoading(). Dies ist nicht erforderlich. Wichtig ist die WebChromeClientdie überschrieben werden muss onCreateWindow().

Also … weisen Sie als Nächstes einen Benutzernamen zu WebChromeClient Unterklasse zu Ihrer WebView:

mWebView.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
        String url = null;
        Message href = view.getHandler().obtainMessage();
        if (href != null) {
            view.requestFocusNodeHref(href);
            url = href.getData().getString("url");
        }
        LogHelper.d(LOGTAG, "onCreateWindow: " + url);

        // Unfortunately, url is null when "Log In to Post" button is pressed
        if (url == null || UriHelper.isFacebookHost(Uri.parse(url))) {
            // Facebook login requires cookies to be enabled, and on more recent versions
            // of Android, it's also necessary to enable acceptance of 3rd-party cookies
            // on the WebView that hosts Facebook comments
            CookieHelper.setAcceptThirdPartyCookies(mWebView, true);

            EventBusHelper.post(new ShowFacebookWebLoginEvent(resultMsg));
        } else {
            LogHelper.d(LOGTAG, "Ignoring request from js to open new window for URL: " + url);
        }
        return true;
    }
});

Sie werden feststellen, dass dies der zweite Aufruf an ist UriHelper.isFacebookHost(). Ich habe keinen kugelsicheren Ansatz, um dies zu bestimmen, aber ich mache Folgendes:

public static boolean isFacebookHost(Uri uri) {
    if (uri != null && !TextUtils.isEmpty(uri.getHost())) {
        String host = uri.getHost().toLowerCase();
        return host.endsWith("facebook.com") || host.endsWith("facebook.net");
    }
    return false;
}

Sie werden auch den Aufruf an bemerken CookieHelper.setAcceptThirdPartyCookies(). Hier ist der Code dafür:

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

    // This is a safeguard, in case you've disabled cookies elsewhere
    if (accept && !cookieManager.acceptCookie()) {
        cookieManager.setAcceptCookie(true);
    }
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        cookieManager.setAcceptThirdPartyCookies(webView, accept);
    }
}

Eine weitere Sache, die einige Leute stolpern lässt, ist die Konfiguration von „Gültigen OAuth-Umleitungs-URIs“ in den Facebook-Entwicklereinstellungen. Wenn Sie einen solchen Fehler in Ihren Protokollen sehen:

URL blockiert: Diese Umleitung ist fehlgeschlagen, weil der Umleitungs-URI nicht in den Client-OAuth-Einstellungen der App auf der weißen Liste steht. Stellen Sie sicher, dass Client- und Web-OAuth-Anmeldung aktiviert sind, und fügen Sie alle Ihre Anwendungsdomänen als gültige OAuth-Umleitungs-URIs hinzu.

… dann sollten Sie sich diese Antwort ansehen: https://stackoverflow.com/a/37009374

Habe Spaß! Eine komplizierte Lösung für ein scheinbar ziemlich einfaches Problem. Auf der positiven Seite hat Android den Entwicklern hier eine Menge Kontrolle gegeben.

  • Können Sie erklären /connection-compte.html? Schicken Sie Ihren Benutzer dorthin, nachdem die Anmeldung von Facebook erfolgreich war?

    – Peitsche

    19. Mai 17 um 7:08 Uhr

Dieser Code funktioniert bei mir! Ich habe auf meiner Seite einen LIKE, TEILEN, Kommentar-Button.

    private lateinit var myWebView: WebView;
private val target_url = "https://www.webkomph.com"
private val target_url_prefix = "webkomph.com"
private var mContext: Context? = null
private var mWebviewPop: WebView? = null
private var mContainer: ConstraintLayout? = null
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    val cookieManager = CookieManager.getInstance();
    cookieManager.setAcceptCookie(true)

    myWebView  = findViewById(R.id.webkom_site);
    mContainer = findViewById(R.id.webview_frame);
    val webkomBlue = Color.parseColor("#1c71bc")
    myWebView.setBackgroundColor(webkomBlue);
    myWebView.background
    val webSettings = myWebView.settings;
    webSettings.setJavaScriptEnabled(true);
    webSettings.setAppCacheEnabled(true);
    webSettings.javaScriptCanOpenWindowsAutomatically = true;
    webSettings.setSupportMultipleWindows(true)
    myWebView.setWebViewClient(UriWebViewClient())
    myWebView.setWebChromeClient(UriChromeClient())
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        cookieManager.setAcceptThirdPartyCookies(myWebView, true)
    }
    myWebView.loadUrl(target_url);
    mContext = this.applicationContext
}

override fun onBackPressed() {
    if (myWebView.canGoBack()) {
        myWebView.goBack()
    } else {
        super.onBackPressed()
    }
}

inner class UriWebViewClient : WebViewClient() {
    override fun shouldOverrideUrlLoading(
        view: WebView,
        url: String
    ): Boolean {
        val host = Uri.parse(url).host
        //Log.d("shouldOverrideUrlLoading", url);
        if(host == null || host == 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 == "m.facebook.com" || host == "www.facebook.com" || url.contains("ret=login")) {
            return false
        }
        // Otherwise, the link is not for a page on my site, so launch
        // another Activity that handles URLs
        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
        startActivity(intent)
        return true
    }

    override fun onPageFinished(view: WebView?, url: String) {
        // Facebook redirects to this url once a user has logged in, this is a blank page so we override this
        // http://www.facebook.com/connect/connect_to_external_page_widget_loggedin.php?............
        if (url.contains("plugins/close_popup.php?reload") || url.contains("dialog/close_window") || url.contains("facebook.com/dialog/plugin.optin?")) {

            if(mWebviewPop != null){
                mWebviewPop!!.visibility = View.GONE
                mContainer!!.removeView(mWebviewPop)
                mWebviewPop = null
                if(myWebView != null && (url.contains("dialog/close_window") || url.contains("facebook.com/dialog/plugin.optin?"))){
                    myWebView?.reload();
                }
            }


            return
        }
        super.onPageFinished(view, url)
    }
    override fun onReceivedSslError(
        view: WebView, handler: SslErrorHandler,
        error: SslError
    ) {
        Log.d("onReceivedSslError", "onReceivedSslError")
        //super.onReceivedSslError(view, handler, error);
    }
}

inner class UriChromeClient : WebChromeClient() {
    override fun onCreateWindow(
        view: WebView, isDialog: Boolean,
        isUserGesture: Boolean, resultMsg: Message
    ): Boolean {
        mWebviewPop = WebView(mContext)
        mWebviewPop!!.setVerticalScrollBarEnabled(false)
        mWebviewPop!!.setHorizontalScrollBarEnabled(false)
        mWebviewPop!!.setWebViewClient(UriWebViewClient())
        mWebviewPop!!.getSettings().setJavaScriptEnabled(true)
        mWebviewPop!!.getSettings().setSavePassword(false)
        mWebviewPop!!.layoutParams = FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        mContainer?.addView(mWebviewPop)
        val transport = resultMsg.obj as WebViewTransport
        transport.webView = mWebviewPop
        resultMsg.sendToTarget()
        return true
    }

    override fun onCloseWindow(window: WebView) {
        Log.d("onCloseWindow", "called")
    }
}

.

788160cookie-checkDie Facebook-Anmeldung mit einer Android-Webansicht zum Laufen bringen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy