本博文主要解決問題以及功能:
1、webview設置頁面標題爲網頁標題;
2、返回按鈕返回到上一個網頁功能;
3、解決返回重定向;
4、鏈接中<input type = 'file' >無法調起攝像頭問題;
5、下載無響應問題。
第一,設置webview:
mContentTetView.getSettings().setJavaScriptEnabled(true);
mContentTetView.getSettings().setDomStorageEnabled(true);
mContentTetView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
mContentTetView.getSettings().setDatabaseEnabled(false);
mContentTetView.getSettings().setAppCacheEnabled(false);
mContentTetView.setWebChromeClient(webChromeClient);
mContentTetView.setDownloadListener(new MyWebViewDownLoadListener());//下載方法
mContentTetView.setInitialScale(68);
mContentTetView.getSettings().setDefaultTextEncodingName("UTF-8");
mContentTetView.setEnabled(true);
mContentTetView.getSettings().setAllowFileAccessFromFileURLs(true);
mContentTetView.getSettings().setAllowUniversalAccessFromFileURLs(true);
mContentTetView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
mContentTetView.setDrawingCacheEnabled(true);
mContentTetView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
mContentTetView.setAlwaysDrawnWithCacheEnabled(true);
mContentTetView.getSettings().setSupportZoom(true);
mContentTetView.getSettings().setBuiltInZoomControls(true);
mContentTetView.getSettings().setUseWideViewPort(true);
mContentTetView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
mContentTetView.getSettings().setLoadWithOverviewMode(true);
mContentTetView.getSettings().setSupportZoom(true);
第二,返回到上一個網頁而不是退出WebView的方法:
//第一種,監聽系統返回按鈕
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (KeyEvent.KEYCODE_BACK == keyCode && mContentTetView.canGoBack()) { //監聽到返回鍵被按下,並且當前網頁可被返回
if (mContentTetView.getUrl().equals(content)) { //獲取當前的網址,與初始網址界面是否相同
finish(); //相同表示爲第一次進入的網址,上一級爲源生
} else {
mContentTetView.goBack(); //返回到網頁的上一級
return true; //返回true,交於系統處理
}
}
return super.onKeyDown(keyCode, event);
}
//第二種,自己寫的返回按鈕功能
findViewById(R.id.leftButton).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (mContentTetView.canGoBack()) {
if (mContentTetView.getUrl().equals(content)) {
finish();
} else {
mContentTetView.goBack();
}
} else {
finish();
}
}
});
第三,解決返回重定向問題:
mContentTetView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
WebView.HitTestResult hitTestResult = view.getHitTestResult();
if (hitTestResult == null) {//hitTestResult==null解決重定向問題
view.loadUrl(url);
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public void onPageFinished(WebView view, String url) {
//獲取頭文字
String title = view.getTitle();
if (isContainChinese(title)) {//中文時實時設置頁面標題
tv_title.setText(title);
}
}
});
public static boolean isContainChinese(String str) {
Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
Matcher m = p.matcher(str.substring(0, 1));
if (m.find()) {
return true;
}
return false;
}
第四,解決調起攝像頭問題:
private static final String TAG = "WebviewTAG:";
private final static int VIDEO_REQUEST = 0x11;
private final static int PHOTO_REQUEST = 0x22;
private ValueCallback<Uri> uploadFile;//定義接受返回值
private ValueCallback<Uri[]> uploadFiles;
private Uri imageUri;
private WebChromeClient webChromeClient = new WebChromeClient() {
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
if (isContainChinese(title)) {
tv_title.setText(title);
}
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void onPermissionRequest(PermissionRequest request) {
request.grant(request.getResources());
}
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
uploadFile = uploadMsg;
openCamera(acceptType);
}
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsgs) {
uploadFile = uploadMsgs;
}
// For Android > 4.1.1
// @Override
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
uploadFile = uploadMsg;
openCamera(acceptType);
}
// For Android >= 5.0
@Override
@SuppressLint("NewApi")
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
uploadFiles = filePathCallback;
String[] acceptTypes = fileChooserParams.getAcceptTypes();
for (int i = 0; i < acceptTypes.length; i++) {
LogUtil.e("接收到的類型爲:" + acceptTypes[i]);
if (acceptTypes[i].equals("")) {//如果前端代碼中沒有指定類型,默認爲拍照
openCamera("image/*");
} else {
openCamera(acceptTypes[i]);
}
}
return true;
}
private void openCamera(String accept) {
LogUtil.i("accept : " + accept);
if (accept.contains("image")) {// image/*
String filePath = Environment.getExternalStorageDirectory() + File.separator
+ Environment.DIRECTORY_PICTURES + File.separator;
String fileName = "IMG_" + DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
//文件的下載目錄爲:/Pictures/
File fileUri = new File(filePath + fileName);
imageUri = Uri.fromFile(fileUri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//此處兼容7.0系統以上
imageUri = FileProvider.getUriForFile(getActivity(), "com.***.***" + ".fileprovider", fileUri);//通過FileProvider創建一個content類型的Uri
//這裏有問題的,參考FileProvider的使用方法。
}
PhotoUtils.takePicture(getActivity(), imageUri, PHOTO_REQUEST);
} else if (accept.contains("video")) {// video/*
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
// set the video file name
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0.5);
//限制時長
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 5);
//開啓攝像機
startActivityForResult(intent, VIDEO_REQUEST);
}
}
};
public class PhotoUtils {
/**
* @param activity 當前activity
* @param imageUri 拍照後照片存儲路徑
* @param requestCode 調用系統相機請求碼
*/
public static void takePicture(Activity activity, Uri imageUri, int requestCode) {
//調用系統相機
Intent intentCamera = new Intent();
if (Build.VERSION.SDK_INT >= 16) {
intentCamera.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加這一句表示對目標應用臨時授權該Uri所代表的文件
}
intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
//將拍照結果保存至photo_file的Uri中,不保留在相冊中
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
if (activity != null) {
activity.startActivityForResult(intentCamera, requestCode);
}
}
}
//回調方法
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
LogUtil.i("onActivityResult" + requestCode);
switch (requestCode) {
case VIDEO_REQUEST:
if (null != uploadFile) {
Uri result = data == null || resultCode != Activity.RESULT_OK ? null : data.getData();
uploadFile.onReceiveValue(result);
uploadFile = null;
}
if (null != uploadFiles) {
Uri result = data == null || resultCode != Activity.RESULT_OK ? null : data.getData();
uploadFiles.onReceiveValue(new Uri[]{result});
uploadFiles = null;
}
break;
case PHOTO_REQUEST:
LogUtil.i(TAG, "PHOTO_REQUEST");
if (null == uploadFile && null == uploadFiles) return;
Uri result = data == null || resultCode != Activity.RESULT_OK ? null : data.getData();
if (uploadFiles != null) {
onActivityResultAboveL(requestCode, resultCode, data);
} else if (uploadFile != null) {
uploadFile.onReceiveValue(result);
uploadFile = null;
}
break;
default:
break;
}
} else if (resultCode == Activity.RESULT_CANCELED) {
if (null != uploadFile) {
uploadFile.onReceiveValue(null);
uploadFile = null;
}
if (null != uploadFiles) {
uploadFiles.onReceiveValue(null);
uploadFiles = null;
}
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent data) {
if (requestCode != PHOTO_REQUEST || uploadFiles == null) {
return;
}
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
if (data == null) {
results = new Uri[]{imageUri};
} else {
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)};
}
}
uploadFiles.onReceiveValue(results);
uploadFiles = null;
}
第五,解決下載方法,
//webview是沒有下載方法的,所以將下載的鏈接丟給系統瀏覽器處理,當然也可以前後端對應,寫異步下載方法。
private class MyWebViewDownLoadListener implements DownloadListener {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
}