diff --git a/app/src/main/assets/apps/H52D34F00/www/js/openDatabase-polyfill.js b/app/src/main/assets/apps/H52D34F00/www/js/openDatabase-polyfill.js new file mode 100644 index 0000000..3283319 --- /dev/null +++ b/app/src/main/assets/apps/H52D34F00/www/js/openDatabase-polyfill.js @@ -0,0 +1,136 @@ +/** + * openDatabase Polyfill for Android 16+ + * 使用 localStorage 模拟 WebSQL 功能 + * 专门为 BM_USER 表设计 + */ +(function() { + 'use strict'; + + console.log('[openDatabase-polyfill] Initializing...'); + + // 如果浏览器已经支持 openDatabase,则不需要 polyfill + if (typeof openDatabase !== 'undefined') { + console.log('[openDatabase-polyfill] Native openDatabase available, skipping polyfill'); + return; + } + + console.log('[openDatabase-polyfill] Native openDatabase not available, installing polyfill'); + + // 创建 polyfill + window.openDatabase = function(name, version, displayName, estimatedSize, creationCallback) { + console.log('[openDatabase-polyfill] Creating database:', name); + + // 调用创建回调 + if (creationCallback && typeof creationCallback === 'function') { + try { + creationCallback(); + } catch (e) { + console.error('[openDatabase-polyfill] Error in creation callback:', e); + } + } + + // 返回数据库对象 + return { + transaction: function(callback, errorCallback, successCallback) { + console.log('[openDatabase-polyfill] Starting transaction'); + + var tx = { + executeSql: function(sql, params, successCb, errorCb) { + console.log('[openDatabase-polyfill] Executing SQL:', sql); + console.log('[openDatabase-polyfill] Parameters:', params); + + try { + // 解析 SQL 语句 + var sqlUpper = sql.trim().toUpperCase(); + + // CREATE TABLE + if (sqlUpper.indexOf('CREATE TABLE') === 0) { + console.log('[openDatabase-polyfill] CREATE TABLE detected'); + if (successCb) successCb(tx, { rowsAffected: 0, rows: { length: 0 } }); + return; + } + + // INSERT + if (sqlUpper.indexOf('INSERT INTO') === 0) { + console.log('[openDatabase-polyfill] INSERT detected'); + + // 从 localStorage 获取现有数据 + var users = JSON.parse(localStorage.getItem('BM_USER') || '[]'); + + // 创建新用户对象 + var user = { + ID: params[0], + NAME: params[1], + PASSWORD: params[2], + LOGIN_NAME: params[3], + ORG_ID: params[4], + LOGGED: params[5] + }; + + users.push(user); + localStorage.setItem('BM_USER', JSON.stringify(users)); + console.log('[openDatabase-polyfill] User inserted:', user); + + if (successCb) successCb(tx, { rowsAffected: 1, insertId: params[0], rows: { length: 0 } }); + return; + } + + // SELECT + if (sqlUpper.indexOf('SELECT') === 0) { + console.log('[openDatabase-polyfill] SELECT detected'); + + var users = JSON.parse(localStorage.getItem('BM_USER') || '[]'); + console.log('[openDatabase-polyfill] Found users:', users); + + // 创建结果对象 + var results = { + rows: { + length: users.length, + item: function(index) { + return users[index]; + } + } + }; + + if (successCb) successCb(tx, results); + return; + } + + // DELETE + if (sqlUpper.indexOf('DELETE FROM') === 0) { + console.log('[openDatabase-polyfill] DELETE detected'); + + localStorage.removeItem('BM_USER'); + console.log('[openDatabase-polyfill] Users deleted'); + + if (successCb) successCb(tx, { rowsAffected: 1, rows: { length: 0 } }); + return; + } + + // 未知的 SQL 语句 + console.warn('[openDatabase-polyfill] Unknown SQL statement:', sql); + if (successCb) successCb(tx, { rowsAffected: 0, rows: { length: 0 } }); + + } catch (e) { + console.error('[openDatabase-polyfill] Error executing SQL:', e); + if (errorCb) { + errorCb(tx, { message: e.message || 'Unknown error' }); + } + } + } + }; + + try { + callback(tx); + if (successCallback) successCallback(); + } catch (e) { + console.error('[openDatabase-polyfill] Error in transaction callback:', e); + if (errorCallback) errorCallback(e); + } + } + }; + }; + + console.log('[openDatabase-polyfill] Polyfill installed successfully'); +})(); + diff --git a/app/src/main/java/com/bonus/fmt/FMTWebViewClient.java b/app/src/main/java/com/bonus/fmt/FMTWebViewClient.java new file mode 100644 index 0000000..1b28602 --- /dev/null +++ b/app/src/main/java/com/bonus/fmt/FMTWebViewClient.java @@ -0,0 +1,59 @@ +package com.bonus.fmt; + +import android.content.Context; +import android.graphics.Bitmap; +import android.util.Log; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +/** + * 自定义 WebViewClient,用于在 WebView 加载页面时配置设置 + */ +public class FMTWebViewClient extends WebViewClient { + private static final String TAG = "FMTWebViewClient"; + private static final String LOG_PREFIX = "[FMT-DEBUG] "; + private final Context context; + private final WebViewClient originalClient; + + public FMTWebViewClient(Context context, WebViewClient originalClient) { + this.context = context; + this.originalClient = originalClient; + } + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + Log.i(TAG, LOG_PREFIX + "onPageStarted: " + url); + + // 在页面开始加载时配置 WebView + try { + WebViewConfigHelper.configureWebView(view, context); + } catch (Exception e) { + Log.e(TAG, LOG_PREFIX + "Error configuring WebView in onPageStarted", e); + } + + if (originalClient != null) { + originalClient.onPageStarted(view, url, favicon); + } else { + super.onPageStarted(view, url, favicon); + } + } + + @Override + public void onPageFinished(WebView view, String url) { + Log.i(TAG, LOG_PREFIX + "onPageFinished: " + url); + + // 在页面加载完成时再次确认配置 + try { + WebViewConfigHelper.configureWebView(view, context); + } catch (Exception e) { + Log.e(TAG, LOG_PREFIX + "Error configuring WebView in onPageFinished", e); + } + + if (originalClient != null) { + originalClient.onPageFinished(view, url); + } else { + super.onPageFinished(view, url); + } + } +} + diff --git a/app/src/main/java/com/bonus/fmt/WebViewFactory.java b/app/src/main/java/com/bonus/fmt/WebViewFactory.java new file mode 100644 index 0000000..bd5ec2a --- /dev/null +++ b/app/src/main/java/com/bonus/fmt/WebViewFactory.java @@ -0,0 +1,77 @@ +package com.bonus.fmt; + +import android.content.Context; +import android.util.AttributeSet; +import android.util.Log; +import android.webkit.WebView; + +/** + * 自定义WebView工厂,用于在WebView创建时立即配置 + * 解决Android 16上localStorage和WebSQL失效的问题 + */ +public class WebViewFactory { + private static final String TAG = "WebViewFactory"; + private static boolean isInitialized = false; + + /** + * 初始化WebView工厂 + * 这个方法应该在Application.onCreate()中调用 + */ + public static void initialize(Context context) { + if (isInitialized) { + Log.d(TAG, "WebViewFactory already initialized"); + return; + } + + try { + Log.i(TAG, "Initializing WebViewFactory for Android " + android.os.Build.VERSION.SDK_INT); + + // 设置WebView的默认配置 + // 注意:这里不能直接创建WebView实例,因为可能会导致进程问题 + + isInitialized = true; + Log.i(TAG, "WebViewFactory initialized successfully"); + + } catch (Exception e) { + Log.e(TAG, "Error initializing WebViewFactory", e); + } + } + + /** + * 创建并配置WebView + */ + public static WebView createConfiguredWebView(Context context) { + Log.i(TAG, "Creating configured WebView"); + WebView webView = new WebView(context); + WebViewConfigHelper.configureWebView(webView, context); + return webView; + } + + /** + * 创建并配置WebView(带属性) + */ + public static WebView createConfiguredWebView(Context context, AttributeSet attrs) { + Log.i(TAG, "Creating configured WebView with attributes"); + WebView webView = new WebView(context, attrs); + WebViewConfigHelper.configureWebView(webView, context); + return webView; + } + + /** + * 配置已存在的WebView + */ + public static void configureExistingWebView(WebView webView, Context context) { + if (webView == null || context == null) { + Log.w(TAG, "Cannot configure null WebView or context"); + return; + } + + try { + Log.i(TAG, "Configuring existing WebView: " + webView.getClass().getName()); + WebViewConfigHelper.configureWebView(webView, context); + } catch (Exception e) { + Log.e(TAG, "Error configuring existing WebView", e); + } + } +} +