Android使用webview加载网页,解决上传文件适配3.0、4.0、5.0手机存在的问题。

本文介绍如何解决WebView在不同Android版本上上传文件的问题,并提供了一种实现方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WebView加载网页,点击上传按钮没有反应。

最近有一个需求,就是用app封装一个网页。主要内容是有写前端的人员开发。我主要是添加几个主要的功能。点击网页时,发现点击网页上的上传按钮没有反应。后来发现WebView在上传文件这块需要适配Android版本。下面就是开发过程。
1.如何展示网页。那边给的是.jsp格式的网址。运用webview加载的时候,要设置缓存模式。
        Webview mWebView = (WebView) findViewById(R.id.wb);
        WebSettings settings = mWebView.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setLoadWithOverviewMode(true);
        settings.setUseWideViewPort(true);
	//设置缓存模式
        settings.setAppCacheEnabled(true);
	mWebView.loadUrl(url);
//返回true,响应网页的事件。返回false,拦截网页点击事件。

 	mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                System.out.println("url::" + url);
                Log.i("222", url);
                if (url.contains("你要拦截的url")) {
                 //这里进行拦截判断与否
                    return flag;                  
                } 
 	 return super.shouldOverrideUrlLoading(view, url);
}); }


上面的代码就可以正常的显示网页。
2.解决上传文件问题。
需要给WebView设置SetWebchromeClient(new PhotoWebChromeClient()),其中PhotoWebChromeClient集成自WebChromeClient。代码如下:

private class PhotoWebChromeClient extends WebChromeClient {
	//适配不同版本的手机,3.x-4.x的手机直接使用openFileChooser(uploadMsg, "");该方法就可以了,

        // For Android 3.0+
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
            if (mUploadMessage != null) return;
            mUploadMessage = uploadMsg;
            selectImage();
        }

        // For Android < 3.0
        public void openFileChooser(ValueCallback<Uri> uploadMsg) {
            openFileChooser(uploadMsg, "");
        }

        // For Android  > 4.1.1
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
            openFileChooser(uploadMsg, acceptType);
        }
        //For Android  5.0   使用单独的方法进行解决。
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
            openFileChooserImplForAndroid5(filePathCallback);
            return true;
        }
    }

    private void openFileChooserImplForAndroid5(ValueCallback<Uri[]> uploadMsg) {
        mUploadCallbackAboveL = uploadMsg;
        selectImage();
    }


    /**
     * 检查SD卡是否存在
     *
     * @return
     */
    public final boolean checkSDcard() {
        boolean flag = Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED);
        if (!flag) {
            Toast.makeText(this, "请插入手机存储卡再使用本功能", Toast.LENGTH_SHORT).show();
        }
        return flag;
    }
//弹出选择对话框
    protected final void selectImage() {
        if (!checkSDcard())
            return;
        String[] selectPicTypeStr = {"相机", "相册"};
        new AlertDialog.Builder(this)
                .setCancelable(false)
                .setItems(selectPicTypeStr, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog,
                                        int which) {
                        switch (which) {
                            // 相机拍摄
                            case 0:
                                openCarcme();
                                break;
                            // 手机相册
                            case 1:
                                chosePic();
                                break;
                            default:
                                break;
                        }
			//选择之后要展示到网页上的名字
                        compressPath = Environment
                                .getExternalStorageDirectory()
                                .getPath()
                                + "/fuiou_wmp/temp";
                        new File(compressPath).mkdirs();
                        compressPath = compressPath + File.separator
                                +  (System.currentTimeMillis() + ".jpg");
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        reSet();
                    }
                }).show();
    }
//如果点击了取消,或做了其他无效操作。进行重置。解决返回到上传界面出现上传错误。
    private void reSet() {
        if (mUploadMessage != null) {
            mUploadMessage.onReceiveValue(null);
            mUploadMessage = null;
        }
        if (mUploadCallbackAboveL != null) {
            mUploadCallbackAboveL.onReceiveValue(null);
            mUploadCallbackAboveL = null;
        }
    }


    /**
     * 打开照相机
     */
    private void openCarcme() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        imagePaths = Environment.getExternalStorageDirectory().getPath()
                + "/fuiou_wmp/temp/"
                + (System.currentTimeMillis() + ".jpg");
        // 必须确保文件夹路径存在,否则拍照后无法完成回调
        File vFile = new File(imagePaths);
        if (!vFile.exists()) {
            File vDirPath = vFile.getParentFile();
            vDirPath.mkdirs();
        } else {
            if (vFile.exists()) {
                vFile.delete();
            }
        }
        cameraUri = Uri.fromFile(vFile);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
        startActivityForResult(intent, REQ_CAMERA);
    }

    /**
     * 拍照结束后
     */
    private void afterOpenCamera() {
        File f = new File(imagePaths);
        addImageGallery(f);
        File newFile = FileUtils.compressFile(f.getPath(), compressPath);
    }

    /**
     * 解决拍照后在相册中找不到的问题
     */
    private void addImageGallery(File file) {
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/*");
        getContentResolver().insert(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    }

    /**
     * 本地相册选择图片
     */
    private void chosePic() {
        FileUtils.delFile(compressPath);
        Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT"
        String IMAGE_UNSPECIFIED = "image/*";
        innerIntent.setType(IMAGE_UNSPECIFIED); // 查看类型
        Intent wrapperIntent = Intent.createChooser(innerIntent, null);
        startActivityForResult(wrapperIntent, REQ_CHOOSE);
    }

    /**
     * 选择照片后结束
     *
     * @param data
     */
    private Uri afterChosePic(Intent data) {

        // 获取图片的路径:
        String[] proj = {MediaStore.Images.Media.DATA};
        if (data == null) {
            reSet();
            return null;
        }
        // 好像是android多媒体数据库的封装接口,具体的看Android文档
        Cursor cursor = managedQuery(data.getData(), proj, null, null, null);
        if (cursor == null) {
            //Toast.makeText(this, "上传的图片仅支持png或jpg格式", Toast.LENGTH_SHORT).show();
            return null;
        }
        // 按我个人理解 这个是获得用户选择的图片的索引值
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        // 将光标移至开头 ,这个很重要,不小心很容易引起越界
        cursor.moveToFirst();
        // 最后根据索引值获取图片路径
        String path = cursor.getString(column_index);
        //path != null && (path.endsWith(".png") || path.endsWith(".PNG") || path.endsWith(".jpg") || path.endsWith(".JPG"))
        if (path != null) {
            File newFile = FileUtils.compressFile(path, compressPath);
            return Uri.fromFile(newFile);
        } else {
            //Toast.makeText(this, "未选中图片或选择图片格式不正确", Toast.LENGTH_SHORT).show();
        }
        return null;
    }


    /**
     * 返回到上传文件界面
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode,
                                    Intent intent) {
	//如果点击了选中按钮。
        if (resultCode == Activity.RESULT_OK) {
            if (null == mUploadMessage && null == mUploadCallbackAboveL)
                return;
            if (null != mUploadMessage) {
                Uri uri = null;
                if (requestCode == REQ_CAMERA) {
                    afterOpenCamera();
                    uri = cameraUri;
                } else if (requestCode == REQ_CHOOSE) {
                    uri = afterChosePic(intent);
                }
                mUploadMessage.onReceiveValue(uri);
                mUploadMessage = null;
            } else {
                Uri result = null;
                if (requestCode == REQ_CAMERA) {
                    afterOpenCamera();
                    result = cameraUri;
                } else if (requestCode == REQ_CHOOSE) {
                    result = afterChosePic(intent);
                }
                if (result != null) {
                    mUploadCallbackAboveL.onReceiveValue(new Uri[]{result});
                } else {
                    mUploadCallbackAboveL.onReceiveValue(new Uri[]{});
                }
                mUploadCallbackAboveL = null;
            }
        } else {
		//如果没有点击选中。
reSet(); } super.onActivityResult(requestCode, resultCode, intent); }


添加了上述代码之后上传文件就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值