Udesk接入需求---Android嵌入Udesk即时通讯网页插件(二实现发送照片,录屏,发送文件)
Posted 怀化纱厂球迷
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Udesk接入需求---Android嵌入Udesk即时通讯网页插件(二实现发送照片,录屏,发送文件)相关的知识,希望对你有一定的参考价值。
这是19年当时的一个需求,这是第一步,接入方式,但是最后我接入的方式,由于公司是付费用户,所有选择的是 webview嵌套H5网页,具体网页是Udesk公司提供的,本次来说下客服同学给测试同学说的一个bug,经过查看,发现是后续对方公司开放的新功能,但是网上搜了一圈,没找到解决办法,也看了Udesk的github-demo,也没找到解决办法,最后联系他们技术支持,给了我答案,这里我需要重新添加代码,这里详细记录下,免得大家以后也遇到同样问题
点击+号,弹出 录像 拍照 档案 按钮,点击需要触发对应的功能,此页面是H5页面
关键回调以及判断方法:
onShowFileChooser
注意事项点:
1.重写一个 UdeskWebChromeClient 继承 WebChromeClient
2.针对 回调 onShowFileChooser 方法增加判断
String[] type = fileChooserParams.getAcceptTypes();
if (("image/*").equals(type[0])) //拍照
setPhoto();
else if ("*/*".equals(type[0])) //档案
setFile();
else if ("video/*".equals(type[0])) //视频
setVideo();
3.拍照或者视频或者档案选择后的结果回调 onActivityResult
这里我把代码贴出来
package com.addcn.android.house591.ui.top;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ClipData;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebStorage;
import android.webkit.WebView;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import com.addcn.android.house591.util.UserPermissionsUtil;
import java.io.File;
public class UdeskWebChromeClient extends WebChromeClient
private Activity mContext;
private ValueCallback<Uri> uploadMessage;
private ValueCallback<Uri[]> uploadMessageAboveL;
private final static int FILE_CHOOSER_RESULT_CODE = 10000;
ICloseWindow closeWindow = null;
private String mFileName;
private File mCurrentPhotoFile; // 相机拍照图片
private File PHOTO_DIR = null; // 拍照片存储位置
// 默认下载图片
public static String downPathImageDir = File.separator + "download"
+ File.separator + "cache_images" + File.separator;
private final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 10001;
private final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 10002;
private Uri photoUri;
private Uri videoUri;
public UdeskWebChromeClient(Activity context, ICloseWindow closeWindow)
mContext = context;
this.closeWindow = closeWindow;
@Override
public void onProgressChanged(WebView view, int newProgress)
super.onProgressChanged(view, newProgress);
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> valueCallback)
uploadMessage = valueCallback;
setFile();
// For Android >= 3.0
public void openFileChooser(ValueCallback valueCallback, String acceptType)
uploadMessage = valueCallback;
if (("image/*").equals(acceptType)) //拍照
setPhoto();
else if ("*/*".equals(acceptType)) //档案
setFile();
else if ("video/*".equals(acceptType)) //视频
setVideo();
//For Android >= 4.1
public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture)
uploadMessage = valueCallback;
if (("image/*").equals(acceptType)) //拍照
setPhoto();
else if ("*/*".equals(acceptType)) //档案
setFile();
else if ("video/*".equals(acceptType)) //视频
setVideo();
// For Android >= 5.0
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
uploadMessageAboveL = filePathCallback;
String[] type = fileChooserParams.getAcceptTypes();
if (("image/*").equals(type[0])) //拍照
setPhoto();
else if ("*/*".equals(type[0])) //档案
setFile();
else if ("video/*".equals(type[0])) //视频
setVideo();
return true;
/**
* 圖片路徑初始
*/
private void initImageDir()
// 初始化图片保存路径
String photoDir = getDefaultImageDownPathDir();
if (photoDir == null || photoDir.trim().length() == 0)
// 存储卡不存在
else
PHOTO_DIR = new File(photoDir);
/**
* 默认图片保存全路径.
*/
public static String getDefaultImageDownPathDir()
String pathDir = null;
try
if (!isCanUseSD())
return null;
// 初始化图片保存路径
File fileRoot = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File dirFile = new File(fileRoot.getAbsolutePath()
+ downPathImageDir);
if (!dirFile.exists())
dirFile.mkdirs();
pathDir = dirFile.getPath();
catch (Exception e)
return pathDir;
/**
* SD卡是否能用.
*
* @return true 可用,false不可用
*/
public static boolean isCanUseSD()
try
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
catch (Exception e)
return false;
/**
* 从照相机获取
*/
private void selectImageFromCamera()
String status = Environment.getExternalStorageState();
// 判断是否有SD卡,如果有sd卡存入sd卡在说,没有sd卡直接转换为图片
if (status.equals(Environment.MEDIA_MOUNTED))
doTakePhoto();
/**
* 拍照获取图片
*/
protected void doTakePhoto()
try
mFileName = System.currentTimeMillis() + ".jpg";
mCurrentPhotoFile = new File(PHOTO_DIR, mFileName);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, null);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri uri = FileProvider.getUriForFile(mContext, "com.addcn.android.house591.fileprovider", mCurrentPhotoFile);
photoUri = uri;
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
mContext.startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
catch (Exception e)
// 未找到系统相机程序
//窗口关闭事件,默认处理关闭activty界面,可以通过ICloseWindow 回到处理对应的逻辑
@Override
public void onCloseWindow(WebView window)
if (closeWindow != null)
closeWindow.closeActivty();
super.onCloseWindow(window);
@Override
//扩容
public void onReachedMaxAppCacheSize(long requiredStorage, long quota, WebStorage.QuotaUpdater quotaUpdater)
quotaUpdater.updateQuota(requiredStorage * 2);
@Override
public void onConsoleMessage(String message, int lineNumber, String sourceID)
Log.e("h5端的log", String.format("%s -- From line %s of %s", message, lineNumber, sourceID));
private void setFile()
Intent i = createFileItent();
mContext.startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE);
private void setVideo()
if (Build.VERSION.SDK_INT >= 23)
// 如果是6.0以上的系统,先申请权限
if (ContextCompat
.checkSelfPermission(
mContext,
UserPermissionsUtil.ARRAY_PERMISSION[UserPermissionsUtil.CODE_CAMERA]) != PackageManager.PERMISSION_GRANTED)
// 判断是否需要向用户解释一下该权限
UserPermissionsUtil.requestUserPermissions(
mContext,
UserPermissionsUtil.CODE_CAMERA);
else
getPhotography();
else
getPhotography();
private void setPhoto()
// 初始化图片保存路径
initImageDir();
if (Build.VERSION.SDK_INT >= 23)
// 如果是6.0以上的系统,先申请权限
if (ContextCompat
.checkSelfPermission(
mContext,
UserPermissionsUtil.ARRAY_PERMISSION[UserPermissionsUtil.CODE_CAMERA]) != PackageManager.PERMISSION_GRANTED)
// 判断是否需要向用户解释一下该权限
UserPermissionsUtil.requestUserPermissions(
mContext,
UserPermissionsUtil.CODE_CAMERA);
else
// 如果权限已经申请成功过了
selectImageFromCamera();
else
selectImageFromCamera();
public void getPhotography()
//调用系统相机
//
// Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); // 表示跳转至相机的录视频界面
// intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // MediaStore.EXTRA_VIDEO_QUALITY 表示录制视频的质量,从 0-1,越大表示质量越好,同时视频也越大
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); // 表示录制完后保存的录制,如果不写,则会保存到默认的路径,在onActivityResult()的回调,通过intent.getData中返回保存的路径
// intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 60 * 10); // 设置视频录制的最长时间
// mContext.startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE); // 跳转
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
File file = FileUtil.getOutputVideoMediaFile(mContext);
Uri uri = FileUtil.getOutputMediaFileUri(mContext,file);
videoUri=uri;
if (Build.VERSION.SDK_INT >= 24)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.addCategory(Intent.CATEGORY_DEFAULT);
mContext.startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
/**
* 创建选择图库的intent
*
* @return
*/
private Intent createFileItent()
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
return intent;
public void onActivityResult(int requestCode, int resultCode, Intent data)
if (requestCode == FILE_CHOOSER_RESULT_CODE)
if (null == uploadMessage && null == uploadMessageAboveL)
return;
//上传文件 点取消需要如下设置。 否则再次点击上传文件没反应
if (data == null)
if (uploadMessage != null)
uploadMessage.onReceiveValue(null);
uploadMessage = null;
if (uploadMessageAboveL != null)
uploadMessageAboveL.onReceiveValue(null);
uploadMessageAboveL = null;
return;
if (uploadMessageAboveL != null) //5.0以上
onActivityResultAboveL(requestCode, resultCode, data);
else if (uploadMessage != null)
if (data != null && resultCode == Activity.RESULT_OK)
Uri result = data.getData();
Log.e("xxx", "5.0-result=" + result);
uploadMessage.onReceiveValue(result);
uploadMessage = null;
else if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE)
if (photoUri != null)
if (uploadMessageAboveL != null)
Uri[] results = new Uri[1];
results[0] = photoUri;
uploadMessageAboveL.onReceiveValue(results);
uploadMessageAboveL = null;
else if (uploadMessage != null)
uploadMessage.onReceiveValue(photoUri);
uploadMessage = null;
else if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE)
if (videoUri != null)
if (uploadMessageAboveL != null)
Uri[] results =new Uri[1];
results[0] = videoUri;
uploadMessageAboveL.onReceiveValue(results);
uploadMessageAboveL = null;
else if (uploadMessage != null)
uploadMessage.onReceiveValue(videoUri);
uploadMessage = null;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent)
Log.e("xxx", "5.0+ 返回了");
if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null)
return;
Uri[] results = null;
if (resultCode == Activity.RESULT_OK)
if (intent != null)
String dataString = intent.getDataString();
ClipData clipData = intent.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);
uploadMessageAboveL.onReceiveValue(results);
uploadMessageAboveL = null;
以上是关于Udesk接入需求---Android嵌入Udesk即时通讯网页插件(二实现发送照片,录屏,发送文件)的主要内容,如果未能解决你的问题,请参考以下文章
Udesk接入需求---Android嵌入Udesk即时通讯网页插件(二实现发送照片,录屏,发送文件)
Udesk肖立鹏:利用商业智能反哺产品,强力激活B端客户需求