文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android设备与外接U盘实现数据读取操作的示例

2023-05-30 18:08

关注

现在越来越多手机支持OTG功能,通过OTG可以实现与外接入的U盘等USB设备实现数据传输。

 USB OTG(On The Go)作为USB2.0的补充协议,于2001年由USB-IF提出。它提出的背景是移动消费类电子产品的迅猛增加,而之前USB协议的主从协议标准让这些电子产品在离开PC电脑时的数据传输变得艰难,OTG技术正是为了解决这一问题的标准。

Android设备与外接U盘实现数据读取操作的示例

通过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盘进行数据操作。通过大量的找资料,终于实现了项目上需要的功能。找资料主要是解决两个问题:

  1. U盘权限问题
  2. 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

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 资料下载
  • 历年真题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯