智齿客服H5聊天链接接入及WebView不支持input file文件上传解决

接入智齿客服网页端流程:

主要问题就是Android webview 屏蔽了上传文件功能,本文附带解决了WebView 不支持<input type=file>文件上传,WebView 点击没有反应的问题;

  智齿客服网页端接入有两种部署方式。1、网页组件;2、聊天链接。本文档不涉及业务流程,只讲述开发接入过程;

  今天主要说一下Android 、ios 对 聊天链接 这种方式的接入,第一种接入方式后期再做描述。

 1、 先注册智齿客服,然后用超级管理员账号登陆后到“设置-支持渠道”获取部署代码;

    例:获取聊天链接如下:

https://www.sobot.com/chat/pc/index.html?sysNum=a047ca3c8fec47cca963d4a6e27b8706

 2、这是智齿客服官方提供的链接开发文档:智齿客服官方文档,文档最后列出了聊天链接可以拼接的参数,可根据需要自行配置,值得注意的是customerFields 字段,是智齿客服提供的允许自定义的字段,登入智齿客服官网 到“设置-自定义字段” 中设置你所需要的字段。

例如新建字段名称为“游戏”,点击“显示ID”,查看自定义字段所对应的参数。最后将自定义字段拼接成json字符串,拼接到链接后面。如下:

拼接链接如下:https://www.sobot.com/chat/pc/index.html?sysNum=a047ca3c8fec47cca963d4a6e27b8706&customerFileds={"customField1":"麻将","customField2":"北京"}

3通过Android或IOS , webview 加载此链接。说明:ios 不需要做任何更改,直接加载链接就可以使用智齿客服网页版的聊天链接了。Android直接加载无法上传图片和拍照。


4、Android 上传图片和拍照问题解决

 由于安全因素android webview屏蔽了文件上传控件,但是他并没有完全封掉。

 解决方法步骤如下:

   (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;

   

    (2)、 扩展WebChromeClient

 webView.setWebChromeClient(mWebChromeClient);


 protected WebChromeClient mWebChromeClient = new WebChromeClient() {
        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
            if (basetitle != null && !TextUtils.isEmpty(title)) {
                basetitle.setText(title);
            } else {
                basetitle.setText(" ");
            }
        }

        // For Android 4.1 - 5.0
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> valueCallback, FileChooserParams fileChooserParams) {
            uploadMessageAboveL = valueCallback;
            uploadPicture();
            return true;
        }

        // For Android >= 5.1
        @Override
        public void openFileChooser(ValueCallback<Uri> valueCallback, String s, String s1) {
            //super.openFileChooser(valueCallback, s, s1);
            uploadMessage = valueCallback;
            uploadPicture();
        }
    };

      (3)、解决选择文件后按钮失效问题,需要覆写onActivityResult方法

    @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;
                }

                //上传文件

                if (uploadMessage != null) {
                    uploadMessage.onReceiveValue(imageUri);
                    uploadMessage = null;
                }
                if (uploadMessageAboveL != null) {
                    uploadMessageAboveL.onReceiveValue(new Uri[]{imageUri});
                    uploadMessageAboveL = null;
                }
            }
        }
    }

    (4)、以上是主要功能点,下面是我自己用到的一个完整文件,可以参考,里面内容部分多余的请自动忽略。

public class BannerWebActivity extends BaseActivity implements View.OnClickListener {

    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 int type;
    private WebView webView;
    private ProgressBar pbProcess;
    private String weburl;
    private ImageView basetitleleftim;
    private TextView basetitle;
    private ValueCallback<Uri[]> uploadMessageAboveL;
    private ValueCallback<Uri> uploadMessage;
    private String mLastPhotoPath;
    private Thread mThread;
    Context mContext;
    private String mCurrentPhotoPath;

    @Override
    public void initView() {
        mContext = getApplicationContext();
        basetitleleftim = getViewID(R.id.basetitle_leftim);
        webView = getViewID(R.id.webview);
        pbProcess = getViewID(R.id.pb_process);
        basetitle = getViewID(R.id.basetitle_title);
        Intent intent = getIntent();
        weburl = intent.getStringExtra("weburl");
        type = intent.getIntExtra("type", 0);
        basetitleleftim.setOnClickListener(this);
        if (type == 1000) {
            OkHttpUtils.getInstance().getToken(this, AgencyUrl.ReadStrategyUrl, 1, BaseDiabean.class);
        }
    }

    @Override
    public void initData() throws Exception {

        WebSettings settings = webView.getSettings();
        /* 大部分网页需要自己保存一些数据,这个时候就的设置下面这个属性 */
        settings.setDomStorageEnabled(true);
        settings.setDatabaseEnabled(true);
        /* 设置缓存模式,我这里使用的默认,不做多讲解 */
        settings.setCacheMode(WebSettings.LOAD_DEFAULT);
        /* 设置支持Js,必须设置的,不然网页基本上不能看 */
        settings.setJavaScriptEnabled(true);
        settings.setAppCacheEnabled(true);
        settings.setAppCachePath(context.getCacheDir().getAbsolutePath());
        /* 设置为使用webview推荐的窗口 */
        settings.setUseWideViewPort(true);
        settings.setLoadWithOverviewMode(true);
        /* 设置是否允许webview使用缩放的功能,我这里设为false,不允许 */
        settings.setBuiltInZoomControls(false);
        /* webview 不显示图片兼容 */
        if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            settings.setMixedContentMode(android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }

        webView.setWebChromeClient(mWebChromeClient);
        webView.setWebViewClient(mWebViewClient);
        webView.setDownloadListener(new DownloadListener() {
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.addCategory(Intent.CATEGORY_BROWSABLE);
                intent.setData(Uri.parse(url));
                startActivity(intent);
            }
        });
        webView.setHorizontalScrollBarEnabled(false);
        webView.loadUrl(weburl);
    }

    protected WebViewClient mWebViewClient = new WebViewClient() {
        public boolean shouldOverrideUrlLoading(WebView view, String url) { // 重写此方法表明点击网页里面的链接不调用系统浏览器,而是在本WebView中显示
            view.loadUrl(url);//加载需要显示的网页
            return true;
            // return super.shouldOverrideUrlLoading(view, url);
        }
    };

    protected WebChromeClient mWebChromeClient = new WebChromeClient() {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            //  super.onProgressChanged(view, newProgress);
            pbProcess.setProgress(newProgress);
            if (newProgress >= 100) {
                pbProcess.setVisibility(View.GONE);
            } else {
                pbProcess.setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
            if (basetitle != null && !TextUtils.isEmpty(title)) {
                basetitle.setText(title);
            } else {
                basetitle.setText(" ");
            }
        }

        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> valueCallback, FileChooserParams fileChooserParams) {
            uploadMessageAboveL = valueCallback;
            uploadPicture();
            return true;
        }

        @Override
        public void openFileChooser(ValueCallback<Uri> valueCallback, String s, String s1) {
            uploadMessage = valueCallback;
            uploadPicture();
        }
    };

    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            takePhoto();
        }
    };

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (grantResults == null && grantResults.length == 0) {
            return;
        }

        if (requestCode == REQUEST_CODE_PERMISSION_CAMERA) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                takePhoto();
            } else {
                new AlertDialog.Builder(mContext)
                        .setTitle("无法拍照")
                        .setMessage("您未授予拍照权限")
                        .setNegativeButton("取消", null)
                        .setPositiveButton("去设置", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Intent localIntent = new Intent();
                                localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                                localIntent.setData(Uri.fromParts("package", getPackageName(), null));
                                startActivity(localIntent);
                            }
                        }).create().show();
            }
        }
    }

    /**
     * 选择相机或者相册
     */
    public void uploadPicture() {
        AlertDialog.Builder builder = new AlertDialog.Builder(BannerWebActivity.this);
        builder.setTitle("请选择图片上传方式");
        builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                if (uploadMessage != null) {
                    uploadMessage.onReceiveValue(null);
                    uploadMessage = null;
                }
                if (uploadMessageAboveL != null) {
                    uploadMessageAboveL.onReceiveValue(null);
                    uploadMessageAboveL = null;
                }
            }
        });

        //相机
        builder.setPositiveButton("相机", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (!TextUtils.isEmpty(mLastPhotoPath)) {
                    mThread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            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) {
                        takePhoto();
                    } else {
                        ActivityCompat.requestPermissions(BannerWebActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_PERMISSION_CAMERA);
                    }
                }
            }
        });

        builder.setNegativeButton("相册", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                chooseAlbumPic();
            }
        });
        builder.create().show();

    }

    /**
     * 拍照
     */
    private void takePhoto() {
        StringBuilder fileName = new StringBuilder();
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        fileName.append(UUID.randomUUID()).append("_upload.png");
        File tempFile = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES), fileName.toString());
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri uri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".fileProvider", tempFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        } else {
            Uri uri = Uri.fromFile(tempFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        }

        mCurrentPhotoPath = tempFile.getAbsolutePath();
        startActivityForResult(intent, REQUEST_CODE_CAMERA);

    }


    /**
     * 选择相册照片
     */
    private void chooseAlbumPic() {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("image/*");
        startActivityForResult(Intent.createChooser(i, "Image Chooser"), REQUEST_CODE_ALBUM);
    }

    /*
     * 回调
     *
     * */

    @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;
                }

                //上传文件

                if (uploadMessage != null) {
                    uploadMessage.onReceiveValue(imageUri);
                    uploadMessage = null;
                }
                if (uploadMessageAboveL != null) {
                    uploadMessageAboveL.onReceiveValue(new Uri[]{imageUri});
                    uploadMessageAboveL = null;
                }

            }

        }
    }

    @Override
    public int setViewLayout() {
        return R.layout.activity_banner_web;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.basetitle_leftim:
                if (webView != null && webView.canGoBack()) {
                    webView.goBack();
                } else {
                    fishActivity(this);
                }
                break;
            default:
                break;
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (webView != null && webView.canGoBack()) {
            webView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void onSuccessResponse(Call call, RBResponse resultBean, int requestCode) throws IOException {
        if (requestCode == 1) {
            BaseDiabean baseDiabean = (BaseDiabean) resultBean;
            if (baseDiabean != null) {
                if (baseDiabean.getCode() != 200) {
                    ToastUtils.showShort(this, baseDiabean.getMessage(), 1);
                }
            } else {
                ToastUtils.showShort(this, "出错了", 1);
            }
        }
    }

    @Override
    public void onFailResponse(Call call, IOException e, int requestCode) {

    }

    @Override
    protected void onDestroy() {
        if (webView != null) {
            webView.setWebChromeClient(null);
            webView.setWebViewClient(null);
            webView.destroy();
            webView = null;
        }
        super.onDestroy();
    }
}

5、智齿客服聊天链接接入完毕。总结一下,主要要处理的一个问题就是Android webview 屏蔽了文件上传。解决了这个问题也就完全解决了,说明一下,选择拍照或者相册的弹窗,可以自己根据需要自己重新写一下UI样式。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值