Android 内嵌 webView 与H5交互的问题和总结

来源:互联网 发布:如何用vb编写上位机 编辑:程序博客网 时间:2024/05/21 21:41

先实现效果android 内嵌WebView 与H5 交互;

先webView 的WebViewClient 中重写 shouldOverrideUrlLoading 方法 通过拦截Url(拦截的协议需要跟H5协调 方式:< a href="xxxx "></ a> 注:xxxx是定义的拦截标识),实现 调用Android 原生拍照或者相册,  然后把获取的图片转成Base64 传给H5 ,H5 在调用头像裁剪的方法 上传到服务器;核核心代码:

        webView.setWebViewClient(new WebViewClient() {

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                // TODO Auto-generated method stub
                super.onPageStarted(view, url, favicon);

                //输出要加载路径

                Log.e("sss", url);
            
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String scheme) {

                 //同样的道理在jsp 页面中 < a href="xxxx "></ a> 拦截下来做指定的跳转

                // 判断url链接中是否含有某个字段,如果有就执行指定的跳转(不执行跳转url链接),如果没有就加载url链接
                String url = AppUtile.spiltURL(scheme);
                if (url.contains("native")) {
                    String[] spilte = url.split("-", 3);
                    if (spilte[1].equals("cancel")) {
                        finish();
                    }
                } else {
                
                    if (scheme.contains("tel:")) {   //拦截打电话
                        String[] stel = scheme.split("tel:");
                        call(context, stel[1]);
                        return true;

                    }
                    if (scheme.contains("img")) {// 拦截拍照
                        selectImage();
                        return true;
                    }
                    if (scheme.contains("https://mclient.alipay.com/cashier/mobilepay.htm")) {//支付宝支付
                        Intent intent = new Intent(context,H5PayDemoActivity.class);
                        Bundle extras = new Bundle();
                        String urlsss =scheme;
                        extras.putString("url", urlsss);
                        intent.putExtras(extras);
                        context.startActivity(intent);
                        return true;
                        
                    }
                    if(scheme.startsWith("alipays:") || scheme.startsWith("alipay")) {
                            try {
                             context.startActivity(new Intent("android.intent.action.VIEW", Uri.parse(scheme)));
                            } catch (Exception e) {
                             new AlertDialog.Builder(context)
                             .setMessage("未检测到支付宝客户端,请安装后重试。")
                             .setPositiveButton("立即安装", new DialogInterface.OnClickListener() {
                        
                              @Override
                              public void onClick(DialogInterface dialog, int which) {
                               Uri alipayUrl = Uri.parse("https://d.alipay.com");
                               context.startActivity(new Intent("android.intent.action.VIEW", alipayUrl));
                              }
                             }).setNegativeButton("取消", null).show();
                            }
                            return true;
                    }

                    //重定向URL

                    if (scheme.contains("?")) {
                        view.loadUrl(scheme + "&appType=FAFA_SOFT_3D&source=FAFA_SOFT_3D_ANDROID");
                    } else {
                        view.loadUrl(scheme + "?appType=FAFA_SOFT_3D&source=FAFA_SOFT_3D_ANDROID");
                    }

                }
                return true;
            }
         关于shouldOverrideUrlLoading()方法的返回值问题,该方法的返回值有三种:

        1.返回true,即根据代码逻辑执行相应操作,webview不加载该url,返回true 表示拦截<a   /a>成功;

        2.返回false,除执行相应代码外,webview加载该url, false则失效;

        3.返回super.shouldOverrideUrlLoading(),点进父类中,我们可以看到,返回的还是false。


    //通过onActivityResult获取 照片的绝对路径

    @Override
    protected void onActivityResult(int requestCode, int resultCode,
            Intent intent) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, intent);

        if (requestCode == REQUEST_CODE_PICK_IMAGE) {// 拍照
            if (resultCode==Activity.RESULT_OK) {

                // PhotoBitmapUtils.amendRotatePhoto 解决个别手机拍完照片 角度旋转的问题

                String filepath = PhotoBitmapUtils.amendRotatePhoto(photoPath,
                        context);

                Bitmap mpBitmap = AppUtile.getSmallBitmap(filepath);
                Bitmap bitmap2 = AppUtile.ratio(mpBitmap, 1080, 1920);
                String base64ImageUrl = AppUtile.bitmapTo(bitmap2);
                if (webView != null) {
                    webView.loadUrl("javascript:setPhoto('"
                            + "data:image/jpeg;base64," + base64ImageUrl + "')");
                }
            }else{
                Toast.makeText(context, "取消操作", Toast.LENGTH_SHORT).show();
            }
        } else if (requestCode == FILECHOOSER_RESULTCODE) {
            // 相册
            if (resultCode==Activity.RESULT_OK) {
                String title = "";
                if (intent != null) {
                    String imgFile = RxPhotoTool.getImageAbsolutePath(context,
                            intent.getData());
                    String filepath = PhotoBitmapUtils.amendRotatePhoto(imgFile,
                            context);
                    if (imgFile.contains(".png")) {
                        title = "data:image/png;base64,";
                    } else if (imgFile.contains(".icon")) {
                        title = "data:image/icon;base64,";
                    } else if (imgFile.contains(".gif")) {
                        title = "data:image/gif;base64,";
                    } else if (imgFile.contains(".jpg")) {
                        title = "data:image/jpeg;base64,";
                    }

                    Bitmap mpBitmap = AppUtile.getSmallBitmap(filepath);
                    Bitmap bitmap2 = AppUtile.ratio(mpBitmap, 1080, 1920);
                    String base64ImageUrl = AppUtile.bitmapTo(bitmap2);

                    if (webView != null) {
                        webView.loadUrl("javascript:setPhoto('" + title
                                + base64ImageUrl + "')");
                    }
            }else{
                Toast.makeText(context, "图片格式错误", Toast.LENGTH_SHORT).show();
            }
            
            } else {
                Toast.makeText(context, "取消操作", Toast.LENGTH_SHORT).show();
            }

        } else {
            Toast.makeText(context, "取消操作", Toast.LENGTH_SHORT).show();
        }

    }

  网上有很多去H5 传值的例子 比如在高版本上重写onShowFileChooser

     通过 ValueCallback<Uri[]>  filePathCallback 这个回调对象
            @Override
           public boolean onShowFileChooser(WebView webView,
                                            ValueCallback<Uri[]> filePathCallback,
                                            WebChromeClient.FileChooserParams fileChooserParams) {
      }

  filePathCallback.onReceiveValue(results); 给Url传值参考链接如下:
     http://blog.csdn.net/gaoyongshuo/article/details/71425573 这种实现方式在个别手机上存在问题,还有在低版本上

    onShowFileChooser 没有这个方法

    所以用了另一种方法  webView.loadUrl("javascript:setPhoto('" +base64ImageUrl + "')");

   调用javascript 的一种方法给他们传一个String ,调用这种方法存在一种弊端,如果图片过大 转Base64 有限制,

    给H5   传不过去了,所以要进行对图片进行压缩;

    注:这里只提供解决问题的思路

    有问题请咨询QQ:1070398201



原创粉丝点击