关于安卓USB开发(一)文件复制,文件夹创建

背景

在安卓应用中,把某个文件,复制到插入的U盘中

开发环境

win10,jdk8+,as4+

测试机型

红米Note11,android13

源码问题

文末将会提供博主整合好的源码项目连接,以供学习交流

注意

本次实战,u盘格式是fat32,其他格式,测试过,并不支持。如果有更好的想法,开源库,可以留言探讨

开源库

libaums link

开始接入

首先第一步,就是一个大坑。国内的文章,一搜索,发现都是可以列入博物馆的了,实战起来的安卓系统版本,也是很低。最近这几年更新的文章,极少。

这里用到的,就是https://github.com/magnusja/libaums这个开源库。这个库最新的版本,是0.10.0,基于kotlin进行开发的,所以还在使用java的项目,就要引入java对kotlin的支持了。

(1)java项目引入kotlin支持

项目根部build.gradle文件,声明
classpath “org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0”,如下图:
在这里插入图片描述
然后在开发模块build.gradle中,引入:

apply plugin: 'kotlin-android'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0"

完成上述步骤后,java就支持kotlin了。

(2)开源库版本的引入方式

博主采用的,是把开源库下载到本地,编译以后,生成aar包,再去引入到开发模块中。
这里真实一波三折,先看三方库开源库的目录:
在这里插入图片描述
下载完以后,在本地运行,发现有很多报错,一一修改以后,才可以正常运行。

报错一

libusbcommunication依赖的libusb编译问题,导致编译失败

报错二

项目依赖的cmake环境,有些高版本的语法需要适配

报错三

主项目中,有些没有适配安卓目标版本的方法,运行的时候报错

以上就是大概的报错类型,处理完成后,才能进行引入

引入的方式,也有很多个,其中,这个开源库作者提供了两个思路:
(1)引入libaums这个库,这个库是比较通用的,但可能有些系统适配不了
(2)引入javafs这个库,这个库是基于libaums进行开发,适配了某些场景
但是通过博主的牺牲时间式引入以后,发现两个库,在我的redmi note 11,安卓13手机上,都不能在U盘创建目录,甚至创建文件也会失败。

因此,博主就开始去看这个库的issues了。

不看不知道,一看,的确有这种情况,而作者也是爱答不理,选择性回复。这就麻了。

最后,通过不断地推敲,查看issues,发现了一种新的引入方式,就是libusbcommunication,这个可不是本地引入的,是作者写好的一个远程库,引入方式如下:

    implementation("me.jahnen.libaums:libusbcommunication:0.3.0", {
        exclude group: "androidx.core", module: "core-ktx"
        exclude group: "androidx.core", module: "core"
        exclude group: "androidx.annotation", module: "annotation-experimental"
    })
    implementation("me.jahnen:java-fs:0.1.4")

这里其实引入的产物,和javafs模块是接近的,不过重要的是,内部可能做了某些处理,目前可以在手机上android13系统跑通,其他系统暂未测试!

上述的引入,对于exclude排除,按项目需要进行排除即可。

(3)开始编写

因为项目中,引入这个库的目的,是为了把文件复制到u盘,所以,这里博主直接封装了一个remote service进行处理,目的是为了不影响原有项目的进程。

而最核心的操作,无非就是一下几个。

(3-1)u盘插入监听,拔出监听

那这个功能实现,用广播即可,相关类:

UsbManager.ACTION_USB_DEVICE_ATTACHED
UsbManager.ACTION_USB_DEVICE_DETACHED
(3-2)u盘读写权限申请

使用USBManager的hasPermission方法,进行判断是否拥有读取该设备的权限,否则进行权限申请,申请的代码如下:

PendingIntent permissionIntent = PendingIntent.getBroadcast(mContext, 0,
                new Intent(USB_PERMISSION), PendingIntent.FLAG_MUTABLE);
getUsbManager().requestPermission(device, permissionIntent);

这里要注意的是,PendingIntent,在安卓高版本的flag。
其中,USB_PERMISSION是一个自定义广播,如果用户同意,系统则会回调该广播action,开发者只在广播接收类中,进行监听该action处理即可。
广播接收核心代码如下:
在这里插入图片描述
大概的意思,就是:
U盘插入–>权限申请
U盘拔出–>资源释放
授权成功–>连接U盘

(3-2)u盘连接

使用三方库提供的类:UsbMassStorageDevice进行设备获取,然后进行初始化,连接即可,示例代码如下:
在这里插入图片描述
可以看到有几个地方注意的:
(1)List是否为空,这个是用于获取操作文件的对象的,后续通过partition.getFileSystem()获取到操作对象进行操作。
(2)数据越界判断

通过上图中的连接操作以后,如无意外,则可以获取到UsbFileSystem操作对象了,如果获取不到,则需要根据设备,进行特定处理。

(3-2)u盘写操作

那么连接成功,又怎样进行写操作呢?
下面是相关的api:

UsbFile root = currentFs.getRootDirectory();

UsbFile[] files = root.listFiles();
for(UsbFile file: files) {
    Log.d(TAG, file.getName());
    if(!file.isDirectory()) {
        Log.d(TAG, file.getLength());
    }
}

UsbFile newDir = root.createDirectory("foo");
UsbFile file = newDir.createFile("bar.txt");

// write to a file
OutputStream os = new UsbFileOutputStream(file);

os.write("hello".getBytes());
os.close();

// read from a file
InputStream is = new UsbFileInputStream(file);
byte[] buffer = new byte[currentFs.getChunkSize()];
is.read(buffer);

详细的用法,可以参考开源库主页。
而对于某些设备,不能写入的情况,正如文章开头时所说的,通过引入方式的切换,进行尝试吧!

有更好的想法,欢迎评论区留言

源码地址链接:https://pan.baidu.com/s/1fpg1ZbboNxMK74dyf_783Q
提取码:r8k9
在这里插入图片描述
that’s all-----------------------------------------------------------------------------

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

弗洛伊德-华沙算法求任意两点之间的最短路径算法

对于弗洛伊德-华沙算法首先是要假设研究的图中是不包含有负边的,对于所给的图中的任意亮点v1,vm,假设两点之间存在一条连通路径,对于该路径中去掉头和尾节点,也就是v1,vm,剩下的节点也就称之为这…

【MySQL】2. 数据库基础

1. 数据库基础(重点) 1.1 什么是数据库 存储数据用文件就可以了,为什么还要弄个数据库? 文件保存数据有以下几个缺点: 文件的安全性问题 文件不利于数据查询和管理 文件不利于存储海量数据 文件在程序中控制不方便 数据库存储介…

告别紧张,轻松应对!公众演讲的实用技巧

告别紧张,轻松应对!公众演讲的实用技巧 公众演讲,对于许多人来说,是一项充满挑战的任务。面对众多的听众,紧张情绪往往难以避免,甚至可能影响到演讲的效果。然而,通过掌握一些实用的技巧&#…

常见的业务场景实现方案

1.解决请求服务器接口跨域的问题 本地项目请求服务器接口时,因为客户端的同源策略,导致了跨域问题 配置允许本地跨域: /api指代我们要请求的接口域名,例如:this.$axios.get(/api/app.php?mApp&cIndex&aind…

一种动态联动的实现方法

安防领域中的联动规则 有安防领域相关的开发经历的人知道,IPCamera可以配置使能“侦测”功能,并且指定仅针对图像传感器的某个区载进行侦测。除了基本的“移动侦测"外,侦测的功能点还有细化的类别,如人员侦测、车辆侦测、烟…

P1042 [NOIP2003 普及组] 乒乓球

题目描述&#xff1a; AC代码&#xff1a; #include<iostream> #include<cmath>using namespace std;const int N 25*250010; int a[N],b[N]; int k[2] {11,21};int main() {int n0;while(1){char c;cin >> c;//方便后面去做计算 if(c W) a[n] 1;if(c…

牛市下 AI + Web3 叙事引关注,Verasity 或成又一黑马项目?

事实上&#xff0c;在 ChatGPT 以及 Sora 大模型被相继提出后&#xff0c;AI 就成为了科技领域重点关注的板块&#xff0c;并引发了一轮又一轮的 AI 投资热潮。在传统科技领域引发的 AI 热潮&#xff0c;正在向加密行业拓展&#xff0c;Web3 领域也涌现出了不少 AIWeb3 概念的项…

单模场哈密顿量推导

满足麦克斯韦方程和边界条件的单模场又下式&#xff08;1&#xff09;&#xff0c;&#xff08;2&#xff09;给出 --------&#xff08;1&#xff09; ---------&#xff08;2&#xff09; , 单模场的经典场能或者哈密顿量又下式给出&#xff1a; &#xff08;3&#xff09…

编译esp32s3的ncnn,并运行mnist 手写数字识别

东哥科技&#xff0c;专注科技研发&#xff0c;wx交流&#xff1a;dg_i688 我的项目代码 https://github.com/cdmstrong/ncnn_on_esp32s3 下载ncnn git clone https://github.com/Tencent/ncnn.git安装idf 环境 这里直接按官网的可执行文件来就好了&#xff0c;直接安装完…

嵌入式Linux 内核的内存管理方法

内存管理的主要工作就是对物理内存进行组织,然后对物理内存的分配和回收。但是Linux引入了虚拟地址的概念。 虚拟地址的作用 如果用户进程直接操作物理地址会有以下的坏处: 1、 用户进程可以直接操作内核对应的内存,破坏内核运行。 2、 用户进程也会破坏其他进程的运行 …

传统电力运维企业的数字化转型案例

一. 传统电力运维企业面临的主要问题 上海某电力集团企业下属有成套设备公司、电力工程公司&#xff0c;依托于自身的设备制造和工程服务能力&#xff0c;以及多年积累的终端客户资源&#xff0c;几年前该公司成立了电力运维服务公司进入用户侧电力托管运维服务行业。 该公司…

【Linux系统编程】进程程序替换

介绍&#xff1a; 进程程序替换是指将一个进程中正在运行的程序替换为另一个全新的程序的过程&#xff0c;但替换不是创建新进程&#xff0c;只是将对应程序的代码和数据进行替换。具体来说&#xff0c;这个替换过程涉及将磁盘中的新程序加载到内存结构中&#xff0c;并重新建立…

Leetcode 31. 删除无效的括号

心路历程&#xff1a; 一开始看到有点懵&#xff0c;后来发现有点像按照一定规则穷举所有可能情况&#xff0c;想到了排列组合问题&#xff0c;再结合问题长度不固定&#xff0c;无法用已知个for循环表示&#xff0c;从而想到了回溯。这个题相当于需要在一定规则下枚举。 按照…

桌面云解决方案

桌面云解决方案是一种基于云计算的服务&#xff0c;它将用户的桌面环境托管在云端&#xff0c;允许用户通过互联网访问自己的虚拟桌面。这种解决方案为企业和个人用户提供了一种灵活、可扩展且成本效益高的桌面计算方式。以下是一些桌面云解决方案的关键特点和优势&#xff1a;…

MusicHiFi: Fast High-Fidelity Stereo Vocoding

文章目录 abstract abstract demo: https://musichifi.github.io/web/主要用于高精度的音乐场景文章主要做了两件事&#xff1a;&#xff08;1&#xff09;低频mel谱输入&#xff0c;生成更高频率的语音&#xff1b;&#xff08;2&#xff09;单声道音频生成立体声&#xff1b…

AI工具快速部署

演示站见文章底部 部署教程 搭建一键整合包&#xff0c;你需要的东西有&#xff1a; 一个最低1h1g的海外服务器 推荐服务器系统为&#xff1a;CentOS-7.9.2111-x64 一份NineAI一件整合包代码 一定的linux指令知识第一步 通过ssh工具连接服务器 同时打开宝塔面板至文件区域 将…

代码随想录算法训练营第二十五天|● 216.组合总和III ● 17.电话号码的字母组合(JS写法)

216 组合总和Ⅲ 题目链接/文章讲解&#xff1a;https://programmercarl.com/0216.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8CIII.html 视频讲解&#xff1a;https://www.bilibili.com/video/BV1wg411873x 方法一&#xff1a;自己写的 自己写的&#xff0c;本题和77很像&#xf…

连号区间数c++

题目 输入样例1&#xff1a; 4 3 2 4 1输出样例1&#xff1a; 7输入样例2&#xff1a; 5 3 4 2 5 1输出样例2&#xff1a; 9样例解释 第一个用例中&#xff0c;有 77 个连号区间分别是&#xff1a;[1,1],[1,2],[1,3],[1,4],[2,2],[3,3],[4,4][1,1],[1,2],[1,3],[1,4],[2,2…

关于Oracle Primavera P6的各数据库帐号用途

在使用/维护P6时&#xff0c;经常会用到各种不同的P6数据库用户&#xff0c;如在连接配置P6 Professional时用到的公共帐号pubuser&#xff0c;进入后台维护p6配置信息(adminpv)或开发常连接的privuser&#xff0c;亦或是配置BI Report/BUSINESS Intelligence报表套件用到的pxr…

Axure 中继器的Item属性介绍及使用

item.列名 获取数据行中指定列的值。 index 获取索引编号&#xff0c;编号起始值为1 isFirst 判断数据是否为第一行 isLast 判断是否为最后一行 isEven 判断是否为偶数行 isOdd 判断是否为奇数行 isMarked 判断行是否被标记 isVisible 改行是否为显示