
现在越来越多手机支持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盘文件路径及文件 *** 作废话不多说,感觉还是喜欢直接上代码才爽快。项目中用到了一个开源框架,开源地址是:
https://github.com/magnusja/libaums。
代码部分:
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,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,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"/>
时间关系,就不贴图了,欢迎指导交流。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android设备与外接U盘实现数据读取 *** 作的示例全部内容,希望文章能够帮你解决Android设备与外接U盘实现数据读取 *** 作的示例所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)