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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/847320.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【AI基础】第二步:安装AI运行环境

开局一张图&#xff1a; 接下来按照从下往上的顺序来安装部署。 规则1 注意每个层级的安装版本&#xff0c;上层的版本由下层版本决定 比如CUDA的版本&#xff0c;需要看显卡安装了什么版本的驱动&#xff0c;然后CUDA的版本不能高于这个驱动的版本。 这个比较好理解&#xff…

毕业论文word常见问题

0、前言&#xff1a; 这里的问题都是以office办公软件当中的word为例&#xff0c;和WPS没有关系。 1、页眉横线删不掉&#xff1a; 解决方案&#xff1a;进入页眉编辑状态&#xff0c;在开始选项栏中选择页眉字体样式&#xff0c;清除格式。 修改方式如下&#xff1a; 2、…

mysql inset bug

在 SQL 中&#xff0c;日期值需要用单引号包围&#xff0c;这是因为 SQL 将日期值视为字符串格式。数据库引擎在处理这些值时会将它们解析为适当的日期类型。如果不使用单引号&#xff0c;数据库引擎会将它们视为数字或列名&#xff0c;从而导致语法错误。 日期格式 MySQL 支…

在Linux/Ubuntu/Debian系统中使用 `tar` 压缩文件

在Linux/Ubuntu/Debian系统中使用 tar 压缩文件 tar 命令是用于在类 Unix 操作系统中创建文件和目录存档的强大实用程序。 基本存档创建 要创建文件夹的简单存档&#xff0c;请使用以下命令&#xff1a; tar -cf ./my-archive.tar ./my-folder/此命令将创建一个名为 my-arc…

java入门 Netty ByteBuf

一、 参考资料 参考黑马netty教程 https://www.bilibili.com/video/BV1py4y1E7oA?p88&spm_id_frompageDriver&vd_source4cd1b6f268e2a29a11bea5d2568836ee 二、 ByteBuf测试 app.java package com.sht.test;import io.netty.buffer.ByteBuf; import io.netty.buff…

Android基础-Jetpack Compose

Jetpack Compose&#xff0c;作为Android平台上一款革命性的UI框架&#xff0c;自其推出以来就受到了广大开发者的热烈关注和广泛应用。它不仅简化了Android应用的UI开发流程&#xff0c;提高了开发效率&#xff0c;而且为开发者带来了更直观、更灵活、更强大的UI定义方式。下面…

Linux——简单指令汇总

Linux&#xff0c;一般指GNU/Linux&#xff0c;是一种免费使用和自由传播的类UNIX操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦兹&#xff08;Linus Benedict Torvalds&#xff09;于1991年10月5日首次发布&#xff0c;它主要受到Minix和Unix思想的启发&#xff0c;是一个…

C++ | Leetcode C++题解之第130题被围绕的区域

题目&#xff1a; 题解&#xff1a; class Solution { public:const int dx[4] {1, -1, 0, 0};const int dy[4] {0, 0, 1, -1};void solve(vector<vector<char>>& board) {int n board.size();if (n 0) {return;}int m board[0].size();queue<pair<…

C++类的继承与派生概念

派生和继承是自然界普遍存在的一种现象。例如&#xff0c;“猫”和“白猫”。当人们谈及“猫”时&#xff0c;知道它有4条腿&#xff0c;1条尾巴&#xff0c;抓老鼠,为哺乳动物。如谈论“白猫”时&#xff0c;它也是猫&#xff0c;只不过增加了一个新的特征&#xff0c;即它的毛…

Flutter 中的 KeepAlive 小部件:全面指南

Flutter 中的 KeepAlive 小部件&#xff1a;全面指南 Flutter 是一个由 Google 开发的跨平台 UI 框架&#xff0c;它允许开发者使用 Dart 语言构建高性能、美观的移动、Web 和桌面应用。在 Flutter 的丰富组件库中&#xff0c;KeepAlive 是一个用于维护组件活跃状态的组件&…

Redis缓存(笔记二:Redis常用五大数据类型)

目录 1、Redis中String字符串 1.1 常用命令解释&#xff1a; 1.2 原子性 1.3 具有原子性的常用命令 1.4 String数据结构 1、Redis中String字符串 概念 String 是 Redis 最基本的类型&#xff0c;可以理解成与 Memcached 一模一样的类型&#xff0c;一个 key对应一个 value…

软设之排序算法对比

直接插入 时间复杂度:平均情况为O(n^2)。特殊情况下基本有序最优为O(n) 空间复杂度:O(1) 希尔排序 时间复杂度:平均情况O(n^1.3) 空间复杂度:O(1) 直接选择排序 时间复杂度:O(n^2) 空间复杂度:O(1) 堆排序 时间复杂度:O(nlog(2)n) 空间复杂度:O(1) 冒泡排序 时间…

第6章:数据库设计基础知识

数据库基本概念 数据(Data)是描述事物的符号记录&#xff0c;它具有多种表现形式&#xff0c;可以是文字、图形、图像、声音和语言等。数据库系统(DataBase System&#xff0c;DBS)是一个采用了数据库技术&#xff0c;有组织地、动态地存储大量相关联数据&#xff0c;从而方便多…

3162. 优质数对的总数 I

给你两个整数数组 nums1 和 nums2&#xff0c;长度分别为 n 和 m。同时给你一个正整数 k。 如果 nums1[i] 可以被 nums2[j] * k 整除&#xff0c;则称数对 (i, j) 为 优质数对&#xff08;0 < i < n - 1, 0 < j < m - 1&#xff09;。 返回 优质数对 的总数。 示…

第100天:权限提升-数据库RedisPostgre第三方软件TV向日葵服务类

目录 思维导图 案例一: 数据库-Redis 数据库权限提升-计划任务 案例二: 数据库-PostgreSQL 数据库权限提升-漏洞 PostgreSQL 提权漏洞&#xff08;CVE-2018-1058&#xff09; PostgreSQL 高权限命令执行漏洞&#xff08;CVE-2019-9193&#xff09; 案例三: 三方应用-…

【数据结构与算法 经典例题】(C语言)反转链表图文详解

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法 经典例题》C语言 期待您的关注 ​ 目录 一、问题描述 二、解题思路分析 三、代码实现 一、问题描述 二、解题…

c++ 函数作为参数

在C中&#xff0c;函数指针或函数对象可以作为参数传递给另一个函数&#xff0c;实现了函数的动态调用和灵活性。这种机制在回调函数、事件处理、泛型编程等领域中非常有用。 1.函数指针作为参数&#xff1a; 函数指针可以指向特定函数&#xff0c;并被用作参数传递给另一个函数…

uniapp使用uQRCode页面不显示也不报错

我使用的版本是&#xff1a;4.0.6 引入到项目中后根据官方的配置教程进行配置&#xff1a; 但是页面上就是不显示&#xff0c;也不报错&#xff0c;看官网发现步骤也没问题 解决方法&#xff1a; 这句话代表的是uQrcode会被自动引用注册&#xff0c;但是你引过组件库或者别的…

Java进阶学习笔记37——正则表达式

正则表达式&#xff1a; 就是由一些特定的字符组成的&#xff0c;代表的是一个规则。 作用&#xff1a; 1&#xff09;用来校验数据格式是否合法&#xff1b; 校验电话号码是否合法&#xff1b; 校验邮箱是否合法&#xff1b; 用户输入的QQ号码是否合法&#xff1b; 2&…

QT treeWidget如何添加虚线

1、添加以下代码即可&#xff1a; ui.treeWidget->setStyle(QStyleFactory::create("windows"));2、效果如下&#xff1a;