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;
}
}