Android Webview应用程序中的Google和Facebook登录(OAuth)(是否需要弹出功能覆盖?)
我正在使用WebView将我的响应式网站转变为本地应用程序。几乎所有的东西似乎都在工作,但有一件事我不能去工作,那就是我的“用Facebook登录”和“用谷歌登录”按钮。 顺便说一句,Google一键登录可以正常工作(在WebView应用程序在另一个页面上登录Google后,即Gmail),但是“使用Facebook登录”和“使用Google登录”按钮不起作用。 请注意,事实上我已经正确地配置了我的意图(即,任何返回URL或带有我域名的回调URL都会被调用,仍然会通过应用程序调用),但我相信谷歌和Facebook的这些登录API不会将用户返回到任何返回URL,而是将结果传递回最初打开登录弹出窗口的javascript 问题在于(我认为):首先,两个按钮都在单独的浏览器窗口(Chrome)中打开了链接。当我完成登录过程(使用Google或Facebook)时,此浏览器窗口将自动关闭,但我的应用程序不会返回任何内容(因此,我的应用程序不知道用户完成了OAuth过程)。 所以我决定设置webSettings.setSupportMultipleWindows(false)。这至少解决了我在Instagram API上的问题(因为那也不起作用),它也确实使Google和Facebook的身份验证窗口现在在应用程序中打开(因此我认为我离实现这一点有点近),但问题是,OAuth进程返回的数据/结果仍然没有返回到我的应用程序。事实上,Facebook登录屏幕会在我的应用程序完成后完全关闭(我猜window.close()也会影响我的WebView应用程序,或者类似的东西)。另一方面,对于谷歌来说,在登录后,页面保持白色。按“上一步”可返回应用程序的登录屏幕 以下是正在发生的情况的示例: Facebook: 谷歌(第一次,登录过程是有效的,但在完成登录后,我们会看到与下面相同的白色页面): 谷歌(此后每次登录谷歌后): 在我的应用程序的网站版本中处理响应的javascript都工作得很好!它捕获OAuth调用Google或Facebook的结果,处理返回的电子邮件地址和Google/Facebook ID,然后将用户登录到我的应用程序 我的问题可能与以下方面有关: 但我没法让它发挥作用。如果有人对WebView技术有更好的理解,或者知道如何将该主题中提到的解决方案应用于我的情况,我们将不胜感激 我也读过: 这个主题中的一些人说我必须覆盖弹出处理,但我不知道如何做到这一点 这是我的主要活动文件:Android Webview应用程序中的Google和Facebook登录(OAuth)(是否需要弹出功能覆盖?),android,webview,oauth,popup,google-oauth,Android,Webview,Oauth,Popup,Google Oauth,我正在使用WebView将我的响应式网站转变为本地应用程序。几乎所有的东西似乎都在工作,但有一件事我不能去工作,那就是我的“用Facebook登录”和“用谷歌登录”按钮。 顺便说一句,Google一键登录可以正常工作(在WebView应用程序在另一个页面上登录Google后,即Gmail),但是“使用Facebook登录”和“使用Google登录”按钮不起作用。 请注意,事实上我已经正确地配置了我的意图(即,任何返回URL或带有我域名的回调URL都会被调用,仍然会通过应用程序调用),但我相信谷歌
webView.setWebViewClient(new MyWebViewClient() {
private Handler notificationHandler;
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String url) {
if (Config.FALLBACK_USE_LOCAL_HTML_FOLDER_IF_OFFLINE) {
loadLocal(INDEX_FILE);
} else {
webView.setVisibility(View.GONE);
offlineLayout.setVisibility(View.VISIBLE);
}
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//Basic Overriding part here (1/2)
if (url.startsWith("mailto:")) {
startActivity(new Intent(Intent.ACTION_SENDTO, Uri.parse(url)));
return true;
}
if (url.startsWith("share:") || url.contains("api.whatsapp.com")) {
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(i);
return true;
}
if (url.startsWith("whatsapp:")) {
Intent i = new Intent();
i.setPackage("com.whatsapp");
i.setAction(Intent.ACTION_SEND);
i.setType("text/plain");
startActivity(i);
return true;
}
if (url.startsWith("geo:") || url.contains("maps:")) {
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(i);
return true;
}
if (url.startsWith("market:")) {
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(i);
return true;
}
if (url.startsWith("maps.app.goo.gl")) {
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(i);
return true;
}
if (url.contains("maps.google.com")) {
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(i);
return true;
}
if (url.startsWith("intent:")) {
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(i);
return true;
}
if (url.startsWith("tel:")) {
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(i);
return true;
}
if (url.startsWith("sms:")) {
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(i);
return true;
}
if (url.startsWith("play.google.com")) {
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(i);
return true;
}
if (OPEN_SPECIAL_URLS_IN_NEW_TAB) {
WebView.HitTestResult result = view.getHitTestResult();
String data = result.getExtra();
Log.i(TAG, " data :" + data);
if ((data != null && data.endsWith("#")) || url.startsWith("newtab:")) {
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
builder.setToolbarColor(getResources().getColor(R.color.colorPrimaryDark));
CustomTabsIntent customTabsIntent = builder.build();
String finalUrl = url;
if (url.startsWith("newtab:")) {
finalUrl = url.substring(7);
}
customTabsIntent.launchUrl(MainActivity.this, Uri.parse(finalUrl));
webView.stopLoading();
return false;
}
}
return super.shouldOverrideUrlLoading(view, url);
}
});
webView.getSettings().setSupportMultipleWindows(false);
webView.setWebChromeClient(new MyWebChromeClient() {
private Handler notificationHandler;
@Override
public void onCloseWindow(WebView window) {
super.onCloseWindow(window);
Log.i(TAG, "onCloseWindow url " + window.getUrl());
Log.i(TAG, "onCloseWindow url " + window.getOriginalUrl());
}
@Override
public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, Message resultMsg) {
Bundle extras = getIntent().getExtras();
String URL = null;
if (extras != null) {
URL = extras.getString("ONESIGNAL_URL");
}
if (URL != null && !URL.equalsIgnoreCase("")) {
isNotificationURL = true;
deepLinkingURL = URL;
} else isNotificationURL = false;
Log.i(TAG, " LOG24 " + deepLinkingURL);
if (!OPEN_SPECIAL_URLS_IN_NEW_TAB) {
Log.i(TAG, "if ");
WebView.HitTestResult result = view.getHitTestResult();
String data = result.getExtra();
Context context = view.getContext();
if (data == null) {
Log.i(TAG, "else true ");
WebView newWebView = new WebView(view.getContext());
newWebView.setWebChromeClient(new MyWebChromeClient());
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(newWebView);
resultMsg.sendToTarget();
return true;
} else {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(data));
context.startActivity(browserIntent);
}
} else {
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
builder.setToolbarColor(getResources().getColor(R.color.colorPrimaryDark));
CustomTabsIntent customTabsIntent = builder.build();
WebView.HitTestResult result = view.getHitTestResult();
String data = result.getExtra();
Log.i("TAG", " data " + data);
String url = "";
WebView newWebView = new WebView(view.getContext());
newWebView.setWebChromeClient(new WebChromeClient());
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(newWebView);
resultMsg.sendToTarget();
}
Log.i("TAG", " running this main activity ");
return true;
}
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.i(TAG, " onJsalert");
return super.onJsAlert(view, url, message, result);
}
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
mUM = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(Intent.createChooser(i, "Upload"), FCR);
}
@SuppressLint("InlinedApi")
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
if (Config.requireStorage && Config.requireCamera) {
String[] perms = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, perms, FCR);
} else if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, FCR);
} else if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, FCR);
} else if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, FCR);
}
if (mUMA != null) {
mUMA.onReceiveValue(null);
}
mUMA = filePathCallback;
if (Arrays.asList(fileChooserParams.getAcceptTypes()).contains("audio/*")) {
Intent chooserIntent = fileChooserParams.createIntent();
startActivityForResult(chooserIntent, CODE_AUDIO_CHOOSER);
return true;
}
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCM);
} catch (IOException ex) {
Log.e(TAG, "Image file creation failed", ex);
}
if (photoFile != null) {
mCM = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".provider", photoFile));
} else {
takePictureIntent = null;
}
}
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {
File videoFile = null;
try {
videoFile = createVideoFile();
takeVideoIntent.putExtra("PhotoPath", mVM);
} catch (IOException ex) {
Log.e(TAG, "Video file creation failed", ex);
}
if (videoFile != null) {
mVM = "file:" + videoFile.getAbsolutePath();
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT,
FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".provider", videoFile));
} else {
takeVideoIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
contentSelectionIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/* video/*");
contentSelectionIntent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"image/*", "video/*"});
Intent[] intentArray;
if (takePictureIntent != null && takeVideoIntent != null) {
intentArray = new Intent[]{takePictureIntent, takeVideoIntent};
} else if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else if (takeVideoIntent != null) {
intentArray = new Intent[]{takeVideoIntent};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Upload");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, FCR);
}
return true;
}
});
final WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setGeolocationEnabled(true);
webSettings.setBuiltInZoomControls(false);
webSettings.setSupportZoom(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
if (Config.CLEAR_CACHE_ON_STARTUP) {
webSettings.setAppCacheEnabled(false);
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
} else {
webSettings.setAppCacheEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
}
webSettings.setAllowUniversalAccessFromFileURLs(true);
webSettings.setAllowFileAccessFromFileURLs(true);
webSettings.setAllowFileAccess(true);
//webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
webSettings.setAllowContentAccess(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);
webSettings.setDatabaseEnabled(true);
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
if (!Config.USER_AGENT.isEmpty()) {
webSettings.setUserAgentString(Config.USER_AGENT);
}
webView.setWebViewClient(新的MyWebViewClient(){
私人处理程序notificationHandler;
public void onGeolocationPermissionsShowPrompt(字符串来源,GeolocationPermissions.Callback){
callback.invoke(origin、true、false);
}
@凌驾
public void onReceivedError(WebView视图、int errorCode、字符串描述、字符串url){
if(Config.FALLBACK\u使用\u本地\u HTML\u文件夹\u if\u脱机){
loadLocal(索引文件);
}否则{
webView.setVisibility(View.GONE);
offlineLayout.setVisibility(View.VISIBLE);
}
}
@凌驾
公共布尔值shouldOverrideUrlLoading(WebView视图,字符串url){
//此处的基本覆盖部分(1/2)
if(url.startsWith(“mailto:”){
startActivity(新的意图(Intent.ACTION_SENDTO,Uri.parse(url));
返回true;
}
if(url.startsWith(“share:”)| | url.contains(“api.whatsapp.com”)){
Intent i=新的Intent(Intent.ACTION_视图,Uri.parse(url));
星触觉(i);
返回true;
}
if(url.startsWith(“whatsapp:”)){
意图i=新意图();
i、 setPackage(“com.whatsapp”);
i、 设置动作(意图、动作和发送);
i、 setType(“文本/普通”);
星触觉(i);
返回true;
}
if(url.startsWith(“geo:)| | url.contains(“maps:)){
Intent i=新的Intent(Intent.ACTION_视图,Uri.parse(url));
星触觉(i);
返回true;
}
if(url.startsWith(“市场:”){
Intent i=新的Intent(Intent.ACTION_视图,Uri.parse(url));
星触觉(i);
返回true;
}
if(url.startsWith(“maps.app.goo.gl”)){
Intent i=新的Intent(Intent.ACTION_视图,Uri.parse(url));
星触觉(i);
返回true;
}
如果(url.contains(“maps.google.com”)){
Intent i=新的Intent(Intent.ACTION_视图,Uri.parse(url));
星触觉(i);
返回true;
}
if(url.startsWith(“intent:”){
Intent i=新的Intent(Intent.ACTION_视图,Uri.parse(url));
星触觉(i);
返回true;
}
如果(url.startsWith(“电话:”){
Intent i=新的Intent(Intent.ACTION_视图,Uri.parse(url));
星触觉(i);
返回true;
}
如果(url.startsWith(“sms:”){
Intent i=新的Intent(Intent.ACTION_视图,Uri.parse(url));
星触觉(i);
返回true;
}
如果(url.startsWith(“play.google.com”)){
Intent i=新的Intent(Intent.ACTION_视图,Uri.parse(url));
星触觉(i);
返回true;
}
如果(在新选项卡中打开特殊URL){
WebView.HitTestResult=view.getHitTestResult();
字符串数据=result.getExtra();
Log.i(标签,“数据:”+数据);
如果((数据!=null&&data)