0
点赞
收藏
分享

微信扫一扫

webview

小安子啊 2022-01-15 阅读 67

public class WebViewActivity extends Activity implements JSCallback {

    private LinearLayout mWebViewRoot;
    private WebView mWebView;
    private RelativeLayout mWVHeadArea;
    private ImageView mBackBtn;
    private TextView mTitleTV;
    private TextView mCloseIV;
    private ProgressBar mProgressBar;
    private RelativeLayout mLoadError;
    private TextView mRetryBtn;

    private String mTitle;
    private boolean isShowTitle = true;
    public String mLoadUrl = "";
    private int mCurProgressTime = 0;
    private Handler mHandler;
    private Runnable progressRunnable;
    public boolean isFreshedTitle = false;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.srt_webview_activity);
        ARouter.getInstance().inject(this);

        initView();
        initWebSettings();
        initWebViewClient();
        initWebChromeClient();
        addJSMethod();
        initData();

        startLoadUrl();
    }

    private void startLoadUrl() {
        if (TextUtils.isEmpty(this.mLoadUrl)) {
            Toast(R.string.srt_wv_request_no_data);
            finish();

        } else {
            initTitle();
            setFirstLoadUrl(this.mLoadUrl);
            if (isNetworkAvailable()) {
                loadPage(mLoadUrl);
                setFirstLoadUrl("");
            } else {
                showErrorVisibility(true);
                setLoadingProgress(15);
            }
        }
    }

    private void showErrorVisibility(boolean isShow) {
        mLoadError.setVisibility(isShow ? View.VISIBLE : View.GONE);
        mWebViewRoot.setVisibility(!isShow ? View.VISIBLE : View.GONE);
    }

    public void hideLoadingProgress() {
        this.mProgressBar.setVisibility(View.INVISIBLE);
    }

    public void showClose() {
        mCloseIV.setVisibility(View.VISIBLE);

    }

    public void showLoadingProgress() {
        this.mProgressBar.setVisibility(View.VISIBLE);
    }


    protected void loadPage(String url) {

        Log.d("---webview---", "url = " + url);
        try {
            WebUtils.checkFileAccess(mWebView.getSettings(), url);
            this.mWebView.loadUrl(url);

        } catch (Exception var3) {
            Log.e("WebView", var3);
        }
    }

    private void initTitle() {
        if (this.isShowTitle) {
            this.mWVHeadArea.setVisibility(View.VISIBLE);
            if (!TextUtils.isEmpty(this.mTitle)) {
                mTitleTV.setText(mTitle);
            }
        } else {
            this.mWVHeadArea.setVisibility(View.GONE);
        }

    }

    private void setWVTitle(String title) {
        if (this.isShowTitle && !TextUtils.isEmpty(title)) {
            String[] titles = title.split(":");
            String titleTxt = title;
            if (titles.length > 0) {
                titleTxt = titles[0];
            }
            mTitleTV.setText(titleTxt);
        }

    }


    private void initView() {
        mWebViewRoot = findViewById(R.id.wv_container);
        mWebView = findViewById(R.id.forum_context);
        mWVHeadArea = findViewById(R.id.wv_header_area);

        mBackBtn = findViewById(R.id.wv_btn_back);
        mTitleTV = findViewById(R.id.wv_title);
        mCloseIV = findViewById(R.id.wv_btn_close);
        mProgressBar = findViewById(R.id.webview_progressbar);

        mLoadError = findViewById(R.id.wv_layout_load_error);
        mRetryBtn = findViewById(R.id.btn_wv_retry);

        showErrorVisibility(false);

        mBackBtn.setOnClickListener(v -> {
            if (mWebView.canGoBack()) {
                mWebView.goBack();
                showClose();
            } else {
                finish();
            }
        });
        mCloseIV.setOnClickListener(v -> {
            finish();
        });
        mRetryBtn.setOnClickListener(v -> {
            refreshWebView();
        });


    }

    private void initData() {

        MAX_SIGN_COUNT = 30;
        mHandler = new ProgressHandler(this);
        progressRunnable = new ProgressRunnable();

        Intent intent = this.getIntent();
        if (null == intent) {
            return;
        }
        mTitle = intent.getStringExtra("activityName");
        mLoadUrl = intent.getStringExtra("url");
        isShowTitle = intent.getBooleanExtra("isShowTitle", true);
    }


    private void initWebSettings() {
        //声明WebSettings子类
        WebSettings webSettings = mWebView.getSettings();
        //如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
        //设置自适应屏幕,两者合用
        webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
        webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小
        //缩放操作

        webSettings.setSupportZoom(false); //支持缩放,默认为true。是下面那个的前提。
        webSettings.setBuiltInZoomControls(false); //设置内置的缩放控件。若为false,则该WebView不可缩放
        webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件

        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); //关闭webview中缓存
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
        webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
        webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
        webSettings.setUserAgentString(getUserAgent());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        //TODO 安全漏洞,使用File,要禁止私用javaScript的
        webSettings.setAllowFileAccess(true); //设置可以访问文件
        webSettings.setSavePassword(false);
        webSettings.setDomStorageEnabled(true);


    }

    private static String getUserAgent() {
        /** user_agent **/
        String userAgent = new StringBuffer().append("Mozilla/5.0(Linux; U;XDSRT-APP;SNCLIENT; Android ").append(Build.VERSION.RELEASE).append("; ").append(Locale.getDefault().getLanguage()).append("; ").append(Build.MODEL).append(") AppleWebKit/533.0 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1").toString();
        return userAgent;
    }


    private void initWebViewClient() {
        mWebView.setWebViewClient(new WebViewClient() {

            //重写shouldOverrideUrlLoading()方法,使得打开网页时不调用系统浏览器, 而是在本WebView中显示
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                //使用WebView加载显示url
                WebUtils.checkFileAccess(mWebView.getSettings(), url);
                view.loadUrl(url);
                //返回true
                return true;
            }


            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                Log.e("sn_webview", "onPageStarted url==" + url);
                isFreshedTitle = false;
                //设定加载开始的操作
                showErrorVisibility(false);
                showLoadingProgress();
                startVirtualProgress();
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                //设定加载结束的操作
                pageFinished(view, url);
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                //TODO 方便验证
//                showErrorVisibility(true);
                Log.e(TAG, "onReceivedError==");
            }

            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                Log.e(TAG, "onReceivedSslError==");
                if (isVerifySsl()) {
                    handler.cancel();
                } else {
                    handler.proceed();
                }
            }
        });
    }


    private void initWebChromeClient() {
        mWebView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                //获得网页的加载进度并显示
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                //当前webview正在加载的页面的title
                if (!TextUtils.isEmpty(title)) {
                    setWVTitle(title);
                    isFreshedTitle = true;
                }
            }

            //Android < 5.0
            public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
                if (Log.logEnabled) {
                    Log.e("SNWebChromeClient", "openFileChooser 3 acceptType==" + acceptType);
                }

                openFileChooserImpl(uploadMsg);
            }
            //Android => 5.0
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> uploadMsg,
                                             WebChromeClient.FileChooserParams fileChooserParams) {
                onenFileChooseImpleForAndroid(uploadMsg);
                return true;
            }
        });
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode,Intent intent) {
        Uri result = (intent == null || resultCode != Activity.RESULT_OK) ? null: intent.getData();
        switch (requestCode){
            case FILE_CHOOSER_RESULT_CODE:  //android 5.0以下 选择图片回调
                if (null == mUploadMessage)
                    return;
                mUploadMessage.onReceiveValue(result);
                mUploadMessage = null;
                break;
            case FILE_CHOOSER_RESULT_CODE_FOR_ANDROID_5:  //android 5.0(含) 以上 选择图片回调
                if (null == mUploadMessageForAndroid5)
                    return;
                if (result != null) {
                    mUploadMessageForAndroid5.onReceiveValue(new Uri[]{result});
                } else {
                    mUploadMessageForAndroid5.onReceiveValue(new Uri[]{});
                }
                mUploadMessageForAndroid5 = null;
                break;
        }
    }

    private boolean hasPermission() {
        boolean hasPermission = true;
        if (Build.VERSION.SDK_INT >= 23) {
            if (ActivityCompat.checkSelfPermission(this, "android.permission.WRITE_EXTERNAL_STORAGE") == 0
                    && ActivityCompat.checkSelfPermission(this, "android.permission.CAMERA") == 0) {
                hasPermission = true;
            } else {
                hasPermission = false;
            }
        }

        return hasPermission;
    }


    private void openFileChooserImpl(ValueCallback<Uri> uploadMsg) {
        try {
            if (this.hasPermission()) {
                mUploadMessage = uploadMsg;
                Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                i.addCategory(Intent.CATEGORY_OPENABLE);
                i.setType("image/*");
                startActivityForResult(Intent.createChooser(i, "File Chooser"), FILE_CHOOSER_RESULT_CODE);

            } else if (ActivityCompat.checkSelfPermission(this, "android.permission.WRITE_EXTERNAL_STORAGE") != 0
                    && ActivityCompat.checkSelfPermission(this, "android.permission.CAMERA") != 0) {
                ActivityCompat.requestPermissions(this, new String[]{"android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.CAMERA"},
                        1001);
            } else if (ActivityCompat.checkSelfPermission(this, "android.permission.WRITE_EXTERNAL_STORAGE") != 0) {
                ActivityCompat.requestPermissions(this, new String[]{"android.permission.WRITE_EXTERNAL_STORAGE"},
                        1002);
            } else if (ActivityCompat.checkSelfPermission(this, "android.permission.CAMERA") != 0) {
                ActivityCompat.requestPermissions(this, new String[]{"android.permission.CAMERA"},
                        1003);
            }
        } catch (Exception var3) {
            Toaster.showMessage(this, "请打开相机或存储权限");
        }

    }
    /**
     * android 5.0(含) 以上开启图片选择(原生)
     * 可以自己改图片选择框架。
     */
    private void onenFileChooseImpleForAndroid(ValueCallback<Uri[]> filePathCallback) {

        try {
            if (this.hasPermission()) {
                mUploadMessageForAndroid5 = filePathCallback;
                Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
                contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
                contentSelectionIntent.setType("image/*");
                Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
                chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
                chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
                startActivityForResult(chooserIntent, FILE_CHOOSER_RESULT_CODE_FOR_ANDROID_5);

            } else if (ActivityCompat.checkSelfPermission(this, "android.permission.WRITE_EXTERNAL_STORAGE") != 0
                    && ActivityCompat.checkSelfPermission(this, "android.permission.CAMERA") != 0) {
                ActivityCompat.requestPermissions(this, new String[]{"android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.CAMERA"},
                        1001);
            } else if (ActivityCompat.checkSelfPermission(this, "android.permission.WRITE_EXTERNAL_STORAGE") != 0) {
                ActivityCompat.requestPermissions(this, new String[]{"android.permission.WRITE_EXTERNAL_STORAGE"},
                        1002);
            } else if (ActivityCompat.checkSelfPermission(this, "android.permission.CAMERA") != 0) {
                ActivityCompat.requestPermissions(this, new String[]{"android.permission.CAMERA"},
                        1003);
            }
        } catch (Exception var3) {
            Toaster.showMessage(this, "请打开相机或存储权限");
        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 1001) {
            if (grantResults.length == 2 && grantResults[0] == 0 && grantResults[1] == 0) {

            } else {
                this.clearValueCallBack();
                Toaster.showMessage(this, R.string.srt_permisson_camer_shoot);
            }
        } else if (requestCode == 1002) {
            if (grantResults.length == 1 && grantResults[0] == 0) {

            } else {
                this.clearValueCallBack();
                Toaster.showMessage(this, R.string.srt_permisson_storage_tip);
            }
        } else if (requestCode == 1003) {
            if (grantResults.length == 1 && grantResults[0] == 0) {

            } else {
                this.clearValueCallBack();
                Toaster.showMessage(this, R.string.srt_permisson_camer_tip);
            }
        }
    }

    public void clearValueCallBack() {
        if (this.mUploadMessage != null) {
            this.mUploadMessage.onReceiveValue(null);
            this.mUploadMessage = null;
        }

        if (this.mUploadMessageForAndroid5 != null) {
            this.mUploadMessageForAndroid5.onReceiveValue(null);
            this.mUploadMessageForAndroid5 = null;
        }

    }

    private void addJSMethod() {
        if (mWebView != null) {
            mWebView.removeJavascriptInterface("searchBoxJavaBridge_");
            mWebView.removeJavascriptInterface("accessibility");
            mWebView.removeJavascriptInterface("accessibilityTraversal");
        }

        if (null != mWebView) {
            mWebView.addJavascriptInterface(new JsBridge(this, this), "srtBridge");
        }
    }


    private void pageFinished(WebView view, String url) {
        Log.e("sn_webview", "onPageFinished url==" + url);
        if (!isFinishing()) {
            hideLoadingProgress();
            if (!isFreshedTitle) {
                String webTitle = this.mWebView.getTitle();
                if (webTitle == null || webTitle.toLowerCase().startsWith("http://") || webTitle.toLowerCase().startsWith("https://")) {
                    webTitle = "";
                }
                setWVTitle(webTitle);
            }
        }
    }

    private void startVirtualProgress() {
        this.mCurProgressTime = 0;
        this.removeProgressDelay();
        this.sendProgressDelay();
    }

    @Override
    public void toast(String message) {
        if (null == mWebView || isFinishing()) {
            return;
        }
        mWebView.post(() -> {
            Toaster.showMessage(WebViewActivity.this, message);
            mWebView.loadUrl("javascript:srtCallJs('toast', '1')");
        });
    }

    @Override
    public void checkSign() {
        checkSign(TASK_ID_ONE);
    }

    @Override
    public void callPhone(String phoneNum) {
        if (!TextUtils.isEmpty(phoneNum)) {
            Intent intent = new Intent(Intent.ACTION_DIAL);
            Uri data = Uri.parse("tel:" + phoneNum);
            intent.setData(data);
            startActivity(intent);
        }
    }

    @Override
    public void closeWeb() {
        finish();
    }

    @Override
    public void goToReceiveAgain(String purchaseNo) {
        Intent intent = new Intent(this, SrtTakeWebActivity.class);
        intent.putExtra("purchaseNo",purchaseNo);
        startActivity(intent);
    }

    @Override
    public void onSignNetResult(int taskId, NetResult result) {

        if (result == null) {
            return;
        }

        if (taskId == TASK_ID_ONE && result.isSuccess()) {
            if (!isFinishing() && mWebView != null) {
                mWebView.loadUrl("javascript:srtCallJs('checkSign', '0')");
            }
        }
    }

    private static class ProgressHandler extends Handler {
        WeakReference<WebViewActivity> mReference;

        ProgressHandler(WebViewActivity webViewActivity) {
            this.mReference = new WeakReference(webViewActivity);
        }

        public void handleMessage(Message msg) {
            WebViewActivity webViewActivity = this.mReference.get();
            if (webViewActivity != null) {
                webViewActivity.handleMessage(msg);
            }

        }
    }

    public void handleMessage(Message msg) {
        if (msg.what == 4353) {
            this.mCurProgressTime += 100;
            int pro = getVirtualProgress(this.mCurProgressTime);
            Log.i("sn_webview", "update virtual progress: " + pro);

            if (pro > 90) {
                removeProgressDelay();
                return;
            }

            this.sendProgressDelay();
        }
    }

    private void refreshWebView() {
        try {
            if (isNetworkAvailable()) {
                this.showErrorVisibility(false);
                if (getFirstLoadUrl() != null && !TextUtils.isEmpty(getFirstLoadUrl().trim())) {
                    this.mWebView.loadUrl(this.getFirstLoadUrl());
                    this.setFirstLoadUrl("");
                } else {
                    this.mWebView.reload();
                }
            } else {
                this.showErrorVisibility(true);
                this.setLoadingProgress(15);
            }
        } catch (Exception var2) {
            if (Log.logEnabled) {
                Log.e(var2.getMessage());
            }
        }

    }

    private void sendProgressDelay() {
        if (this.mHandler != null) {
            this.mHandler.postDelayed(progressRunnable, 100L);
        }

    }

    class ProgressRunnable implements Runnable {
        ProgressRunnable() {
        }

        public void run() {
            if (mHandler != null) {
                mHandler.sendEmptyMessage(4353);
            }

        }
    }

    private int getVirtualProgress(int time) {
        int progress;
        if (time >= 0 && time < 3000) {
            progress = 20 * time / 1000;
        } else if (time >= 3000 && time < 5000) {
            progress = 60 + 10 * (time - 3000) / 1000;
        } else if (time >= 5000 && time < 9000) {
            progress = 80 + 5 * (time - 5000) / 2000;
        } else {
            progress = 91;
        }

        return progress;
    }

    private void removeProgressDelay() {
        if (this.mHandler != null) {
            this.mHandler.removeCallbacks(this.progressRunnable);
        }

    }

    public void setLoadingProgress(int progress) {
        this.mProgressBar.setProgress(progress);
    }

    private boolean isVerifySsl() {
        return "prd".equals(Url.ENVIRONMENT);
    }


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) {
            mWebView.goBack();
            showClose();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (null != mWebView) {
            mWebView.onResume();
        }

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (null != mWebView) {
            mWebView.onPause();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (null != mHandler) {
            mHandler.removeCallbacks(null);
            mHandler = null;
        }
        try {
            if (null != mWebView) {
                if (this.mWebView.getSettings() != null) {
                    this.mWebView.getSettings().setJavaScriptEnabled(false);
                }
                this.mWebView.setVisibility(View.GONE);
                resetImageSetting(mWebView);
                mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
                mWebView.clearHistory();

                ViewGroup view = (ViewGroup) this.mWebView.getParent();
                view.removeAllViews();
                this.mWebView.removeAllViews();
                this.mWebView.destroy();
                this.mWebView = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void resetImageSetting(WebView webview) {
        try {
            WebSettings settings = webview.getSettings();
            if (!settings.getLoadsImagesAutomatically()) {
                settings.setLoadsImagesAutomatically(true);
            }

            if (settings.getBlockNetworkImage()) {
                settings.setBlockNetworkImage(false);
            }
        } catch (Exception var2) {
            if (Log.logEnabled) {
                Log.e("ConfigManager", "WebView had destroyed,forbid it's interfaces to be called");
            }
        }

    }

    public String getFirstLoadUrl() {
        return this.firstLoadUrl;
    }

    public void setFirstLoadUrl(String firstLoadUrl) {
        this.firstLoadUrl = firstLoadUrl;
    }

}

举报

相关推荐

0 条评论