|
@@ -0,0 +1,456 @@
|
|
|
+package com.cooleshow.student.ui.web;
|
|
|
+
|
|
|
+import static com.cooleshow.base.common.WebConstants.WEB_URL;
|
|
|
+
|
|
|
+import android.Manifest;
|
|
|
+import android.content.Intent;
|
|
|
+import android.content.pm.ActivityInfo;
|
|
|
+import android.content.res.Configuration;
|
|
|
+import android.net.Uri;
|
|
|
+import android.os.Build;
|
|
|
+import android.os.Bundle;
|
|
|
+import android.text.TextUtils;
|
|
|
+import android.view.View;
|
|
|
+import android.webkit.GeolocationPermissions;
|
|
|
+import android.webkit.ValueCallback;
|
|
|
+import android.webkit.WebChromeClient;
|
|
|
+import android.webkit.WebSettings;
|
|
|
+import android.webkit.WebView;
|
|
|
+import android.widget.FrameLayout;
|
|
|
+
|
|
|
+import androidx.annotation.NonNull;
|
|
|
+import androidx.annotation.Nullable;
|
|
|
+
|
|
|
+import com.alibaba.android.arouter.facade.annotation.Route;
|
|
|
+import com.cooleshow.base.BuildConfig;
|
|
|
+import com.cooleshow.base.common.WebConstants;
|
|
|
+import com.cooleshow.base.router.RouterPath;
|
|
|
+import com.cooleshow.base.ui.activity.BaseActivity;
|
|
|
+import com.cooleshow.base.utils.LogUtils;
|
|
|
+import com.cooleshow.base.utils.PermissionUtils;
|
|
|
+import com.cooleshow.base.utils.UriUtils;
|
|
|
+import com.cooleshow.base.utils.Utils;
|
|
|
+import com.cooleshow.base.utils.helper.QMUIStatusBarHelper;
|
|
|
+import com.cooleshow.base.utils.helper.upload.UploadHelper;
|
|
|
+import com.cooleshow.base.widgets.LollipopFixedWebView;
|
|
|
+import com.cooleshow.base.widgets.WebClient;
|
|
|
+import com.cooleshow.base.widgets.dialog.CommonDialog;
|
|
|
+import com.cooleshow.student.R;
|
|
|
+import com.cooleshow.student.databinding.ActivityHtmlBinding;
|
|
|
+import com.cooleshow.student.widgets.helper.JsInterfaceHelper;
|
|
|
+import com.cooleshow.usercenter.helper.UserHelper;
|
|
|
+import com.daya.live_teaching.utils.GlideEngine;
|
|
|
+import com.luck.picture.lib.PictureSelector;
|
|
|
+import com.luck.picture.lib.config.PictureConfig;
|
|
|
+import com.luck.picture.lib.config.PictureMimeType;
|
|
|
+import com.luck.picture.lib.entity.LocalMedia;
|
|
|
+import com.luck.picture.lib.tools.PictureFileUtils;
|
|
|
+import com.tbruyelle.rxpermissions3.RxPermissions;
|
|
|
+
|
|
|
+import org.json.JSONObject;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Author by pq, Date on 2022/4/24.
|
|
|
+ */
|
|
|
+@Route(path = RouterPath.WebCenter.ACTIVITY_HTML)
|
|
|
+public class WebActivity extends BaseActivity<ActivityHtmlBinding> implements JsInterfaceHelper.OnJsMethodCallListener, View.OnClickListener {
|
|
|
+ private static final int REQUEST_CODE_FILE_CHOOSER = 500;
|
|
|
+ private WebView webView;
|
|
|
+ private String url;
|
|
|
+ private JsInterfaceHelper mInterfaceUtils;
|
|
|
+ private WebClient mWebClient;
|
|
|
+ private ValueCallback mUploadCallbackAboveL;
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
|
|
|
+ super.onCreate(savedInstanceState);
|
|
|
+ QMUIStatusBarHelper.setStatusBarLightMode(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ @NonNull
|
|
|
+ @Override
|
|
|
+ protected ActivityHtmlBinding getLayoutView() {
|
|
|
+ return ActivityHtmlBinding.inflate(getLayoutInflater());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void initView() {
|
|
|
+ Utils.setHeadView(viewBinding.statusBarView, this, 0);
|
|
|
+ viewBinding.btnClose.setOnClickListener(this);
|
|
|
+ viewBinding.btnBack.setOnClickListener(this);
|
|
|
+ try {
|
|
|
+ if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT < 23) {
|
|
|
+ webView = new LollipopFixedWebView(this);
|
|
|
+ } else {
|
|
|
+ webView = new WebView(this);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ if (null == webView) {
|
|
|
+ finish();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ url = getIntent().getStringExtra(WEB_URL);
|
|
|
+ if (TextUtils.isEmpty(url)) {
|
|
|
+ finish();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ viewBinding.viewParent.addView(webView, new FrameLayout.LayoutParams(
|
|
|
+ FrameLayout.LayoutParams.MATCH_PARENT,
|
|
|
+ FrameLayout.LayoutParams.MATCH_PARENT));
|
|
|
+ initWebView();
|
|
|
+ mInterfaceUtils = new JsInterfaceHelper(WebActivity.this);
|
|
|
+ mInterfaceUtils.setOnJsCallListener(this);
|
|
|
+ webView.addJavascriptInterface(mInterfaceUtils, WebConstants.WEB_JS_INTERFACE);
|
|
|
+ mWebClient = new WebClient();
|
|
|
+ webView.setWebViewClient(mWebClient);
|
|
|
+ webView.setWebChromeClient(new MyWebChromeClient());
|
|
|
+ loadUrl();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void loadUrl() {
|
|
|
+ String userToken = UserHelper.getUserToken();
|
|
|
+ mWebClient.setAuthorization(userToken);
|
|
|
+ boolean status = url.contains("?");
|
|
|
+ if (status) {
|
|
|
+ url = (url + "&Authorization=" + userToken);
|
|
|
+ } else {
|
|
|
+ url = (url + "?Authorization=" + userToken);
|
|
|
+ }
|
|
|
+ webView.loadUrl(url);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void initData() {
|
|
|
+ super.initData();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void initWebView() {
|
|
|
+ //声明WebSettings子类
|
|
|
+ WebSettings webSettings = webView.getSettings();
|
|
|
+ webSettings.setUserAgentString(webSettings.getUserAgentString() + WebConstants.WEB_UA_PARAMS);
|
|
|
+ webSettings.setGeolocationDatabasePath(getApplicationContext().getFilesDir().getPath());
|
|
|
+ webSettings.setGeolocationEnabled(true);
|
|
|
+ webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
|
|
|
+ //如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
|
|
|
+ webSettings.setJavaScriptEnabled(true);
|
|
|
+ webSettings.setMediaPlaybackRequiresUserGesture(false);//false允许自动播放音视频
|
|
|
+ //是否启用缓存
|
|
|
+ webSettings.setAppCacheEnabled(true);
|
|
|
+
|
|
|
+ // 开启DOM缓存,默认状态下是不支持LocalStorage的
|
|
|
+ webSettings.setDomStorageEnabled(true);
|
|
|
+ // 开启数据库缓存
|
|
|
+ webSettings.setDatabaseEnabled(true);
|
|
|
+ // 地址跨域导致视频预览图片加载不出来 无法播放:
|
|
|
+ webSettings.setAllowUniversalAccessFromFileURLs(false);
|
|
|
+ webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
|
|
|
+
|
|
|
+ //设置自适应屏幕,两者合用
|
|
|
+ webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
|
|
|
+ webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小
|
|
|
+ //缩放操作
|
|
|
+ webSettings.setSupportZoom(false); //支持缩放,默认为true。是下面那个的前提。
|
|
|
+ // 设置允许JS弹窗
|
|
|
+ webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
|
|
|
+ //其他细节操作
|
|
|
+ webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); //关闭webview中缓存
|
|
|
+ webSettings.setAllowFileAccess(true); //设置可以访问文件
|
|
|
+ webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
|
|
|
+ webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
|
|
|
+ webSettings.setDefaultTextEncodingName("UTF-8");//设置编码格式
|
|
|
+
|
|
|
+ webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); //富文本适配
|
|
|
+ webSettings.setAppCacheMaxSize(Long.MAX_VALUE);
|
|
|
+ webSettings.setAppCachePath(this.getDir("appcache", 0).getPath());
|
|
|
+ webSettings.setDatabasePath(this.getDir("databases", 0).getPath());
|
|
|
+ webSettings.setGeolocationDatabasePath(this.getDir("geolocation", 0)
|
|
|
+ .getPath());
|
|
|
+ webSettings.setPluginState(WebSettings.PluginState.ON_DEMAND);
|
|
|
+ if (BuildConfig.DEBUG) {
|
|
|
+ webView.setWebContentsDebuggingEnabled(true);
|
|
|
+ }
|
|
|
+ webSettings.setTextZoom(100);//设置字体默认的缩放比例,以避免手机系统的字体修改对页面字体及布局造成影响。
|
|
|
+ webView.setHorizontalScrollBarEnabled(false);
|
|
|
+ webView.setVerticalScrollBarEnabled(false);
|
|
|
+ webView.setDownloadListener((url, userAgent, contentDisposition, mimetype, contentLength) -> {
|
|
|
+// downloadFile(url);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 状态栏控制
|
|
|
+ *
|
|
|
+ * @param message
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void setBarStatus(JSONObject message) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 返回按钮
|
|
|
+ *
|
|
|
+ * @param message
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void backIconChange(JSONObject message) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void chooseFile(JSONObject message) {
|
|
|
+ JSONObject content = (JSONObject) message.opt("content");
|
|
|
+ String type = (String) content.opt("image/*");
|
|
|
+ String[] types = new String[]{type};
|
|
|
+ showFileChooser();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取状态栏高度
|
|
|
+ *
|
|
|
+ * @param message
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void getNavHeight(JSONObject message) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onDestroy() {
|
|
|
+ super.onDestroy();
|
|
|
+ if (mInterfaceUtils != null) {
|
|
|
+ mInterfaceUtils.release();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ if (v.getId() == R.id.btn_back) {
|
|
|
+ onBackPressed();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (v.getId() == R.id.btn_close) {
|
|
|
+ finish();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private class MyWebChromeClient extends WebChromeClient {
|
|
|
+ public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
|
|
|
+ callback.invoke(origin, true, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onProgressChanged(WebView view, int newProgress) {
|
|
|
+ LogUtils.e(newProgress + "");
|
|
|
+ if (newProgress == 100 && null != viewBinding.progressBar) {
|
|
|
+ viewBinding.progressBar.setVisibility(View.GONE);//加载完网页进度条消失
|
|
|
+ } else {
|
|
|
+ if (null != viewBinding.progressBar) {
|
|
|
+ viewBinding.progressBar.setVisibility(View.VISIBLE);//开始加载网页时显示进度条
|
|
|
+ viewBinding.progressBar.setProgress(newProgress);//设置进度值
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onReceivedTitle(WebView view, String title) {
|
|
|
+ super.onReceivedTitle(view, title);
|
|
|
+ if (!TextUtils.isEmpty(title)) {
|
|
|
+ viewBinding.tvTitle.setText(title);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // Android > 5.0.1
|
|
|
+ @Override
|
|
|
+ public boolean onShowFileChooser(
|
|
|
+ WebView webView, ValueCallback<Uri[]> filePathCallback,
|
|
|
+ FileChooserParams fileChooserParams) {
|
|
|
+ LogUtils.i("pq", "fileChooserParams" + fileChooserParams.toString());
|
|
|
+ if (fileChooserParams.getAcceptTypes().length == 1 && fileChooserParams.getAcceptTypes()[0].equals("image/*")) {
|
|
|
+ mUploadCallbackAboveL = filePathCallback;
|
|
|
+ startPictureSelect();
|
|
|
+ } else {
|
|
|
+ mUploadCallbackAboveL = filePathCallback;
|
|
|
+ startFileSelect(fileChooserParams);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private CustomViewCallback mCustomViewCallback;
|
|
|
+ // 横屏时,显示视频的view
|
|
|
+ private View mCustomView;
|
|
|
+
|
|
|
+ // 点击全屏按钮时,调用的方法
|
|
|
+ @Override
|
|
|
+ public void onShowCustomView(View view, CustomViewCallback callback) {
|
|
|
+ super.onShowCustomView(view, callback);
|
|
|
+
|
|
|
+ //如果view 已经存在,则隐藏
|
|
|
+ if (mCustomView != null) {
|
|
|
+ callback.onCustomViewHidden();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ mCustomView = view;
|
|
|
+ mCustomView.setVisibility(View.VISIBLE);
|
|
|
+ mCustomViewCallback = callback;
|
|
|
+ viewBinding.flVideo.addView(mCustomView);
|
|
|
+ viewBinding.flVideo.setVisibility(View.VISIBLE);
|
|
|
+// mLayout.bringToFront();
|
|
|
+ viewBinding.headerBarView.setVisibility(View.GONE);
|
|
|
+ //设置横屏
|
|
|
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 取消全屏调用的方法
|
|
|
+ @Override
|
|
|
+ public void onHideCustomView() {
|
|
|
+ super.onHideCustomView();
|
|
|
+ if (mCustomView == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ mCustomView.setVisibility(View.GONE);
|
|
|
+ viewBinding.flVideo.removeView(mCustomView);
|
|
|
+ mCustomView = null;
|
|
|
+ viewBinding.flVideo.setVisibility(View.GONE);
|
|
|
+ try {
|
|
|
+ mCustomViewCallback.onCustomViewHidden();
|
|
|
+ } catch (Exception e) {
|
|
|
+
|
|
|
+ }
|
|
|
+ viewBinding.headerBarView.setVisibility(View.VISIBLE);
|
|
|
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onConfigurationChanged(@NonNull Configuration newConfig) {
|
|
|
+ super.onConfigurationChanged(newConfig);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void showFileChooser() {
|
|
|
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
|
|
+ intent.setType("*/*");
|
|
|
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
|
+ intent.putExtra(Intent.EXTRA_TITLE, "File Chooser");
|
|
|
+ intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
|
|
|
+ startActivityForResult(intent, REQUEST_CODE_FILE_CHOOSER);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void startFileSelect(WebChromeClient.FileChooserParams fileChooserParams) {
|
|
|
+ new RxPermissions(this)
|
|
|
+ .request(Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
|
+ .subscribe(permission -> {
|
|
|
+ if (permission) {
|
|
|
+ showFileChooser();
|
|
|
+ } else {
|
|
|
+ String tip = "上传文件需要储存卡读取权限,是否去设置?";
|
|
|
+ showCommonTipDialog(tip);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private void startPictureSelect() {
|
|
|
+ new RxPermissions(this)
|
|
|
+ .request(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
|
+ .subscribe(permission -> {
|
|
|
+ if (permission) {
|
|
|
+ PictureSelector.create(this)
|
|
|
+ .openGallery(PictureMimeType.ofImage())//全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()
|
|
|
+ .loadImageEngine(GlideEngine.createGlideEngine())
|
|
|
+ .theme(com.cooleshow.base.R.style.picture_daya_style)// 主题样式设置 具体参考 values/styles 用法:R .style.picture.white.style
|
|
|
+ .selectionMode(PictureConfig.SINGLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE
|
|
|
+ .enableCrop(false)// 是否裁剪 true or false
|
|
|
+ .showCropGrid(false)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false
|
|
|
+ .compress(true)// 是否压缩 true or false
|
|
|
+ .circleDimmedLayer(false)// 是否圆形裁剪 true or false
|
|
|
+ .forResult(PictureConfig.CHOOSE_REQUEST);
|
|
|
+ } else {
|
|
|
+ String tip = "上传照片需要相机权限,是否去设置?";
|
|
|
+ showCommonTipDialog(tip);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private void showCommonTipDialog(String tip) {
|
|
|
+ CommonDialog dialog = new CommonDialog(this);
|
|
|
+ dialog.show();
|
|
|
+ dialog.setTitle("提示");
|
|
|
+ dialog.setContent(tip);
|
|
|
+ dialog.setOnCancelClickListener(view1 -> {
|
|
|
+ dialog.dismiss();
|
|
|
+ });
|
|
|
+
|
|
|
+ dialog.setOnConfirmClickListener(view1 -> {
|
|
|
+ PermissionUtils.toSelfSetting(this);
|
|
|
+ dialog.dismiss();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
|
|
+ super.onActivityResult(requestCode, resultCode, data);
|
|
|
+ LogUtils.i("pq", "requestCode" + requestCode);
|
|
|
+ LogUtils.i("pq", "resultCode" + resultCode);
|
|
|
+ if (requestCode == PictureConfig.CHOOSE_REQUEST && mUploadCallbackAboveL != null) {
|
|
|
+ // 图片、视频、音频选择结果回调
|
|
|
+ List<LocalMedia> selectList = PictureSelector.obtainMultipleResult(data);
|
|
|
+ String avatar = selectList.get(0).getCompressPath();
|
|
|
+
|
|
|
+ if (avatar != null) {
|
|
|
+ mUploadCallbackAboveL.onReceiveValue(new Uri[]{PictureFileUtils.parUri(getApplicationContext(), new File(avatar))});
|
|
|
+ } else {
|
|
|
+ mUploadCallbackAboveL.onReceiveValue(new Uri[]{});
|
|
|
+ }
|
|
|
+ mUploadCallbackAboveL = null;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (requestCode == REQUEST_CODE_FILE_CHOOSER) {
|
|
|
+ Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
|
|
|
+ if (result != null) {
|
|
|
+ File file = UriUtils.uri2File(result);
|
|
|
+ if (file != null && file.exists()) {
|
|
|
+ UploadHelper uploadHelper = new UploadHelper(WebActivity.this);
|
|
|
+ uploadHelper.uploadFile(file);
|
|
|
+// if (f.exists() && f.isFile()) {
|
|
|
+// Uri newUri = Uri.fromFile(f);
|
|
|
+// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
|
+// if (mUploadCallbackAboveL != null) {
|
|
|
+// if (newUri != null) {
|
|
|
+// mUploadCallbackAboveL.onReceiveValue(new Uri[]{newUri});
|
|
|
+// mUploadCallbackAboveL = null;
|
|
|
+// return;
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// } else {
|
|
|
+// ToastUtil.getInstance().show(WebActivity.this, "文件损坏或不存在,请重新选择");
|
|
|
+// }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ clearUploadMessage();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * webview没有选择文件也要传null,防止下次无法执行
|
|
|
+ */
|
|
|
+ private void clearUploadMessage() {
|
|
|
+ if (mUploadCallbackAboveL != null) {
|
|
|
+ mUploadCallbackAboveL.onReceiveValue(null);
|
|
|
+ mUploadCallbackAboveL = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|