Android WebView上传文件/自定义弹窗技术,附件的解决方案
安卓内核开发
其实是Android的webview默认是不支持<input type="file"/>文件上传的。现在的前端页面需要处理的是:

权限
文件路径AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
宿主返回代码
private ValueCallback<Uri> uploadMessage;private ValueCallback<Uri[]> uploadMessageAboveL;private final static int FILE_CHOOSER_RESULT_CODE = 10000;// 2.回调方法触发本地选择文件private void openImageChooserActivity() {Intent i = new Intent(Intent.ACTION_GET_CONTENT);i.addCategory(Intent.CATEGORY_OPENABLE);
// i.setType("image/*");//图片上传
// i.setType("file/*");//文件上传i.setType("*/*");//文件上传startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE);}// 3.选择图片后处理@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == FILE_CHOOSER_RESULT_CODE) {if (null == uploadMessage && null == uploadMessageAboveL) return;Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();// Uri result = (((data == null) || (resultCode != RESULT_OK)) ? null : data.getData());if (uploadMessageAboveL != null) {onActivityResultAboveL(requestCode, resultCode, data);} else if (uploadMessage != null) {uploadMessage.onReceiveValue(result);uploadMessage = null;}} else {//这里uploadMessage跟uploadMessageAboveL在不同系统版本下分别持有了//WebView对象,在用户取消文件选择器的情况下,需给onReceiveValue传null返回值//否则WebView在未收到返回值的情况下,无法进行任何操作,文件选择器会失效if (uploadMessage != null) {uploadMessage.onReceiveValue(null);uploadMessage = null;} else if (uploadMessageAboveL != null) {uploadMessageAboveL.onReceiveValue(null);uploadMessageAboveL = null;}}}// 4. 选择内容回调到Html页面@TargetApi(Build.VERSION_CODES.LOLLIPOP)private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {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;}
webview完整扩展
private class Cyber_ChromeClient extends WebChromeClient {
{@Overridepublic void onProgressChanged(WebView view, int newProgress) {super.onProgressChanged(view, newProgress);// mProgress.setProgress(newProgress);}@Overridepublic void onReceivedTitle(WebView view, String title) {super.onReceivedTitle(view, title);// mTitle.setText(title);}@Overridepublic void onReceivedIcon(WebView view, Bitmap icon) {super.onReceivedIcon(view, icon);}@Overridepublic boolean onJsAlert(WebView view, String url, String message, final android.webkit.JsResult result) {new AlertDialog.Builder(cyber_instance).setTitle("悠然智慧管理4.0").setMessage(message).setPositiveButton(android.R.string.ok,new AlertDialog.OnClickListener() {public void onClick(DialogInterface arg0, int arg1) {// TODO Auto-generated method stubresult.confirm();}}).setCancelable(false).create().show();return true;}//2020-5-15/*** 对网络连接状态进行判断* @return true, 可用; false, 不可用*/private boolean isOpenNetwork() {ConnectivityManager connManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo networkInfo = connManager.getActiveNetworkInfo(); if(networkInfo!= null) {//2.获取当前网络连接的类型信息//int networkType = networkInfo.getType();if(ConnectivityManager.TYPE_WIFI == networkType){//当前为wifi网络}else if(ConnectivityManager.TYPE_MOBILE == networkType){//当前为mobile网络}return connManager.getActiveNetworkInfo().isAvailable(); }return false;}/*** 覆盖默认的window.confirm展示界面,避免title里显示为“:来自file:”*/public boolean onJsConfirm(WebView view, String url, String message,final JsResult result) {final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());builder.setTitle("优然智慧管理系统").setMessage(message).setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {result.confirm();}}).setNeutralButton("取消", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {result.cancel();}});builder.setOnCancelListener(new DialogInterface.OnCancelListener() {@Overridepublic void onCancel(DialogInterface dialog) {result.cancel();}});// 屏蔽keycode等于84之类的按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题builder.setOnKeyListener(new DialogInterface.OnKeyListener() {@Overridepublic boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {//Log.v("onJsConfirm", "keyCode==" + keyCode + "event="+ event);return true;}});// 禁止响应按back键的事件// builder.setCancelable(false);AlertDialog dialog = builder.create();dialog.show();return true;// return super.onJsConfirm(view, url, message, result);}/*** 覆盖默认的window.prompt展示界面,避免title里显示为“:来自file:”* window.prompt('请输入您的域名地址', '618119.com');*/public boolean onJsPrompt(WebView view, String url, String message,String defaultValue, final JsPromptResult result) {final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());builder.setTitle("优然智慧管理系统").setMessage(message);final EditText et = new EditText(view.getContext());et.setSingleLine();et.setText(defaultValue);builder.setView(et).setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {result.confirm(et.getText().toString());}}).setNeutralButton("取消", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {result.cancel();}});// 屏蔽keycode等于84之类的按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题builder.setOnKeyListener(new DialogInterface.OnKeyListener() {public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {//Log.v("onJsPrompt", "keyCode==" + keyCode + "event="+ event);if (keyCode == KeyEvent.KEYCODE_ENTER) {result.confirm(et.getText().toString());dialog.dismiss();return true;}else{return false;}//}});// 禁止响应按back键的事件// builder.setCancelable(false);final AlertDialog dialog = builder.create();//2021-3-18 回车检测et.setOnKeyListener(new View.OnKeyListener() {@Overridepublic boolean onKey(View v, int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_ENTER) {// 监听到回车键,会执行2次该方法。按下与松开result.confirm(et.getText().toString());dialog.dismiss();}return false;}});dialog.show();return true;// return super.onJsPrompt(view, url, message, defaultValue,// result);}/2020-5-15//20240604 文件// For Android < 3.0public void openFileChooser(ValueCallback<Uri> valueCallback) {uploadMessage = valueCallback;openImageChooserActivity();}// For Android >= 3.0public void openFileChooser(ValueCallback valueCallback, String acceptType) {uploadMessage = valueCallback;openImageChooserActivity();}//For Android >= 4.1public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {uploadMessage = valueCallback;openImageChooserActivity();}// For Android >= 5.0@Overridepublic boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {uploadMessageAboveL = filePathCallback;openImageChooserActivity();return true;}}
}
调用浏览
//非常重要cwpd_Web.setWebViewClient(new Cyber_WebviewClient());cwpd_Web.setWebChromeClient(new Cyber_ChromeClient());
相关文章:
Android WebView上传文件/自定义弹窗技术,附件的解决方案
安卓内核开发 其实是Android的webview默认是不支持<input type"file"/>文件上传的。现在的前端页面需要处理的是: 权限 文件路径AndroidManifest.xml <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&g…...
selenium 输入框、按钮,输入点击,获取元素属性等简单例子
元素操作 nput框 输入send_keys, input框 清除clear(), 按钮 点击click() 按钮 提交submit() 获取元素 tag_name、 class属性值、 坐标尺寸 """ input框 输入1次,再追加输入一次, 清除, 再重新输入&…...
结构体构造函数
【知识点:结构体构造函数】下面两段代码等价。 (1)结构体构造函数写法 struct LinkNode {int data;LinkNode* next;LinkNode(int x):data(x),next(NULL) {} }; LinkNode* Lnew LinkNode(123); (2)非结构体构造函数写…...
基于单片机的电子万年历设计
摘要: 本设计以 AT89C51 单片机为主控器,使用 DS1302 时钟芯片、DS18B20 温度芯片、LCD1602 显示模块,利用Proteus 仿真软件和 Keil 编译软件进行了基于单片机的电子万年历仿真,设计的万年历可以在液晶上显示时间,同时还具有时间校准、温度显示等功能。 关键词 :单片机…...
大厂真实面试题(一)
滴滴大数据sql 取出累计值与1000差值最小的记录 1.题目 已知有表t_cost_detail包含id和money两列,id为自增,请累加计算money值,并求出累加值与1000差值最小的记录。 2.分析 本题主要是想找到累加值域1000差距最小的记录,也就是我们要对上述按照id进行排序并且累加,并…...
Docker搭建ELKF日志分析系统
Docker搭建ELKF日志分析系统 文章目录 Docker搭建ELKF日志分析系统资源列表基础环境一、系统环境准备1.1、创建所需的映射目录1.2、修改系统参数1.3、单击创建elk-kgc网络桥接 二、基于Dockerfile构建Elasticsearch镜像2.1、创建Elasticsearch工作目录2.2、上传资源到指定工作路…...
把系统引导做到U盘,实现插上U盘才能开机
前言 有个小伙伴提出了这样一个问题:能不能把U盘制作成电脑开机的钥匙? 小白稍微思考了一下,便做了这样一个回复:可以。 至于为什么要思考一下,这样会显得我有认真思考他提出的问题。 Windows7或以上系统均支持UEF…...
【计算机网络基础知识】
首先举一个生活化的例子,当你和朋友打电话时,你可能会使用三次握手和四次挥手的过程进行类比: 三次握手(Three-Way Handshake): 你打电话给朋友:你首先拨打你朋友的电话号码并等待他接听。这就…...
个股场外期权个人如何参与买卖?
个股场外期权作为一种金融衍生品,为个人投资者提供了多样化的投资选择和风险管理工具。想要参与个股场外期权的买卖,以下是一些关键步骤和考虑因素。 文章来源/:财智财经 第一步:选择合适的金融机构 首先,个人投资者需…...
程序猿大战Python——pycharm软件的使用
基础配置 目标:了解PyCharm软件的基础配置处理。 修改背景颜色: Appearance -> Theme 修改字体大小: 搜索font -> Font 例如,一起完成背景、字体大小的修改。 总结: (1)如果要对PyChar…...
Unity Standard shader 修改(增加本地坐标裁剪)
本想随便找一个裁剪的shader,可无奈的是没找到一个shader符合要求,美术制作的场景都是用的都标准的着色器他们不在乎你的功能逻辑需求,他们只关心场景的表现,那又找不到和unity标准着色器表现一样的shader 1.通过贴图的透明通道做…...
【数据结构】排序——插入排序,选择排序
前言 本篇博客我们正式开启数据结构中的排序,说到排序,我们能联想到我之前在C语言博客中的冒泡排序,它是排序中的一种,但实现效率太慢,这篇博客我们介绍两种新排序,并好好深入理解排序 💓 个人主…...
2024.6.9刷题记录
目录 一、1103. 分糖果 II 1.模拟 2.数学 二、312. 戳气球 1.递归-记忆化搜索 2.区间dp 三、2. 两数相加 1.迭代 2.递归-新建节点 3.递归-原节点 四、4. 寻找两个正序数组的中位数 1.堆 2.双指针二分 五、5. 最长回文子串 1.动态规划 2.中心扩展算法 六、6. Z…...
Matlab|遗传粒子群-混沌粒子群-基本粒子群
目录 1 主要内容 2 部分代码 3 效果图 4 下载链接 1 主要内容 很多同学在发文章时候最犯愁的就是创新点创新点创新点(重要的事情说三遍),对于采用智能算法的模型,可以采用算法改进的方式来达到提高整个文章创新水平的目的&…...
31|HTTP3:甩掉TCP、TLS 的包袱,构建高效网络
前面两篇文章我们分析了HTTP/1和HTTP/2,在HTTP/2出现之前,开发者需要采取很多变通的方式来解决HTTP/1所存在的问题,不过HTTP/2在2018年就开始得到了大规模的应用,HTTP/1中存在的一大堆缺陷都得到了解决。 HTTP/2的一个核心特性是…...
2 程序的灵魂—算法-2.2 简单算法举例-【例 2.3】
【例 2.3】判定 2000 — 2500 年中的每一年是否闰年,将结果输出。 润年的条件: 1. 能被 4 整除,但不能被 100 整除的年份; 2. 能被 100 整除,又能被 400 整除的年份; 设 y 为被检测的年份,则算法可表示如下…...
Python中的上下文管理器(contextlib)模块
Python中的contextlib模块提供了一些用于创建和管理上下文管理器(context managers)的工具。上下文管理器是实现了__enter__()和__exit__()方法的对象,它们通常用于确保在代码块执行前后执行某些操作,比如资源获取与释放、设置和重…...
C语言:定义和使用结构体变量
定义和使用结构体变量 介绍基础用法1.定义结构体2. 声明结构体变量3. 初始化和访问结构体成员4. 使用指针访问结构体成员5. 使用结构体数组 高级用法6. 嵌套结构体7. 匿名结构体8. 结构体和动态内存分配9. 结构体作为函数参数按值传递按引用传递 介绍 在C语言中,结…...
Vue3学习第二天记录
Vue3学习第二天记录 背景说明截图记录一个简单的JS文件Vue3的watch()函数Vue3的toRef()/toRefs()函数前端数据类型的分类前端写一个对外暴露的函数前端的...语法Vue3中watch()函数的总结Vue3中watchEffect()函数Vue3中watch()函数的坑Vue3中computed()函数 背景 最近在学习尚硅…...
C语言:双链表
一、什么是双链表? 双链表,顾名思义,是一种每个节点都包含两个链接的链表:一个指向下一个节点,另一个指向前一个节点。这种结构使得双链表在遍历、插入和删除操作上都表现出色。与单链表相比,双链表不仅可以…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
