android项目从零开始 Android webview支持 文件上传、图片上传

安卓 WebView 的文件上传问题分析 安卓 WebView 的文件上传问题 - ValueCallback 回调 阅读详情

项目中用webview包裹网站,出现上传文件无反应的情况,之前了解过文件上传。现在的前端页面需要处理的是

1.打开本地文件选择器

2.用户选择需要上传的文件

3.处理用户选择的文件通知webview

4.前端提交表单上传文件


首先需要webview 对 JS 的支持

webview.getSettings().setJavaScriptEnable(true)


前端页面针对不同版本的android系统 webview内核会有不同,调用方法不一致

webview.setWebChromeClient(new WebChromeClient() {

        // For Android < 3.0
        public void openFileChooser(ValueCallback<Uri> valueCallback) {
            ***
        }

        // For Android  >= 3.0
        public void openFileChooser(ValueCallback valueCallback, String acceptType) {
            ***
        }

        //For Android  >= 4.1
        public void openFileChooser(ValueCallback<Uri> valueCallback, 
                String acceptType, String capture) {
            ***
        }

        // For Android >= 5.0
        @Override
        public boolean onShowFileChooser(WebView webView, 
                ValueCallback<Uri[]> filePathCallback, 
                WebChromeClient.FileChooserParams fileChooserParams) {
            ***
            return true;
        }
    });



完整代码


public class MainActivity extends AppCompatActivity {

    private ValueCallback<Uri> uploadMessage;
    private ValueCallback<Uri[]> uploadMessageAboveL;
    private final static int FILE_CHOOSER_RESULT_CODE = 10000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        WebView webview = (WebView) findViewById(R.id.web_view);
        assert webview != null;
        WebSettings settings = webview.getSettings();
        settings.setUseWideViewPort(true);
        settings.setLoadWithOverviewMode(true);
        settings.setJavaScriptEnabled(true);
        webview.setWebChromeClient(new WebChromeClient() {

            // For Android < 3.0
            public void openFileChooser(ValueCallback<Uri> valueCallback) {
                uploadMessage = valueCallback;
                openImageChooserActivity();
            }

            // For Android  >= 3.0
            public void openFileChooser(ValueCallback valueCallback, String acceptType) {
                uploadMessage = valueCallback;
                openImageChooserActivity();
            }

            //For Android  >= 4.1
            public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
                uploadMessage = valueCallback;
                openImageChooserActivity();
            }

            // For Android >= 5.0
            @Override
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
                uploadMessageAboveL = filePathCallback;
                openImageChooserActivity();
                return true;
            }
        });
        String targetUrl = "file:///android_asset/up.html";
        webview.loadUrl(targetUrl);
    }

    private void openImageChooserActivity() {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("image/*");
        startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE);
    }

    @Override
    protected 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();
            if (uploadMessageAboveL != null) {
                onActivityResultAboveL(requestCode, resultCode, data);
            } else if (uploadMessage != null) {
                uploadMessage.onReceiveValue(result);
                uploadMessage = null;
            }
        }
    }

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


Vue.js 图片上传实战:vue-picture-input + FormData + axios 完整链路解析 图片上传是 Web 开发中基础却高危的技术环节,其本质是浏览器原生 File API 与表单数据编码(multipart/form-data)的协同过程。核心原理在于利用 FormData 构建符合 RFC 7578 规范的二进制载荷,并由 axios 等 HTTP 客户端在不干扰 boundary 自动生成的前提下完成传输。该技术方案的价值在于兼顾前端交互可控性、网络层可调试性与后端协议兼容性,广泛应用于头像管理、商品图上传、表单附件提交等场景。本文聚焦 Vue 生态下稳定落地的关键实践,深度解析 vue 阅读详情

相关推荐

Gemini在iOS上怎么用?官方网页版使用全指南

Gemini作为谷歌推出的先进AI大模型,其核心能力依赖云端推理与实时服务。在iOS生态中,由于苹果平台对本地AI运行、后台进程及敏感权限的严格限制,谷歌选择不发布独立App,而是主推Safari网页端——这并非妥协,而是基于WebGPU支持、模型热更新、隐私可控与跨设备一致性等技术逻辑的最优解。该方案完整支持多轮对话、文件上传(PDF/DOCX/JPG等)、代码生成与图像理解,且始终运行最新版Gemini 1.5 Pro模型。适用于律师合同分析、设计师稿图解读、开发者Swift脚本生成等真实工作场景。本文

weixin_30824479的博客 378

Android开发深入理解WebChromeClient之onShowFileChooser或openFileChooser使用说明

Android开发使用WebView控件加载包含表单的H5网页,点击上传文件按钮,弹出对话框,选择从相册获取照片、拍照或打开手机文件管理器,从Android手机选取一张图片或一个文件,然后通过ValueCallback接口传递,在WebView加载的H5网页显示。这里有一个问题,点击“取消”或返回按钮,无法重复回调onShowFileChooser或openFileChooser方法,控制台打印:Attempted to finish an input event but the input event r

xiaodongvtion的专栏 8554

手把手教你用Vant实现拍照上传功能:从基础配置到高级技巧

本文详细介绍了如何使用Vant的`van-uploader`组件实现移动端拍照上传功能,从基础配置到高级技巧全面覆盖。内容包括环境准备、多平台兼容性处理、图片质量压缩、上传进度反馈等实用功能,特别强调了`capture`属性的使用技巧和移动端适配方案,帮助开发者快速构建稳定高效的拍照上传功能。

weixin_29009501的博客 127

安卓WebView文件上传的实现(解决安卓WebView中<input type=‘file‘/>标签点击没反应)

网页端上传文件常用<input type='file'/>标签,放上这个标签,浏览器就会出现这个文件选择器,点击就可以弹出文件选择窗口,很是简单方便,不过,包含<input type='file'/>标签的网页要是在安卓WebView中渲染,<input type='file'/>这个标签就会失效,用户点击后毫无反应,根本原因就是安卓WebView没有实现具体的文件选择器方法,对应的方法是空的,我们要安卓WebView支持<input type='file'/&gt

sdxjwkq01的博客 9642

Trae移动端:轻量智能开发神经末梢的架构演进

现代移动开发已超越传统App范畴,演进为融合本地计算、边缘推理与上下文感知的智能工作流。其核心在于将IDE级能力按需下沉至终端,在离线、低延迟、高安全约束下实现精准响应。关键技术包括轻量化大模型(如Qwen1.5-0.5B)的端侧部署、基于Capacitor+React Native Bridge的混合架构设计、以及以‘信任半径’为准则的沙箱化执行环境。这类方案广泛应用于碎片化开发场景——如通勤查日志、现场调试API、语音驱动代码解释等。Trae移动端正是这一范式的典型实践,它不追求功能堆砌,而专注在3秒内

congtaixiao7151的博客 365

localForage:浏览器本地存储的易用异步解决方案

浏览器本地存储是前端离线能力与用户体验优化的基础技术,涉及 IndexedDB、localStorage 等底层机制,但原生 API 存在同步阻塞、类型限制、兼容性差等工程痛点。localForage 通过存储引擎抽象层实现自动降级与 Promise 化封装,在保留二进制支持(如 Blob、ArrayBuffer)的同时,提供类同步的简洁调用体验。其核心价值在于降低开发者的心智负担,让表单防丢失、PWA 离线缓存、待办清单持久化等典型场景得以快速落地。本文围绕 localForage 的异步设计、类型安全序

weixin_30340819的博客 431

android WebView上传文件到服务器[android+server代码]

最近比较坑爹,公司app部分页面要转H5,美其名曰称之为节约人力成本,无奈,我们就从后台PHP,JQuery从零开始学起。项目中遇到这么一个问题:要从android的WebView中上传用户头像到服务器,当初感觉蛮简单的,就没怎么注意,没想到一道道大坑摆在我面前,特此记录一下。前端界面蛮丑的,这么就不说,基本上就像下图一样: 这里的加号图片,主要是美化上传用的,它还有一个作用就是图片预览功能,基本

成长的烧年 3202

Android WebView中文件上传功能的实现

在该方法中,我们首先检查之前的文件上传回调是否已存在,如果存在,则取消之前的回调。如果是,我们首先检查fileUploadCallback是否存在,如果存在,则获取文件选择器返回的结果,并通过fileUploadCallback.onReceiveValue()方法将结果传递给WebView。通过以上步骤,我们就实现了在Android应用的WebView中支持文件上传的功能。在网页中,当用户点击文件上传按钮时,将会启动文件选择器,用户可以选择本地文件进行上传操作。如果你有任何问题,请随时提问。

ScriptCharm的博客 1449

Vue2项目中集成vue-qrcode-reader实现Web端二维码扫描全攻略

二维码识别作为Web前端开发中的常见需求,其核心原理是通过浏览器API捕获视频流,结合图像处理算法解析编码信息。在Vue技术栈中,vue-qrcode-reader插件将底层jsQR库与Vue响应式系统结合,提供了组件化的解决方案,极大简化了开发流程。该方案适用于电商、物联网、企业内部管理等场景,能够实现扫码登录、设备绑定等实时交互功能。本文基于Vue2项目实践,详细解析了vue-qrcode-reader的集成步骤、性能优化策略及常见问题排查方法,帮助开发者快速构建稳定高效的Web端扫码功能。

weixin_30940783的博客 386

关于Android WebView调用onShowFileChooser 无法重复调用的问题

在WebVIew开发中,经常会遇到调⽤⼿机系统相册的场景,不过由于Android版本多的原因,很多系统无法正常打开手机的系统相册。通常,在Web页⾯上点击选择⽂件的控件时,前端一般会使用的写法,此时系统会自动调用WebChromeClient 的openFileChooser()方法(5.0及以上系统会调用onShowFileChooser())来打开打开系统相册。参考代码如下: 然后,在onActivityResult()中将选择的图⽚内容通过ValueCallback的onReceiveValue()方

xiangzhihong8的专栏 2702

仿微信界面H5聊天室源码:多人群聊IM系统部署与二次开发

即时通讯(IM)能力已成为Web应用中的高频需求,从社交聊天到客服系统都离不开实时消息交互。其底层核心通常依托WebSocket长连接技术,通过连接管理、心跳检测、消息推送与重连机制,保障多人群聊场景下的低延迟通信。在实际工程项目中,一套成熟的聊天室源码能大幅降低从零搭建的技术门槛,尤其当界面设计接近微信交互习惯时,可显著提升用户体验与验收通过率。这类网页聊天室方案不仅支持单聊、群聊、好友关系,还可扩展客服分配与工单体系,适合接单开发者、产品经理及企业内部沟通工具使用。本文梳理一套可直接部署的H5聊天室源码

weixin_34408624的博客 308

VibeCoding实战:一个月构建全平台云笔记应用

在当今快速迭代的软件开发领域,低代码与可视化编程工具正成为提升开发效率的关键技术。这类工具通过抽象底层代码细节,让开发者能更专注于业务逻辑与用户体验设计,其核心原理在于将常见的应用模式(如数据模型、API接口、UI组件)封装为可配置的模块。从技术价值看,它们极大地降低了全栈应用开发的门槛,缩短了从概念验证到产品上线的周期,尤其适合构建以数据增删改查(CRUD)为核心的中低复杂度应用,例如管理后台、内部工具和快速原型。在应用场景上,独立开发者或小型团队可以利用此类工具高效实现多端覆盖(如Web、移动端),快速

weixin_30553777的博客 407

微信小程序+云开发:校园跑步社交系统的设计与实现

在移动应用开发领域,小程序因其轻量化和免安装的特性,成为高校校园场景下应用落地的重要载体。微信小程序提供了一整套前端运行环境,而云开发能力则免去了自建服务器的运维负担,让开发者可以专注于业务逻辑。云函数作为云端计算单元,承担了身份校验、数据聚合和内容安全检测等关键职责,结合云数据库与云存储,构建了完整的数据闭环。这套技术组合广泛应用于校园工具、社交社区、运动健康等场景,尤其适合开发具备真实业务闭环的毕业设计项目。本文围绕一个校园跑步社交小程序的架构设计展开,详细讲解如何利用微信原生框架与云开发实现GPS轨迹

weixin_34221654的博客 230

webview开发中使用onShowFileChooser实现web页打开照相机或者图片浏览

转自https://www.jianshu.com/p/48e688ce801f 最近公司项目需要在WebView上调用手机系统相册来上传图片,开发过程中发现在很多机器上无法正常唤起系统相册来选择图片。 解决问题之前我们先来说说WebView上传文件的逻辑:当我们在Web页面上点击选择文件的控件(<input type="file">)时,会回调WebChromeClient下的o...

wangluoyang的专栏 7275

Android WebView 上传文件支持全解析

主要针对Android WebView 上传文件支持进行全面解析,感兴趣的小伙伴们可以参考一下

天池长期赛:二手车价格预测(422方案分享)

本次比赛是一次很好的锻炼数据挖掘能力的入门赛,从EDA-数据清洗-特征工程-模型调参-模型融合,能够完整的学习到大数据的分析和挖掘,值得历练。

weixin_46685991的博客 1万+

安卓WebView(H5)调用原生相机及相册

WebView(h5)调用安卓原生相机或者相册

m0_46366678的博客 8628

EtherCAT主站开发(学习笔记一)

摘要:本文介绍了基于STM32H7的EtherCAT主站开发探索。EtherCAT是一种高实时性工业以太网协议,具有低延迟、高带宽利用率等特点。文章详细解析了EtherCAT的协议架构、帧结构和工作原理,重点阐述了PDO数据传输过程及主从站通信机制。同时介绍了CoE、FoE等应用层协议扩展。作者将基于SOEM开源协议栈进行开发,为后续实际应用中的伺服电机控制奠定基础。

weixin_69388007的博客 1473

【亲测免费】 探索Android WebView上传文件的最佳实践:`android-webview-upload-file`

探索Android WebView上传文件的最佳实践:android-webview-upload-file 在移动应用开发中,集成WebView组件以展示网页内容是一种常见的做法。然而,实现WebView内的文件上传功能并非易事,尤其是在处理安全性和用户体验上。为此,我们找到了一个出色的开源项目——,它为开发者提供了一种高效、可控的解决方案。 项目简介 android-webview-uploa...

gitblog_00085的博客 844

WRF和WPS安装和编译时遇到的问题

检查是否自己netcdf和Fortran编译器一致。解决办法:修改configure.wps里的路径。如果没问题且wrf已成功编译,考虑重新。path修改为jasper在的路径。

m0_54898744的博客 1837

主流双目相机技术参数横向评测:从ZED到国产新锐

本文对主流双目相机技术参数进行了横向评测,涵盖ZED、Bumblebee等国际品牌及国产新锐产品。详细分析了分辨率、帧率、视场角等关键参数,并针对机器人导航、AR/VR交互、工业检测等场景提供选型建议。特别推荐ZED相机在科研领域的成熟应用,以及国产方案在长基线设计和主动双目技术上的创新突破。

weixin_33670786的博客 317

安卓webview上传文件

后端jsp 客户端 @Override public boolean onShowFileChooser(WebView webView, ValueCallback&amp;amp;amp;lt;Uri[]&amp;amp;amp;gt; filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) { ...

积跬步,成千里。 1236

Qwen-Image(阿里通义千问)技术浅析(一)

Qwen-Image(阿里通义千问多模态模型)是阿里巴巴推出的视觉-语言多模态大模型,能够理解图像内容并完成复杂的跨模态任务。

m0_75253143的博客 675
上一篇: android项目从零开始 RecycleView 设置滚动到某item时间
下一篇: android webview 页面关闭还保持登录态session问题
束千凡
博客等级 码龄14年 21粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值