android WebView調起攝像頭並上傳(兼容7.0以上)、返回重定向等等問題。

 

本博文主要解決問題以及功能:
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);
    }
}

 

發佈了19 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章