英文:
How to make the 'Remember Me' function in Blazor Server login page work consistently in Android WebView?
问题
在我的Blazor Server应用程序中,我使用了内置的AuthenticationStateProvider服务进行Blazor Server的身份验证。该服务的登录页面具有正常工作的“记住我”功能。
在我的Android应用程序中,我使用WebView显示Blazor Server网站。
MainActivity.java:
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private WebView webView;
private ProgressBar progressBar;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
progressBar = findViewById(R.id.progressBar);
// 配置WebView设置
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
CookieManager.getInstance().setAcceptCookie(true);
CookieManager.getInstance().acceptThirdPartyCookies(webView);
// 设置WebView客户端
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
webView.setVisibility(View.GONE);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
webView.setVisibility(View.VISIBLE);
}
});
webView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
progressBar.setProgress(progress);
}
});
// 加载网站
webView.loadUrl("URL HERE");
}
@Override
public void onBackPressed() {
// 处理WebView内的返回按钮按下
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
}
添加到AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:indeterminate="false"
android:max="100"
android:progress="0"
android:visibility="gone" />
</RelativeLayout>
当我通过WebView应用程序登录时,“记住我”功能在100次尝试中只有1次成功,并将凭据存储在我的手机上的应用数据中。我知道这是因为:
- 即使在Google Chrome中清除浏览器历史记录后,我仍然保持登录状态。
- 即使清除应用程序的缓存存储后,我仍然保持登录状态。
- 当我清除应用程序的所有数据(应用信息 -> 存储 -> 清除数据)时,我不再保持登录状态。
在其他99次尝试中,它不会记住登录,当我再次打开WebView应用程序时,我必须重新登录。
如何使此功能在100次尝试中都能正常工作?我从未弄清楚应用程序何时保存登录凭据以及何时不保存...
我已激活了JavaScript和(第三方)Cookie。问题仍未解决。
英文:
I have a Blazor Server app where I use the build-in AuthenticationStateProvider service for Blazor Server. The login page of this service has a remember me function that works properly.
Within my Android App I show the Blazor Server website with a WebView
MainActivity.Java:
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private WebView webView;
private ProgressBar progressBar;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
progressBar = findViewById(R.id.progressBar);
// Configure WebView settings
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
CookieManager.getInstance().setAcceptCookie(true);
CookieManager.getInstance().acceptThirdPartyCookies(webView);
// Set WebView clients
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
webView.setVisibility(View.GONE);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
webView.setVisibility(View.VISIBLE);
}
});
webView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
progressBar.setProgress(progress);
}
});
// Load the website
webView.loadUrl("URL HERE");
}
@Override
public void onBackPressed() {
// Handle back button press inside WebView
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
}
Added to the AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
Activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:indeterminate="false"
android:max="100"
android:progress="0"
android:visibility="gone" />
</RelativeLayout>
When I login via the WebView app, the Remember Me function is working 1 out of 100 times and stores the credentials local on my phone within the app data. I know this because:
- I remain logged in when I clear my browser history on Google Chrome
- I remain logged in when I clear the cache storage of the app
- I am no longer logged in when I clear all data of the app (App info -> Storage -> Clear Data)
The other 99 out of 100 times it does not remember the login and when I open de WebView app again I have to login again.
How can I make this functionality work 100 out of 100 times? I never got to figure out when the app does save the login credentials and when it does not...
I activated JavaScript and (third party) coockies. Problem still not solved.
答案1
得分: 0
我发现 WebView 应用程序并不总是正确同步存储的 Cookie。为了修复这个问题,将以下代码添加到 MainActivity 中:
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
CookieManager.getInstance().flush();
}
});
完整代码:
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private WebView webView;
private ProgressBar progressBar;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
progressBar = findViewById(R.id.progressBar);
// 配置 WebView 设置
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
CookieManager.getInstance().setAcceptCookie(true);
CookieManager.getInstance().acceptThirdPartyCookies(webView);
// 设置 WebView 客户端
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
webView.setVisibility(View.GONE);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
CookieManager.getInstance().flush();
progressBar.setVisibility(View.GONE);
webView.setVisibility(View.VISIBLE);
}
});
webView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
progressBar.setProgress(progress);
}
});
// 加载网站
webView.loadUrl("在此处输入网址");
}
@Override
public void onBackPressed() {
// 处理 WebView 内部的返回按钮按下事件
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
}
英文:
I found out the WebView App is not always syncing the stored cookies correctly. To fix this add the following code to the MainActivity:
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
CookieManager.getInstance().flush();
}
}
full code:
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private WebView webView;
private ProgressBar progressBar;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
progressBar = findViewById(R.id.progressBar);
// Configure WebView settings
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
CookieManager.getInstance().setAcceptCookie(true);
CookieManager.getInstance().acceptThirdPartyCookies(webView);
// Set WebView clients
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
webView.setVisibility(View.GONE);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
CookieManager.getInstance().flush();
progressBar.setVisibility(View.GONE);
webView.setVisibility(View.VISIBLE);
}
});
webView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
progressBar.setProgress(progress);
}
});
// Load the website
webView.loadUrl("URL HERE");
}
@Override
public void onBackPressed() {
// Handle back button press inside WebView
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论