关键词:
这是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接入需求---1.初步接入 Udesk接入需求---1.初步接入这是19年当时的一个需求,这是第一步,接入方式,但是最后我接入的方式,由于公司是付费用户,所有选择的是webview嵌套H5网页,具体网页是Udesk公司... 查看详情
android接入腾讯云图形验证(代码片段)
Android接入腾讯云图形验证官方的文档有默认的方法:https://cloud.tencent.com/document/product/1110/49810但由于需求,需要定制的,这里使用的是web里面的方法3,官方没有demo,所以这里放出来给大家参考一下,也很... 查看详情
android如何接入穿山甲广告?(代码片段)
目录下载SDK集成SDKAndroidManifest配置provider配置运行环境配置白名单配置工具类下载SDK首先去穿山甲官网注册账号以及创建应用点击进入平台(我的是创建完账号并且登录之后是这个样子)进来之后是如下界面然后依次点击流量—>... 查看详情
如何让android平台像ipc一样实现gb28181前端设备接入
...数据的按需查看等操作。像执法记录仪等智能终端,跑在Android平台,对接GB28181平台的需求也非常大,网上相关demo也不少,但真正设计符合相关协议规范、功能完善、长时间稳定运行的并不多。基于此,我们研发了Android平台GB281... 查看详情
android平台gb28181接入端如何对接uvc摄像头?
我们在对接Android平台GB28181接入的时候,有公司提出这样的需求,除了采集执法记录仪摄像头自带的数据外,还想通过执法记录仪采集外接UVC摄像头。实际上,这块对我们来说有点炒冷饭了,不算新的诉求。大牛直播SDK... 查看详情
android平台gb28181接入端如何对接uvc摄像头?
我们在对接Android平台GB28181接入的时候,有公司提出这样的需求,除了采集执法记录仪摄像头自带的数据外,还想通过执法记录仪采集外接UVC摄像头。实际上,这块对我们来说有点炒冷饭了,不算新的诉求。大牛直播SDK在2016年对... 查看详情
利用nodemcu和mqtt协议让嵌入式设备接入互联网(一.layui前端框架)(代码片段)
...部身体样式表CSSlayui介绍源码前言为了让自己的嵌入设备接入互联网,而且能互相通讯,用直接的TCP或者UDP协议肯定是不够的,在了解了目前物联网行业后,发现物联网常用的协议是mqtt协议(messagequeuingtelemetry... 查看详情
text嵌入式软件开发人员需求表(代码片段)
android平台gb28181接入模块技术接入说明
技术背景今天,我们主要讲讲Android平台GB28181接入模块的技术对接,Android平台GB28181接入模块设计的目的,可实现不具备国标音视频能力的Android终端,通过平台注册接入到现有的GB/T28181—2016服务,可用于如智能监控、智慧零售、... 查看详情
嵌入式android系统增加新硬件支持
...ter显示,截至2021年4月全球移动操作系统中,谷歌Android占比高达72.2%,苹果IOS占比26.99%,其余移动操作系统占比之和低于1%。包含桌面操作系统在内的全球操作系统占比中,Android以40.66%位列第一位,Windows位... 查看详情
flutter插件开发之android高德地图(代码片段)
从零开发一个Android高德地图插件前言看过很多博客文章,发现很少提到关于实战中如何使用Android与Dart的混编交互,Flutter在实际项目中仍然需要大量运用到原生的一些功能,比如相机,地图,访问设备本地相... 查看详情
锐动视频编辑sdk接入说明
...频时不需要转码,减少用户等待时间。一、运行环境 Android4.1(api16)以上; 处理器:双核 1GHz以上CPU(目前只支持ARMCPU,X86、MIPS暂不支持);推荐四 查看详情
嵌入式嵌入式设备实现网络功能——综述
...线网络的实现1通过外接物理层(PHY)芯片的方式接入有线网络2通过外接以太网芯片前言随着物联网的推进,以及一些特殊应用场合下对网络功能的要求,网络功能在嵌入式设备中已经成为常客。对于大部分物联... 查看详情
哪个用于客户端应用程序的嵌入式数据库最适合以下需求?
】哪个用于客户端应用程序的嵌入式数据库最适合以下需求?【英文标题】:WhichembeddedDatabaseforclientbaseapplicationisbestforfollowingneeds?【发布时间】:2012-01-2610:49:16【问题描述】:1.In-buildEncryptionsupport2.FullTextSearch3.BooleanSearch4.C/C++,VBa... 查看详情
利用nodemcu和mqtt协议让嵌入式设备接入互联网(二.nodejs的安装和配置)(代码片段)
文章目录前言nodejsnvm和nodejs的安装npm的相关配置配置npm的global和cache路径配置npm仓库为国内淘宝镜像npm下载相关依赖包npm初始化项目安装相关依赖包前言第一篇讲了怎么用layui做HTML的前端网页,现在我们需要将我们的数据传... 查看详情
ude-12154:operationgeneratedoracleerror12154
[[email protected]~]$expdpsystem/[email protected]directory=dump_dirdumpfile=plusdevschema.dmpschemas=PLUSDEVUDE-12154:operationgeneratedORACLEerror12154ORA-12154:TNS:couldnotresolvetheconne 查看详情
视频监控如何实现多设备平台到省应急智慧中心播放的场景需求?
...套这样的系统需要考虑三个方面的内容,分别是前端接入、视频诊断、视频转码。本文我们就从这三个方面讲一下这套系统的实现。视频前端接入对于没有建设联网平台的行业单位,视频联网系统可以通过直接接入前端... 查看详情
嵌入式arm核心板的介绍
...设计需求; 预装裁剪好的嵌入式操作系统(如:Linux、Android或WinCE等),并提供板载所有外围设备驱动库,客户可以完全不用调试复杂的底层驱动,直接进行应用程序开发; 高性能、低功耗、扩展性强、集成度高,经过不同行... 查看详情