Android设备与外接U盘实现数据读取操作的示例
程序员文章站
2023-01-01 17:12:21
现在越来越多手机支持otg功能,通过otg可以实现与外接入的u盘等usb设备实现数据传输。
usb otg(on the go)作为usb2.0的补充协议,于...
现在越来越多手机支持otg功能,通过otg可以实现与外接入的u盘等usb设备实现数据传输。
usb otg(on the go)作为usb2.0的补充协议,于2001年由usb-if提出。它提出的背景是移动消费类电子产品的迅猛增加,而之前usb协议的主从协议标准让这些电子产品在离开pc电脑时的数据传输变得艰难,otg技术正是为了解决这一问题的标准。
通过otg技术实现设备间端到端互联
otg协议规定连接时默认情况作为host的设备为a设备,a设备负责为总线供电;默认作为device的设备为b设备(usb otg标准在完全兼容usb2.0标准的基础上,增加了一个id pin;id拉低为默认a设备);而有些设备由于集成了host控制器和device控制器,既可以作a设备又可以做b设备,称为dura-role device。
最近项目上用到了该功能,项目上用的是安卓7.1的盒子,要实现与插入的u盘进行数据操作。通过大量的找资料,终于实现了项目上需要的功能。找资料主要是解决两个问题:
- u盘权限问题
- u盘文件路径及文件操作
废话不多说,感觉还是喜欢直接上代码才爽快。项目中用到了一个开源框架,开源地址是:
。
代码部分:
public class mainactivity extends appcompatactivity implements view.onclicklistener { //输入的内容 private edittext u_disk_edt; //写入到u盘 private button u_disk_write; //从u盘读取 private button u_disk_read; //显示读取的内容 private textview u_disk_show; //自定义u盘读写权限 private static final string action_usb_permission = "com.android.example.usb_permission"; //当前处接u盘列表 private usbmassstoragedevice[] storagedevices; //当前u盘所在文件目录 private usbfile cfolder; private final static string u_disk_file_name = "u_disk.txt"; private handler mhandler = new handler() { @override public void handlemessage(message msg) { switch (msg.what) { case 100: showtoastmsg("保存成功"); break; case 101: string txt = msg.obj.tostring(); if (!textutils.isempty(txt)) u_disk_show.settext("读取到的数据是:" + txt); break; } } }; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); initviews(); } private void initviews() { u_disk_edt = (edittext) findviewbyid(r.id.u_disk_edt); u_disk_write = (button) findviewbyid(r.id.u_disk_write); u_disk_read = (button) findviewbyid(r.id.u_disk_read); u_disk_show = (textview) findviewbyid(r.id.u_disk_show); u_disk_write.setonclicklistener(this); u_disk_read.setonclicklistener(this); } @override public void onclick(view view) { switch (view.getid()) { case r.id.u_disk_write: final string content = u_disk_edt.gettext().tostring().trim(); mhandler.post(new runnable() { @override public void run() { savetext2udisk(content); } }); break; case r.id.u_disk_read: mhandler.post(new runnable() { @override public void run() { readfromudisk(); } }); break; } } private void readfromudisk() { usbfile[] usbfiles = new usbfile[0]; try { usbfiles = cfolder.listfiles(); } catch (ioexception e) { e.printstacktrace(); } if (null != usbfiles && usbfiles.length > 0) { for (usbfile usbfile : usbfiles) { if (usbfile.getname().equals(u_disk_file_name)) { readtxtfromudisk(usbfile); } } } } /** * @description 保存数据到u盘,目前是保存到根目录的 * @author ldm * @time 2017/9/1 17:17 */ private void savetext2udisk(string content) { //项目中也把文件保存在了sd卡,其实可以直接把文本读取到u盘指定文件 file file = fileutil.getsavefile(getpackagename() + file.separator + fileutil.default_bin_dir, u_disk_file_name); try { filewriter fw = new filewriter(file); fw.write(content); fw.close(); } catch (ioexception e) { e.printstacktrace(); } if (null != cfolder) { fileutil.savesdfile2otg(file, cfolder); mhandler.sendemptymessage(100); } } /** * @description otg广播注册 * @author ldm * @time 2017/9/1 17:19 */ private void registerudiskreceiver() { //监听otg插入 拔出 intentfilter usbdevicestatefilter = new intentfilter(); usbdevicestatefilter.addaction(usbmanager.action_usb_device_attached); usbdevicestatefilter.addaction(usbmanager.action_usb_device_detached); registerreceiver(motgreceiver, usbdevicestatefilter); //注册监听自定义广播 intentfilter filter = new intentfilter(action_usb_permission); registerreceiver(motgreceiver, filter); } /** * @description otg广播,监听u盘的插入及拔出 * @author ldm * @time 2017/9/1 17:20 * @param */ private broadcastreceiver motgreceiver = new broadcastreceiver() { public void onreceive(context context, intent intent) { string action = intent.getaction(); switch (action) { case action_usb_permission://接受到自定义广播 usbdevice usbdevice = intent.getparcelableextra(usbmanager.extra_device); //允许权限申请 if (intent.getbooleanextra(usbmanager.extra_permission_granted, false)) { if (usbdevice != null) { //用户已授权,可以进行读取操作 readdevice(getusbmass(usbdevice)); } else { showtoastmsg("没有插入u盘"); } } else { showtoastmsg("未获取到u盘权限"); } break; case usbmanager.action_usb_device_attached://接收到u盘设备插入广播 usbdevice device_add = intent.getparcelableextra(usbmanager.extra_device); if (device_add != null) { //接收到u盘插入广播,尝试读取u盘设备数据 redudiskdevslist(); } break; case usbmanager.action_usb_device_detached://接收到u盘设设备拔出广播 showtoastmsg("u盘已拔出"); break; } } }; /** * @description u盘设备读取 * @author ldm * @time 2017/9/1 17:20 */ private void redudiskdevslist() { //设备管理器 usbmanager usbmanager = (usbmanager) getsystemservice(context.usb_service); //获取u盘存储设备 storagedevices = usbmassstoragedevice.getmassstoragedevices(this); pendingintent pendingintent = pendingintent.getbroadcast(this, 0, new intent(action_usb_permission), 0); //一般手机只有1个otg插口 for (usbmassstoragedevice device : storagedevices) { //读取设备是否有权限 if (usbmanager.haspermission(device.getusbdevice())) { readdevice(device); } else { //没有权限,进行申请 usbmanager.requestpermission(device.getusbdevice(), pendingintent); } } if (storagedevices.length == 0) { showtoastmsg("请插入可用的u盘"); } } private usbmassstoragedevice getusbmass(usbdevice usbdevice) { for (usbmassstoragedevice device : storagedevices) { if (usbdevice.equals(device.getusbdevice())) { return device; } } return null; } private void readdevice(usbmassstoragedevice device) { try { device.init();//初始化 //设备分区 partition partition = device.getpartitions().get(0); //文件系统 filesystem currentfs = partition.getfilesystem(); currentfs.getvolumelabel();//可以获取到设备的标识 //通过filesystem可以获取当前u盘的一些存储信息,包括剩余空间大小,容量等等 log.e("capacity: ", currentfs.getcapacity() + ""); log.e("occupied space: ", currentfs.getoccupiedspace() + ""); log.e("free space: ", currentfs.getfreespace() + ""); log.e("chunk size: ", currentfs.getchunksize() + ""); cfolder = currentfs.getrootdirectory();//设置当前文件对象为根目录 } catch (exception e) { e.printstacktrace(); } } private void showtoastmsg(string msg) { toast.maketext(this, msg, toast.length_short).show(); } private void readtxtfromudisk(usbfile usbfile) { usbfile descfile = usbfile; //读取文件内容 inputstream is = new usbfileinputstream(descfile); //读取秘钥中的数据进行匹配 stringbuilder sb = new stringbuilder(); bufferedreader bufferedreader = null; try { bufferedreader = new bufferedreader(new inputstreamreader(is)); string read; while ((read = bufferedreader.readline()) != null) { sb.append(read); } message msg = mhandler.obtainmessage(); msg.what = 101; msg.obj = read; mhandler.sendmessage(msg); } catch (exception e) { e.printstacktrace(); } finally { try { if (bufferedreader != null) { bufferedreader.close(); } } catch (ioexception e) { e.printstacktrace(); } } } }
对应布局文件:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.ldm.androidudisk.mainactivity" android:orientation="vertical"> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android盒子外接u盘文件读写测试demo" android:layout_gravity="center" android:layout_margin="10dp" /> <edittext android:id="@+id/u_disk_edt" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:hint="输入要保存到u盘中的文字内容"/> <button android:id="@+id/u_disk_write" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:gravity="center" android:text="往u盘中写入数据"/> <button android:id="@+id/u_disk_read" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:gravity="center" android:text="从u盘中读取数据"/> <textview android:id="@+id/u_disk_show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginleft="10dp" /> </linearlayout>
文件操作工具类:
package com.ldm.androidudisk.utils; import android.os.environment; import com.github.mjdev.libaums.fs.usbfile; import com.github.mjdev.libaums.fs.usbfileoutputstream; import java.io.closeable; import java.io.file; import java.io.fileinputstream; import java.io.ioexception; import java.io.inputstream; import java.io.outputstream; import static android.os.environment.getexternalstoragedirectory; /** * 文件操作工具类 * * @author ldm * @description: * @date 2016-4-28 下午3:17:10 */ public final class fileutil { public static final string default_bin_dir = "usb"; /** * 检测sd卡是否存在 */ public static boolean checksdcard() { return environment.media_mounted.equals(environment .getexternalstoragestate()); } /** * 从指定文件夹获取文件 * * @return 如果文件不存在则创建, 如果如果无法创建文件或文件名为空则返回null */ public static file getsavefile(string folderpath, string filenmae) { file file = new file(getsavepath(folderpath) + file.separator + filenmae); try { file.createnewfile(); } catch (ioexception e) { e.printstacktrace(); } return file; } /** * 获取sd卡下指定文件夹的绝对路径 * * @return 返回sd卡下的指定文件夹的绝对路径 */ public static string getsavepath(string foldername) { return getsavefolder(foldername).getabsolutepath(); } /** * 获取文件夹对象 * * @return 返回sd卡下的指定文件夹对象,若文件夹不存在则创建 */ public static file getsavefolder(string foldername) { file file = new file(getexternalstoragedirectory() .getabsolutefile() + file.separator + foldername + file.separator); file.mkdirs(); return file; } /** * 关闭流 */ public static void closeio(closeable... closeables) { if (null == closeables || closeables.length <= 0) { return; } for (closeable cb : closeables) { try { if (null == cb) { continue; } cb.close(); } catch (ioexception e) { e.printstacktrace(); } } } private static void redfilestream(outputstream os, inputstream is) throws ioexception { int bytesread = 0; byte[] buffer = new byte[1024 * 8]; while ((bytesread = is.read(buffer)) != -1) { os.write(buffer, 0, bytesread); } os.flush(); os.close(); is.close(); } /** * @description 把本地文件写入到u盘中 * @author ldm * @time 2017/8/22 10:22 */ public static void savesdfile2otg(final file f, final usbfile usbfile) { usbfile ufile = null; fileinputstream fis = null; try {//开始写入 fis = new fileinputstream(f);//读取选择的文件的 if (usbfile.isdirectory()) {//如果选择是个文件夹 usbfile[] usbfiles = usbfile.listfiles(); if (usbfiles != null && usbfiles.length > 0) { for (usbfile file : usbfiles) { if (file.getname().equals(f.getname())) { file.delete(); } } } ufile = usbfile.createfile(f.getname()); usbfileoutputstream uos = new usbfileoutputstream(ufile); try { redfilestream(uos, fis); } catch (ioexception e) { e.printstacktrace(); } } } catch (final exception e) { e.printstacktrace(); } } }
不要忘记在app/build.grade下添加:
compile 'com.github.mjdev:libaums:0.5.5'
及androidmanifest.xml中添加权限:
<uses-permission android:name="android.permission.mount_unmount_filesystems"/> <uses-permission android:name="android.permission.read_external_storage"/>
时间关系,就不贴图了,欢迎指导交流。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。