AndroidのWebViewでFacebookログインを実装しようとしています。問題は、HTMLページでFacebookボタンをクリックして、Facebookダイアログでユーザー名とパスワードを挿入した後です。 URLリダイレクトは、私に黒いページを与えているだけです。
@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);
これはHTMLページ上のFacebookの通常のJavaScript APIであり、この関数はfacebookボタンがクリックされると呼び出されます。
$("#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'});
Facebookのダイアログページでリダイレクト後に応答を取得する方法についてのアイデアはありますか?ありがとう。
Androidアプリケーションで同じ問題が発生しました。問題の原因は、FBログインjavascriptが新しいウィンドウで新しいページを開くことです。 、ログイン成功後WebViewは通常「単一ウィンドウのみ」であるため、戻る場所がないため、空白の画面になります。
私の作業コードから流れる例をフォローしてください。
<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"
/>
Id "webview"のWebviewは、私のコンテンツのメインビューです。以下は私の活動コードです。
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");
}
}
}
この問題の鍵はonCreateWindowです。新しいウィンドウが作成され、フレームレイアウトに挿入され、成功すると削除されます。 shouldOverrideUrlLoadingで削除を追加しました。
Androidプロジェクトの例を次に示します。 Github:Android_Popup_Webview_handler_example
これは、Android Webviewでポップアップを処理する方法を示すAndroid Studioプロジェクトです。ほとんどのオープンソースブラウザは、ポップアップを開くことをサポートしていません。
ポップアップは、多くのWebサイトで使用されるOAuthログインで特に重要です(例: www.feedly.com )。このプロジェクトのポップアップはダイアログで開かれ、閉じるボタンまたは[戻る]を押すか、ポップアップウィンドウが閉じた場合(ほとんどのログイン認証フローで発生するような)で閉じることができます。
ベストアンサー から この質問 に関しては、使用するWebViewClientクラスのonPageFinishedメソッドを実装するだけです。
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);
}
私にとってはうまくいきました。それがあなたにも役立つことを願っています:)
WebViewClient
でshouldOverrideUrlLoading()
をオーバーライドします。 shouldOverrideUrlLoading
here を検索します。また、facebookのログインAPIに渡すことができるパラメーターがあります。私はそれがredirect_uriだと思います。これは、ログインが成功し、shouldOVerrideUrlLoading()
で認識されるのに役立つはずです。ロードされるURLを検出し、指定したredirect_uriであれば、そのメソッドでtrueを返し、ログインが成功したときにwebviewまたは何でもしたい。
上記の答えは古すぎて、最新のFacebook SDKバージョン2.7では機能しません。それに4時間を費やした後、私はそれでいくつかの変更を発見しました。次のコードは、最新のSDKで正常に機能します。
以下は、XMLレイアウトファイルです。
<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>
これはAndroidアクティビティコードスニペット
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");
}
}
}
Webビューをxmlレイアウトファイルに移動してみてください。空白ページエラーは、oAuth=承認受け入れページへのログイン中にjsスクリプトが失敗するために発生しました。この問題は、webviewをxmlレイアウトに移動することで解決できます。
おそらく常に実行可能な答えではないかもしれませんが、別のオプションは「ポップアップとJS」スタイルOAuth非ポップアップ「redirect_uri」OAUthスタイルへのログインログインページに送信し、成功/失敗後に「some uri err other」(例:自分のWebサイトの別のページ)に送信され、認証が完了します。
Facebookで「WebViewを使用している場合、それらを https://www.facebook.com/connect/login_success.html "にリダイレクトします」というFWIWは、単一のWebViewおよび)OAuth=を使用してログインするため、通常のWebフローではなく収集できるlogin_success.htmlに認証パラメーターを追加します...
別の可能性としては、 オーバーライド javascript postMessage
関数を使用して、それが何であったかをキャプチャできるようにしますabout to親ウィンドウに戻ります。
私の答えは、リダイレクトに関する問題を解決しようとするのではなく、Facebookログインページをホストするために2番目のWebView
を作成するという点で、ここの他のいくつかと本質的に似ています。ただし、ログインWebView
を独自のFragment
に配置し、専用のWebViewClient
およびWebChromeClient
サブクラスにすることを選択しました。これにより、各コンポーネントがどのような役割を果たし、どのオブジェクトがどの設定と動作を必要とするかが少しわかりやすくなると思います。
また、WebChromeClient.onCloseWindow()
を使用して、FacebookのJavaScriptがログインウィンドウを閉じたいときを検出します。これは、別の答えから私が最初に追求したアプローチよりもはるかに堅牢です。
Activity
レイアウトには、コメントをホストする「プライマリ」_WebView
と、FacebookWebLoginFragment
のコンテナがあります。ログインFragment
は必要なときにオンザフライで作成され、FacebookのログインJavaScriptがウィンドウのクローズを要求したときに削除されます。
私のActivity
レイアウトは次のようになります。
_<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>
_
Activity
内で、Facebook Webログインフラグメントを表示および非表示にするコードが必要です。 Ottoイベントバスを使用しているため、以下のようなイベントハンドラーがあります。 (ここではこの問題に特化したものはありません。ログインFragment
が全体の構造にどのように適合するかを示すために、このコードを含めています。)
_@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();
}
}
_
FacebookWebLoginFragment
が存在する間、デバイスのバックボタンの押下を処理する権限を付与する必要があります。 Facebookのログインフローにはログインページから移動する機能が含まれており、ユーザーは[戻る]ボタンでログインに戻ることが期待されるため、これは重要です。だから、私のActivity
には、これがあります:
_@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();
}
}
_
FacebookWebLoginFragment
のレイアウトは非常に簡単です。
_<?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>
_
これがFacebookWebLoginFragment
コードです。 FacebookログインJavaScriptがウィンドウを閉じる(つまり、フラグメントを削除する)準備ができたことを検出するために、WebChromeClient
のサブクラスに依存していることに注意してください。また、このログインWebView
とコメントUIを含むプライマリWebView
の間には直接通信がないことに注意してください。認証トークンはサードパーティのCookieを介して渡されるため、プライマリWebView
でサードパーティのCookieサポートを有効にする必要があります。
_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();
}
};
}
}
_
さて、既存のWebView
に必要な変更を行うのが最も難しいのは、既にかなりの量のコードが適切に配置されている可能性があるためです。変化する。
まず、JavaScriptが有効になっており、複数のウィンドウをサポートしていることを確認してください。
_WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportMultipleWindows(true);
_
あなたはnotsetJavaScriptCanOpenWindowsAutomatically(true)
を呼び出す必要があります。
他のいくつかの答えを見ると、WebViewClient
に割り当てられているWebView
を使用して、shouldOverrideUrlLoading()
をオーバーライドする必要があると思うかもしれません。これは必要ありません。重要なのはWebChromeClient
です。これはonCreateWindow()
をオーバーライドする必要があります。
それで...次に、カスタムWebChromeClient
サブクラスを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;
}
});
_
これはUriHelper.isFacebookHost()
の2番目の呼び出しであることに気付くでしょう。私はこれを決定するための防弾アプローチを持っていませんが、ここで私がやっていることは次のとおりです。
_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;
}
_
CookieHelper.setAcceptThirdPartyCookies()
の呼び出しにも気付くでしょう。そのためのコードは次のとおりです。
_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);
}
}
_
一部の人々をつまずかせるもう1つのことは、Facebook開発設定の「有効なOAuth=リダイレクトURI」の設定です。ログに次のようなエラーが表示された場合:
URLのブロック:リダイレクトURIがアプリのクライアントにホワイトリストに登録されていないため、このリダイレクトは失敗しましたOAuth設定。クライアントとWebを確認してくださいOAuth有効なOAuthリダイレクトURI。
...次に、この答えを確認してください。 https://stackoverflow.com/a/37009374
楽しんで!非常に単純な問題のように見えるものに対する複雑な解決策。良い面として、Androidは開発者にここで多くの制御を与えました。