package com.xscm.moduleutil.activity; import static android.view.View.GONE; import static android.view.View.VISIBLE; import android.annotation.SuppressLint; import android.app.Activity; import android.content.ClipData; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.webkit.GeolocationPermissions; import android.webkit.JavascriptInterface; import android.webkit.ValueCallback; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; import androidx.annotation.Nullable; import com.alibaba.android.arouter.facade.annotation.Autowired; import com.alibaba.android.arouter.facade.annotation.Route; import com.alibaba.android.arouter.launcher.ARouter; import com.blankj.utilcode.util.LogUtils; import com.blankj.utilcode.util.ToastUtils; import com.xscm.moduleutil.R; import com.xscm.moduleutil.base.CommonAppContext; import com.xscm.moduleutil.databinding.ActivityWebViewBinding; import com.xscm.moduleutil.utils.ARouteConstants; import com.tencent.imsdk.v2.V2TIMConversation; import com.tencent.mm.opensdk.modelbiz.WXOpenCustomerServiceChat; import com.tencent.mm.opensdk.openapi.IWXAPI; import com.tencent.mm.opensdk.openapi.WXAPIFactory; import com.tencent.qcloud.tuicore.TUIConstants; import com.tencent.qcloud.tuikit.tuichat.classicui.page.TUIC2CChatActivity; import com.tencent.qcloud.tuikit.tuichat.classicui.page.TUIGroupChatActivity; /** * @author qx * @data 2025/6/3 * @description: webview公共方法 */ @Route(path = ARouteConstants.H5) public class WebViewActivity extends BaseAppCompatActivity { public String title; public String url; @Autowired public String type;//type=1:青少年模式 private ValueCallback mUploadMessage; private ValueCallback mUploadCallbackAboveL; private final int REQUEST_FILE_PICKER = 1; @SuppressLint("SetJavaScriptEnabled") @Override protected void initData() { WebSettings webSettings = mBinding.webView.getSettings(); // 禁用水平滚动 webSettings.setUseWideViewPort(true); webSettings.setLoadWithOverviewMode(true); webSettings.setJavaScriptEnabled(true); webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); //关闭webview中缓存 //增加JSBridge mBinding.webView.addJavascriptInterface(new WebAppInterface(this, type), "Android"); if (title != null && !title.isEmpty()) { if (title.contains("协议")) { webSettings.setDisplayZoomControls(false); // 隐藏默认缩放控件 webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL); // 使用正常布局算法 webSettings.setBuiltInZoomControls(false); webSettings.setSupportZoom(false); // 重要:设置布局算法为适应屏幕 webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING); // 设置初始缩放 mBinding.webView.setInitialScale(100); mBinding.webView.getSettings().setUseWideViewPort(false); } else { webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); } } else { webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); } webSettings.setBuiltInZoomControls(true); webSettings.setSupportZoom(true); webSettings.setDomStorageEnabled(true); webSettings.setBlockNetworkImage(false);//解决图片不显示 webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); mBinding.webView.setHorizontalScrollBarEnabled(false);//水平不显示 mBinding.webView.setVerticalScrollBarEnabled(false); //垂直不显示 mBinding.webView.setScrollbarFadingEnabled(false); mBinding.webView.setScrollContainer(true); mBinding.webView.setWebViewClient(new WebViewClient()); mBinding.webView.setBackgroundColor(Color.TRANSPARENT); mBinding.webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); mBinding.webView.requestFocus(); mBinding.webView.loadUrl(url); mBinding.webView.setWebChromeClient(new WebChromeClient() { //配置权限(同样在WebChromeClient中实现) @Override public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) { callback.invoke(origin, true, false); super.onGeolocationPermissionsShowPrompt(origin, callback); } @Override public void onProgressChanged(WebView view, int newProgress) { if (title != null && !title.isEmpty()) { if (title.contains("协议")) { if (newProgress >= 100) { // 页面加载完成后调整文本换行 new Handler().postDelayed(new Runnable() { @Override public void run() { // 注入CSS确保文字自动换行 mBinding.webView.loadUrl("javascript:(function() {" + "var sheets = document.styleSheets;" + "for (var i = 0; i < sheets.length; i++) {" + " try {" + " sheets[i].addRule('*', 'word-wrap: break-word !important; white-space: normal !important; overflow-x: hidden !important;', 0);" + " } catch(e) {" + " try {" + " sheets[i].insertRule('* { word-wrap: break-word !important; white-space: normal !important; overflow-x: hidden !important; }', 0);" + " } catch(e2) {}" + " }" + "}" + "})()"); } }, 100); } } } } // For Android < 3.0 public void openFileChooser(ValueCallback uploadMsg) { mUploadMessage = uploadMsg; // showFileChooser(); } // For Android > 4.1.1 public void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture) { mUploadMessage = uploadMsg; // showFileChooser(); } // For Android > 5.0支持多张上传 @Override public boolean onShowFileChooser(WebView webView, ValueCallback uploadMsg, WebChromeClient.FileChooserParams fileChooserParams) { mUploadCallbackAboveL = uploadMsg; showFileChooser(); return true; } @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); // tvTitle.setText(title); } }); } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getOnBackPressedDispatcher() != null) { getOnBackPressedDispatcher().addCallback(this, new androidx.activity.OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { // 拦截返回键,显示退出对话框而不是直接退出 showExitRoomDialog(); } }); } } private void showExitRoomDialog() { if (type != null) { if (type.equals("1")) { ARouter.getInstance().build(ARouteConstants.UNDERAGE_ACTIVITY).withInt("type", 1).navigation(); } else { finish(); } } else { finish(); } } private void showFileChooser() { // 这里可以扩展为显示对话框让用户选择“拍照”或“从相册选择” Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); startActivityForResult(Intent.createChooser(intent, "选择图片"), REQUEST_FILE_PICKER); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_FILE_PICKER) { if (mUploadMessage != null) { Uri result = data == null || resultCode != RESULT_OK ? null : data.getData(); mUploadMessage.onReceiveValue(result); mUploadMessage = null; } else if (mUploadCallbackAboveL != null) { Uri[] results = null; if (resultCode == Activity.RESULT_OK && data != null) { String dataString = data.getDataString(); ClipData clipData = data.getClipData(); if (clipData != null) { results = new Uri[clipData.getItemCount()]; for (int i = 0; i < clipData.getItemCount(); i++) { ClipData.Item item = clipData.getItemAt(i); results[i] = item.getUri(); } } if (dataString != null) results = new Uri[]{Uri.parse(dataString)}; } mUploadCallbackAboveL.onReceiveValue(results); mUploadCallbackAboveL = null; } } } @Override public void onBackPressed() { // 当type==1时,禁止返回键和手势返回 // 不执行任何操作,禁止返回 if (type != null) { if (type.equals("1")) { ARouter.getInstance().build(ARouteConstants.UNDERAGE_ACTIVITY).withInt("type", 1).navigation(); } else { finish(); } return; } else { finish(); } // 正常处理返回键 super.onBackPressed(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { LogUtils.d("MainActivity", "onKeyDown called, keyCode: " + keyCode); if (keyCode == KeyEvent.KEYCODE_BACK) { if (type != null) { if (type.equals("1")) { ARouter.getInstance().build(ARouteConstants.UNDERAGE_ACTIVITY).withInt("type", 1).navigation(); } else { finish(); } } else { finish(); } return true; // 消费事件 } return super.onKeyDown(keyCode, event); } // @Override // public boolean dispatchTouchEvent(MotionEvent ev) { // // 当type==1时,禁止手势滑动返回 // if (type.equals("1")) { // // 检查是否是边缘滑动返回手势 // if (ev.getAction() == MotionEvent.ACTION_DOWN) { // // 如果触摸点在屏幕边缘,拦截事件 // if (ev.getX() < 50) { // 左边缘50像素内 // return true; // 拦截事件,不传递给子View // } // } // } // return super.dispatchTouchEvent(ev); // } @Override protected void initView() { getWindow().getDecorView().setBackgroundResource(com.xscm.moduleutil.R.color.white); title = getIntent().getStringExtra("title"); url = getIntent().getStringExtra("url"); type = getIntent().getStringExtra("type"); if (type != null) { // 当type==1时,禁用返回手势滑动 if (type.equals("1")) { // 禁用边缘滑动返回 if (getSupportActionBar() != null) { getSupportActionBar().setDisplayHomeAsUpEnabled(false); } } } if (title != null) { if (title.equals("举报") || title.equals("等级") || title.equals("公会") || title.equals("邀请") || title.equals("反馈")) { mBinding.topBar.setVisibility(GONE); // mBinding.webView.setPadding(0,20,0,0); } else { mBinding.topBar.setVisibility(VISIBLE); mBinding.topBar.setTitle(title); } } else { if (url.equals(CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl() + "/api/Page/page_show?id=6")) { mBinding.topBar.setVisibility(VISIBLE); mBinding.topBar.setTitle("用户协议"); } else if (url.equals(CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl() + "/api/Page/page_show?id=4")) { mBinding.topBar.setVisibility(VISIBLE); mBinding.topBar.setTitle("隐私协议"); } else { mBinding.topBar.setVisibility(GONE); } } } @Override protected int getLayoutId() { return R.layout.activity_web_view; } public class WebAppInterface { Context mContext; String type; WebAppInterface(Context c, String type1) { mContext = c; type = type1; } // 被 H5 调用的方法 @JavascriptInterface public void showToast(String toast) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); } @JavascriptInterface public void closeWeb() { if (type != null) { if (type.equals("1")) { ARouter.getInstance().build(ARouteConstants.UNDERAGE_ACTIVITY).withInt("type", 1).navigation(); } else { finish(); } } else { finish(); } } @JavascriptInterface public void customerService() { String appId = CommonAppContext.getInstance().getCurrentEnvironment().getWxAppId(); // 填移动应用(App)的 AppId IWXAPI api = WXAPIFactory.createWXAPI(mContext, appId); // 判断当前版本是否支持拉起客服会话 WXOpenCustomerServiceChat.Req req = new WXOpenCustomerServiceChat.Req(); req.corpId = "ww1de4300858c0b461"; // 企业ID req.url = "https://work.weixin.qq.com/kfid/kfcb3d23a59c188a0e7"; // 客服URL api.sendReq(req); } @JavascriptInterface public void jumpRoomPage(String room_id) { ARouter.getInstance().build(ARouteConstants.ROOM_DETAILS).withString("form", "首页").withString("roomId", room_id).navigation(); } @JavascriptInterface public void jumpWebPage(String objects) { // ARouter.getInstance().build(ARouteConstants.USER_HOME_PAGE).navigation(); ARouter.getInstance().build(ARouteConstants.USER_HOME_PAGE).withString("userId", objects).navigation(); } @JavascriptInterface public void enterGroupChat(String group_id, String cover, String guild_name) { Intent intent = new Intent(mContext, TUIGroupChatActivity.class); intent.putExtra(TUIConstants.TUIChat.CHAT_ID, group_id); intent.putExtra(TUIConstants.TUIChat.CHAT_TYPE, V2TIMConversation.V2TIM_GROUP); mContext.startActivity(intent); } @JavascriptInterface public void chatWithUser(String user_id, String nickname) { Intent intent = new Intent(mContext, TUIC2CChatActivity.class); intent.putExtra(TUIConstants.TUIChat.CHAT_ID, user_id); intent.putExtra(TUIConstants.TUIChat.CHAT_TYPE, V2TIMConversation.V2TIM_C2C); mContext.startActivity(intent); } @JavascriptInterface public void exchange() { ARouter.getInstance().build(ARouteConstants.CURRENCY).navigation(); } @JavascriptInterface public void Withdrawal() { ARouter.getInstance().build(ARouteConstants.WITHDRAWAL_ACTIVITY).navigation(); } @JavascriptInterface public void enterAuthent() {//实名认证 ARouter.getInstance().build(ARouteConstants.REAL_NAME_ACTIVITY2).navigation(); } @JavascriptInterface public void Recharge() { ARouter.getInstance().build(ARouteConstants.RECHARGE_ACTIVITY).navigation(); } } @JavascriptInterface public void closeWeb() { //做原生操作 // Intent intent = new Intent(mContext, ListActivity.class); // intent.putExtra("menuName", msg); // startActivity(intent); LogUtils.e("closeWeb"); } }