Android - WebView接入H5客服&照片/视频上传

webView加载H5,主要是解决上传图片和视频的问题。

1)Activity定义一些常量变量

	private static final int REQUEST_CODE_PERMISSION_CAMERA = 0x03;
    private static final int REQUEST_CODE_CAMERA = 0x02;
    private static final int REQUEST_CODE_ALBUM = 0x01;
    private ValueCallback<Uri[]> uploadMessageAboveL;
    private ValueCallback<Uri> uploadMessage;
    private String mLastPhotoPath,mCurrentPhotoPath;
    private Thread mThread;

2)WebChromeClient、WebViewClient

除了实现onProgressChanged、onShowFileChooser方法外,自定义多个openFileChooser以兼容不同版本。不同版本的api调用不同的方法。

protected WebChromeClient webChromeClient = new WebChromeClient() {
    
    
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
    
    
        	//关闭加载中
            if (newProgress >= 100) {
    
    
                dismissCustomDialog();
            }
        }

        /**
         * API >= 21(Android 5.0.1)回调此方法
         */
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> valueCallback, FileChooserParams fileChooserParams) {
    
    
            uploadMessageAboveL = valueCallback;
            uploadPicture();
            return true;
        }

        /**
         * 8(Android 2.2) <= API <= 10(Android 2.3)回调此方法
         */
        private void openFileChooser(ValueCallback<Uri> uploadMsg) {
    
    
            uploadMessage = uploadMsg;
            uploadPicture();
        }

        /**
         * 11(Android 3.0) <= API <= 15(Android 4.0.3)回调此方法
         */
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
    
    
            openFileChooser(uploadMsg);
        }

        /**
         * 16(Android 4.1.2) <= API <= 20(Android 4.4W.2)回调此方法
         */
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
    
    
            openFileChooser(uploadMsg);
        }

    };
protected WebViewClient webViewClient = new WebViewClient() {
    
    
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
    
    
            //让一般的http和https协议开头的走正常的页面,而其他的URL则会开启一个Acitity然后去调用原生APP应用
            if (url.startsWith("http") || url.startsWith("https")) {
    
    
                return super.shouldInterceptRequest(view, url);
            } else {
    
    
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(intent);
                return null;
            }
        }
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
    
     // 表明点击网页里面的链接不调用系统浏览器,而是在本WebView中显示
            view.loadUrl(url);//加载需要显示的网页
            return true;
        }

        @Override
        public void onPageFinished(WebView view, String url) {
    
    //页面完成加载
            super.onPageFinished(view, url);
            if (webView != null && webView.getProgress() >= 100) {
    
    
                dismissCustomDialog();
            }
        }
    };

3)上传照片/视频的方法

先让用户选择相机/相册

1. 选择相机

第一次选择相机先判断相机和录音权限,然后选择拍照或录像。不是第一次选择不做权限判断。

	@SuppressLint("HandlerLeak")
    Handler mHandler = new Handler() {
    
    
        @Override
        public void handleMessage(Message msg) {
    
    
            super.handleMessage(msg);
            takePhoto();
        }
    };
    
	/**
     * 选择相机或者相册
     */
    public void uploadPicture() {
    
    
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("请选择上传方式");
        builder.setOnCancelListener(dialog -> {
    
    
        	//解决按钮失效问题
            if (uploadMessage != null) {
    
    
                uploadMessage.onReceiveValue(null);
                uploadMessage = null;
            }
            if (uploadMessageAboveL != null) {
    
    
                uploadMessageAboveL.onReceiveValue(null);
                uploadMessageAboveL = null;
            }
        });

        //相机
        builder.setPositiveButton("相机", (dialog, which) -> {
    
    
            if (!TextUtils.isEmpty(mLastPhotoPath)) {
    
    
                mThread = new Thread(() -> {
    
    
                    File file = new File(mLastPhotoPath);
                    if (file != null) {
    
    
                        file.delete();
                    }
                    mHandler.sendEmptyMessage(1);
                });
                mThread.start();
            } else {
    
    
                if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED &&
                        ActivityCompat.checkSelfPermission(mContext, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
    
    
                    takePhoto();
                } else {
    
    
                    ActivityCompat.requestPermissions(ServiceWebViewActivity.this, new String[]{
    
    Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, REQUEST_CODE_PERMISSION_CAMERA);
                }
            }
        });

        builder.setNegativeButton("相册", (dialog, which) -> chooseAlbumPic());
        builder.create().show();
    }

    /**
     * 拍照/录像
     */
    private void takePhoto() {
    
    
        AlertDialog.Builder cameraTypeDialog = new AlertDialog.Builder(this);
        cameraTypeDialog.setTitle("请选择拍照或录像");
        cameraTypeDialog.setOnCancelListener(dialog -> {
    
    
            if (uploadMessage != null) {
    
    
                uploadMessage.onReceiveValue(null);
                uploadMessage = null;
            }
            if (uploadMessageAboveL != null) {
    
    
                uploadMessageAboveL.onReceiveValue(null);
                uploadMessageAboveL = null;
            }
        });

        cameraTypeDialog.setNegativeButton("拍照", (dialog, which) -> {
    
    
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            StringBuilder fileName = new StringBuilder();
            fileName.append(UUID.randomUUID()).append("_upload.png");
            cameraType(intent, fileName);
        });

        cameraTypeDialog.setPositiveButton("录像", (dialog, which) -> {
    
    
            Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
            StringBuilder fileName = new StringBuilder();
//            intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 30);//视频时长
            intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);//视频质量
//            intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT,10 *1024*1024L);//限制录制大小(10M=10 * 1024 * 1024L)
            fileName.append(UUID.randomUUID()).append("_video.mp4");
            cameraType(intent, fileName);
        });

        cameraTypeDialog.create().show();
    }

    private void cameraType(Intent intent, StringBuilder fileName) {
    
    
        File tempFile = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES), fileName.toString());
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
    
    
            if (!tempFile.getParentFile().exists()) {
    
    
                tempFile.getParentFile().mkdirs();
            }
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(this.getApplicationContext(), this.getPackageName() + ".provider", tempFile));
        } else {
    
    
            Uri uri = Uri.fromFile(tempFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        }
        mCurrentPhotoPath = tempFile.getAbsolutePath();
        startActivityForResult(intent, REQUEST_CODE_CAMERA);
    }
2. 选择相册

图片&视频

    private void chooseAlbumPic() {
    
    
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("video/*;image/*");
        startActivityForResult(Intent.createChooser(i, "File Chooser"),
                REQUEST_CODE_ALBUM);
    }
3. 回调

获取文件Uri

	@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
    
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_ALBUM || requestCode == REQUEST_CODE_CAMERA) {
    
    
            if (uploadMessage == null && uploadMessageAboveL == null) {
    
    
                return;
            }
            //取消拍照或者取消选择相册
            if (resultCode != RESULT_OK) {
    
    
                if (uploadMessage != null) {
    
    
                    uploadMessage.onReceiveValue(null);
                    uploadMessage = null;
                }
                if (uploadMessageAboveL != null) {
    
    
                    uploadMessageAboveL.onReceiveValue(null);
                    uploadMessageAboveL = null;
                }
            }
            //拍照成功或选择照片
            if (resultCode == RESULT_OK) {
    
    
                Uri imageUri = null;
                switch (requestCode) {
    
    
                    case REQUEST_CODE_ALBUM:
                        if (data != null) {
    
    
                            imageUri = data.getData();
                        }
                        break;
                    case REQUEST_CODE_CAMERA:
                        if (!TextUtils.isEmpty(mCurrentPhotoPath)) {
    
    
                            File file = new File(mCurrentPhotoPath);
                            Uri loadUri = Uri.fromFile(file);
                            Intent localIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, loadUri);
                            sendBroadcast(localIntent);
                            imageUri = Uri.fromFile(file);
                            mLastPhotoPath = mCurrentPhotoPath;
                        }
                        break;
                    default:;
                }

                //上传文件
                if (uploadMessage != null) {
    
    
                    uploadMessage.onReceiveValue(imageUri);
                    uploadMessage = null;
                }
                if (uploadMessageAboveL != null) {
    
    
                    uploadMessageAboveL.onReceiveValue(new Uri[]{
    
    imageUri});
                    uploadMessageAboveL = null;
                }
            }
        }
    }

4)WebView基础设置

	@SuppressLint("JavascriptInterface")
    private void initView(String entrance) {
    
    
        showCustomDialog();
        viewBack.setOnClickListener(v -> finish());
        webView.setWebChromeClient(webChromeClient);
        webView.setWebViewClient(webViewClient);
        //监听下载
        webView.setDownloadListener((url, userAgent, contentDisposition, mimeType, contentLength) -> {
    
    
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.addCategory(Intent.CATEGORY_BROWSABLE);
            intent.setData(Uri.parse(url));
            startActivity(intent);
        });

        WebSettings settings = webView.getSettings();
        // 网页保存一些数据
        settings.setDomStorageEnabled(true);
        settings.setDatabaseEnabled(true);
        // 设置缓存模式
        settings.setCacheMode(WebSettings.LOAD_DEFAULT);
        // 设置支持Js
        settings.setJavaScriptEnabled(true);
        settings.setAppCacheEnabled(true);
        settings.setAppCachePath(this.getCacheDir().getAbsolutePath());
        // 设置为使用webview推荐的窗口
        settings.setUseWideViewPort(true);// 支持HTML的“viewport”标签或者使用wide viewport
        settings.setLoadWithOverviewMode(true);
        // 允许访问文件
        settings.setAllowFileAccess(true);
        // 设置是否允许webview使用缩放的功能,不允许
        settings.setBuiltInZoomControls(false);
        //        settings.setDefaultTextEncodingName("GBK");//设置解码格式
		//        settings.setSupportZoom(true); // 支持缩放
        // webview 不显示图片兼容
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
    
    
            settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        webView.setHorizontalScrollBarEnabled(false);

        String url = "http://xxxx.html?username="+entrance;
        webView.loadUrl(url);
    }
    
    @Override
    protected void onDestroy() {
    
    
        if (webView != null) {
    
    
            webView.setWebChromeClient(null);
            webView.setWebViewClient(null);
            webView.destroy();
            webView = null;
        }
        super.onDestroy();
    }
    
	@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    
    
        if (webView != null && webView.canGoBack()) {
    
    
            webView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

参考:
https://blog.csdn.net/xxlyzgt/article/details/95638998
https://www.jianshu.com/p/29ef4a5d77a5
https://blog.csdn.net/zwq1457/article/details/8350057

猜你喜欢

转载自blog.csdn.net/czssltt/article/details/124291643