diff --git a/webpagesources/build.properties b/webpagesources/build.properties
index 6c25536..d2f1af9 100644
--- a/webpagesources/build.properties
+++ b/webpagesources/build.properties
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
-#Tue Jun 10 07:12:46 GMT 2025
+#Tue Jun 10 19:49:43 GMT 2025
stageCount=0
libraryProject=
baseVersion=15.0
publishVersion=15.0.0
-buildCount=11
+buildCount=19
baseBetaVersion=15.0.1
diff --git a/webpagesources/src/beta/AndroidManifest.xml b/webpagesources/src/beta/AndroidManifest.xml
index ee78d9f..fa8f0b4 100644
--- a/webpagesources/src/beta/AndroidManifest.xml
+++ b/webpagesources/src/beta/AndroidManifest.xml
@@ -2,10 +2,23 @@
-
+
+
+
+
+
diff --git a/webpagesources/src/main/AndroidManifest.xml b/webpagesources/src/main/AndroidManifest.xml
index 93f023c..848a857 100644
--- a/webpagesources/src/main/AndroidManifest.xml
+++ b/webpagesources/src/main/AndroidManifest.xml
@@ -12,6 +12,9 @@
+
+
+
+
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/webpagesources/src/main/java/cc/winboll/studio/webpagesources/common/BaseWebView.java b/webpagesources/src/main/java/cc/winboll/studio/webpagesources/common/BaseWebView.java
index 43200de..c85b5a7 100644
--- a/webpagesources/src/main/java/cc/winboll/studio/webpagesources/common/BaseWebView.java
+++ b/webpagesources/src/main/java/cc/winboll/studio/webpagesources/common/BaseWebView.java
@@ -1,12 +1,5 @@
package cc.winboll.studio.webpagesources.common;
-/**
- * @Author ZhanGSKen@QQ.COM
- * @Date 2023/06/22 12:57:08
- * @Describe 网页客户端视图基础类
- * 参考:https://blog.csdn.net/Azhuoyanyan/article/details/17531887?app_version=5.15.2&code=app_1562916241&csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%2217531887%22%2C%22source%22%3A%22weixin_38986226%22%7D&uLinkId=usr1mkqgl919blen&utm_source=app
- *
- */
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -14,8 +7,8 @@ import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
+import android.os.Build;
import android.os.Handler;
-import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.view.GestureDetector;
@@ -66,71 +59,87 @@ public class BaseWebView extends WebView {
WebChromeClient.FileChooserParams mFileChooserParams;
AuthLoginDialog mAuthLoginDialog;
- // AuthenticationBean mLastAuthenticationBean;
- /**
- * 在java代码里new的时候会用到
- * @param context
- */
public BaseWebView(Context context) {
super(context);
}
- /**
- * 在xml布局文件中使用时自动调用
- * @param context
- */
public BaseWebView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
mBaseWebViewHandler = new BaseWebViewHandler();
- /*TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.test);
- String text = ta.getString(R.styleable.test_text);
- setText(text + " ZhanGSKen.CN");
- ta.recycle();*/
- //setBackgroundResource(R.drawable.custom_edittext_background);
- //setMinWidth(100);
- //setPadding(10,0,10,0);
- //setPaddingRelative(0,0,0,0);
MyWebChromeClient mMyWebChromeClient = new MyWebChromeClient();
setWebChromeClient(mMyWebChromeClient);
mBaseWebViewClient = new BaseWebViewClient();
setWebViewClient(mBaseWebViewClient);
WebSettings mWebSettings = getSettings();
- // 设置是否启用安全浏览。
+
+ // ------------------- 优化后的 WebSettings 配置 -------------------
+ // 基础功能配置
+ mWebSettings.setJavaScriptEnabled(true); // 启用JavaScript
+ mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true); // 允许JS打开新窗口
+ mWebSettings.setDomStorageEnabled(true); // 启用DOM存储
+ mWebSettings.setDatabaseEnabled(true); // 启用数据库存储
+ //mWebSettings.setAppCacheEnabled(true); // 启用应用缓存
+ String appCachePath = context.getCacheDir().getAbsolutePath();
+ //mWebSettings.setAppCachePath(appCachePath);
+ mWebSettings.setCacheMode(WebSettings.LOAD_DEFAULT); // 缓存模式
+
+ // 页面渲染与缩放
+ mWebSettings.setUseWideViewPort(true); // 支持viewport标签
+ mWebSettings.setLoadWithOverviewMode(true); // 自动加载时适应屏幕
+ mWebSettings.setSupportZoom(true); // 支持缩放
+ mWebSettings.setBuiltInZoomControls(true); // 显示缩放控件
+ mWebSettings.setDisplayZoomControls(false); // 隐藏默认缩放控件
+ mWebSettings.setDefaultTextEncodingName("utf-8"); // 默认编码
+ mWebSettings.setMinimumFontSize(12); // 最小字体大小
+
+ // 性能优化
+ mWebSettings.setLoadsImagesAutomatically(true); // 自动加载图片
+ mWebSettings.setBlockNetworkImage(false); // 不阻止图片加载
+ mWebSettings.setRenderPriority(WebSettings.RenderPriority.HIGH); // 高渲染优先级
+
+ // 混合内容配置(Android 5.0+)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ mWebSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
+ }
+
+ // 安全配置
+ mWebSettings.setSafeBrowsingEnabled(true); // 启用安全浏览
+ mWebSettings.setAllowFileAccess(true); // 允许访问文件URL
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ mWebSettings.setAllowFileAccessFromFileURLs(false); // 禁止文件URL访问其他文件
+ mWebSettings.setAllowUniversalAccessFromFileURLs(false); // 禁止文件URL执行JS
+ }
+
+ // 高级功能(可选)
+ mWebSettings.setGeolocationEnabled(true); // 启用地理位置
+ mWebSettings.setNeedInitialFocus(true); // 获取初始焦点
+ mWebSettings.setSaveFormData(true); // 保存表单数据
+ mWebSettings.setEnableSmoothTransition(true); // 平滑过渡动画
+
+ // 硬件加速(Android 3.0+)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ }
+
+ // 字体缩放(100%为默认)
+ mWebSettings.setTextZoom(100);
+ // ------------------- WebSettings 配置结束 -------------------
+
mWebSettings.setSafeBrowsingEnabled(true);
- // 启用JavaScript
- mWebSettings.setJavaScriptEnabled(true);
- // 设置可以支持缩放
- mWebSettings.setSupportZoom(true);
- // 设置true,才能让Webivew支持标签的viewport属性
- mWebSettings.setUseWideViewPort(true);
- // 设置出现缩放工具
- mWebSettings.setBuiltInZoomControls(true);
- // 设置隐藏缩放控件
- mWebSettings.setDisplayZoomControls(false);
- mWebSettings.setDefaultTextEncodingName("utf-8");
- // 允许WebView运行JavaScript,并开启JavaScript Console以接收日志
- mWebSettings.setDomStorageEnabled(true); // 如果有localStorage等需要
- mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);
addJavascriptInterface(new JSConsole(mContext), "console");
addJavascriptInterface(new JS(mContext), "local_obj");
- // 最小缩放等级
setInitialScale(60);
- mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);
- //winbollView.loadUrl("https://www.so.com");
-
mGestureDetector = new GestureDetectorCompat(mContext, new GestureDetector.SimpleOnGestureListener() {
@Override
public void onLongPress(MotionEvent e) {
downX = (int) e.getX();
downY = (int) e.getY();
- //LogUtils.d(TAG, "downX is " + Integer.toString(downX));
- //LogUtils.d(TAG, "downY is " + Integer.toString(downY));
}
});
@@ -146,43 +155,19 @@ public class BaseWebView extends WebView {
if (type == WebView.HitTestResult.UNKNOWN_TYPE)
return false;
if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
- //let TextViewhandles context menu return true;
}
final ItemLongClickedPopWindow itemLongClickedPopWindow = new ItemLongClickedPopWindow(mContext, ItemLongClickedPopWindow.IMAGE_VIEW_POPUPWINDOW, UIUtil.dip2px(mContext, 180), ViewGroup.LayoutParams.WRAP_CONTENT);
- // Setup custom handlingdepending on the type
- switch (type) {
- case WebView.HitTestResult.PHONE_TYPE: // 处理拨号
- break;
- case WebView.HitTestResult.EMAIL_TYPE: // 处理Email
- break;
- case WebView.HitTestResult.GEO_TYPE: // TODO
- break;
- case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
- break;
- case WebView.HitTestResult.SRC_ANCHOR_TYPE: // 超链接
- // Log.d(DEG_TAG, "超链接");
- //szUrl = result.getExtra();
- //break;
- case WebView.HitTestResult.IMAGE_TYPE: // 处理长按图片的菜单项
- szUrl = result.getExtra();
- //通过GestureDetector获取按下的位置,来定位PopWindow显示的位置
- itemLongClickedPopWindow.showAtLocation(v, Gravity.TOP | Gravity.LEFT, downX, downY + 10);
- break;
- default:
- break;
- }
+ szUrl = result.getExtra();
+
+ itemLongClickedPopWindow.showAtLocation(v, Gravity.TOP | Gravity.LEFT, downX, downY + 10);
itemLongClickedPopWindow.getView(R.id.item_longclicked_copylink)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- // 复制链接到剪贴板
- // Gets a handle to the clipboard service.
ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
- // Creates a new text clip to put on the clipboard
ClipData clip = ClipData.newPlainText("simple text", szUrl);
- // Set the clipboard's primary clip.
clipboard.setPrimaryClip(clip);
Toast.makeText(mContext, "Copy to clipboard.", Toast.LENGTH_SHORT).show();
itemLongClickedPopWindow.dismiss();
@@ -199,67 +184,12 @@ public class BaseWebView extends WebView {
return true;
}
});
- /*setOnCreateContextMenuListener(new View.OnCreateContextMenuListener(){
- public void onCreateContextMenu(ContextMenu menu, View arg1,
- ContextMenuInfo arg2) {
- final HitTestResult hitTestResult = ((WebView) arg1).getHitTestResult();
-
- MenuItem.OnMenuItemClickListener handler = new MenuItem.OnMenuItemClickListener() {
-
- public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case WEB_CopyLink : {
-
- break;
- }
- case WEB_DownLoadLink : {
- // 下载链接地址
- new Thread(new LinkDownLoadThread(hitTestResult.getExtra())).start();
- break;
- }
- }
- return true;
- }
- };
-
- // 添加上下文菜单
- int resultType = hitTestResult.getType();
- if ((resultType == HitTestResult.ANCHOR_TYPE) ||
- (resultType == HitTestResult.IMAGE_ANCHOR_TYPE) ||
- (resultType == HitTestResult.SRC_ANCHOR_TYPE) ||
- (resultType == HitTestResult.SRC_IMAGE_ANCHOR_TYPE)) {
- Intent i = new Intent();
- //AppLog.d("extrea", result.getExtra());
- MenuItem item = menu.add(0, WEB_CopyLink, 0, "Copy Link").setOnMenuItemClickListener(handler);
- MenuItem item2 = menu.add(0, WEB_DownLoadLink, 0, "DownLoad Link").setOnMenuItemClickListener(handler);
- item.setIntent(i);
- //menu.setHeaderTitle(hitTestResult.getExtra());
- TextView tv = new TextView(mContext);
- tv.setText(hitTestResult.getExtra());
- tv.setTextColor(0x8F000000);
- tv.setPadding(15, 5, 15, 5);
- menu.setHeaderView(tv);
- }
- }
- });
-
- setDownloadListener(new MyDownLoadListener(mContext));*/
}
- /**
- * 不会自动调用,如果有默认style时,在第二个构造函数中调用
- * @param context
- * @param attrs
- * @param defStyleAttr
- */
public BaseWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
- /*public void setLastUrl(String lastUrl) {
- this.mszLastUrl = lastUrl;
- }*/
-
public String getLastUrl() {
return _mszLastUrl;
}
@@ -269,12 +199,10 @@ public class BaseWebView extends WebView {
Pattern patternHttp = Pattern.compile("(?i)^http[s]{0,1}://", Pattern.CASE_INSENSITIVE);
Matcher matcherHttp = patternHttp.matcher(url);
if (matcherHttp.matches()) {
- // 加载普通 Http 协议访问
stopLoading();
loadUrl(url);
return;
} else {
- // 加载其他协议类型访问
Pattern pattern = Pattern.compile("^[a-z]+:.*", Pattern.MULTILINE);
Matcher matcher = pattern.matcher(url);
if (matcher.find()) {
@@ -303,25 +231,24 @@ public class BaseWebView extends WebView {
private class MyWebChromeClient extends WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
- //super.onProgressChanged(view, newProgress);
}
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
setFilePathCallback(filePathCallback);
setFileChooserParams(fileChooserParams);
- //ToastUtils.show("onShowFileChooser");
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
((AppCompatActivity)mContext).startActivityForResult(intent, MainActivity.REQUEST_FILE_CHOOSER);
return true;
- //return super.onShowFileChooser(webView, filePathCallback, fileChooserParams);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
- mGestureDetector.onTouchEvent(event);
+ boolean ret = mGestureDetector.onTouchEvent(event);
+ LogUtils.d(TAG, String.format("onTouchEvent ret : %s", ret));
+
return super.onTouchEvent(event);
}
@@ -335,7 +262,6 @@ public class BaseWebView extends WebView {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SHOW_DATA:{
- //LogUtils.d(TAG, "(String)msg.obj is " + (String)msg.obj);
loadDataWithBaseURL("", (String)msg.obj, "text/html", "UTF-8", "");
break;
}
@@ -344,14 +270,9 @@ public class BaseWebView extends WebView {
}
}
- /**
- * 逻辑处理
- * @author linzewu
- */
final class InJavaScriptLocalObj {
@JavascriptInterface
public void getSource(String html) {
- //LogUtils.d(TAG, html);
}
}
@@ -370,11 +291,6 @@ public class BaseWebView extends WebView {
}
}
- /**
- * @Author ZhanGSKen@QQ.COM
- * @Date 2023/06/22 12:57:08
- * @Describe 网页客户端基础类
- */
class BaseWebViewClient extends WebViewClient {
public static final String TAG = "BaseWebViewClient";
@@ -387,42 +303,16 @@ public class BaseWebView extends WebView {
mIOnPageFinished.onPageFinished(url);
LogUtils.d(TAG, "Page load finished : " + url);
_mszLastUrl = url;
- //ToastUtils.show("onPageFinished");
-
- new Handler(Looper.getMainLooper()).postDelayed(new Runnable(){
- @Override
- public void run() {
- if (mAuthLoginDialog != null) {
- mAuthLoginDialog.checkAndSaveLastAuthenticationBean();
- mAuthLoginDialog = null;
- }
- }
- }, 1000);
-
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
- // WinBoll Studio 网站证书校验
- /*if (SSLUtil.isSSLCertOk(error.getCertificate(), "9F568FCA9E2B3D59FF3BE2F5FF77CB5BFE1D30562D9880D2D354F0DF63A012E1")) {
- LogUtils.d(TAG, "WinBoll Studio 网站证书校验通过。");
- handler.proceed();
- return;
- }*/
LogUtils.d(TAG, "onReceivedSslError 0\nerror : " + error.toString());
- //LogUtils.d(TAG, "On Received Ssl Error.");
- //handler.proceed();
-
- //super.onReceivedSslError(view, handler, error);
}
@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
int statusCode = errorResponse.getStatusCode();
- /*if (statusCode == 404) {
- // 处理404错误
- Log.d("WebView", "Received a 404 error: " + failingUrl);
- }*/
LogUtils.d(TAG, "onReceivedHttpError statusCode " + Integer.toString(statusCode));
super.onReceivedHttpError(view, request, errorResponse);
}
@@ -431,18 +321,8 @@ public class BaseWebView extends WebView {
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
- /*if (errorCode == WebViewClient.ERROR_TIMEOUT) {
- LogUtils.d(TAG, "WebViewClient.ERROR_TIMEOUT");
- ToastUtils.show("WebViewClient.ERROR_TIMEOUT");
- } else if (errorCode == WebViewClient.ERROR_UNKNOWN) {
- LogUtils.d(TAG, "WebViewClient.ERROR_UNKNOWN");
- ToastUtils.show("WebViewClient.ERROR_UNKNOWN");
- }*/
LogUtils.d(TAG, "onReceivedError 1\nerrorCode : " + errorCode
+ "\ndescription :" + description + "\nfailingUrl : " + failingUrl);
-
- //在此处显示加载失败页面
- //loadFailure.setVisibility(View.VISIBLE);
}
@Override
@@ -462,13 +342,11 @@ public class BaseWebView extends WebView {
@Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
- //加载资源
}
@Override
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
- //super.onReceivedHttpAuthRequest(view, handler, host, realm);
mAuthLoginDialog = new AuthLoginDialog(view, handler, host, realm);
mAuthLoginDialog.show();
}
@@ -476,15 +354,20 @@ public class BaseWebView extends WebView {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
- //开始加载页面
LogUtils.d(TAG, "Page load started : " + url);
_mszLastUrl = url;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
- //点击链接跳转,对网页中超链接按钮的响应。
- //view.loadUrl(url);
+ view.loadUrl(url);
+ return true;
+ }
+
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
+ // 修复Android 5.0点击无反应的问题
+ view.loadUrl(request.getUrl().toString());
return true;
}
}
@@ -496,4 +379,18 @@ public class BaseWebView extends WebView {
public void setOnPageFinished(IOnPageFinished iOnPageFinished) {
mIOnPageFinished = iOnPageFinished;
}
+
+ public class JSConsole {
+ private Context mContext;
+
+ public JSConsole(Context context) {
+ this.mContext = context;
+ }
+
+ @JavascriptInterface
+ public void log(String message) {
+ LogUtils.d(TAG, message);
+ }
+ }
}
+
diff --git a/webpagesources/src/stage/AndroidManifest.xml b/webpagesources/src/stage/AndroidManifest.xml
index ee78d9f..007e0f0 100644
--- a/webpagesources/src/stage/AndroidManifest.xml
+++ b/webpagesources/src/stage/AndroidManifest.xml
@@ -5,7 +5,17 @@
+
+
+
+