现在越来越多手机支持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); } } } } 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); } } 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); } 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; } } }; 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(); } } }}
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
软考中级精品资料免费领
- 历年真题答案解析
- 备考技巧名师总结
- 高频考点精准押题
- 资料下载
- 历年真题
193.9 KB下载数265
191.63 KB下载数245
143.91 KB下载数1148
183.71 KB下载数642
644.84 KB下载数2756