Android中App与U盘通信的示例分析

这篇文章主要介绍了Android中App与U盘通信的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

创新互联是一家专业提供黄州企业网站建设,专注与成都做网站、网站建设、外贸营销网站建设H5场景定制、小程序制作等业务。10年已为黄州众多企业、政府机构等服务。创新互联专业网站制作公司优惠进行中。

一、自定义广播接收器接收 U 盘相关的信息

在 U 盘插入或插出的时候,系统都会发出一条相关的广播,所以我们需要自定义广播接收器,接收这两条广播,然后进行相应的处理。

public class OtgReceiver extends BroadcastReceiver {
 @Override
 public void onReceive(Context context, Intent intent) {
  String action = intent.getAction();
  switch (action) {
   // 接收到 U 盘插入广播
   case UsbManager.ACTION_USB_DEVICE_ATTACHED:
    showToast(context, "U 盘已插入");
     // 获取相关的 Usb 设备
    UsbDevice attachUsbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
    if (attachUsbDevice != null) {
      // 进行权限申请
     permissionRequest();
    }
    break;
   // 接收到 U 盘拔出广播
   case UsbManager.ACTION_USB_DEVICE_DETACHED:
    showToast(context, "U 盘已拔出");
    break;
   default:
    break;
  }
 }
}

因为 Usb 相关的设备操作,需要申请相关的权限,所以在接收到 U 盘插入的广播之后,我们需要进行权限申请。

private void permissionRequest() {
  // 设备管理器
  UsbManager usbManager = (UsbManager) MainActivity.getContext().get().getSystemService(Context.USB_SERVICE);
  // 获取 U 盘存储设备
  UsbMassStorageDevice[] storageDevices = UsbMassStorageDevice.getMassStorageDevices(OtgApplication.getContext());
  PendingIntent pendingIntent = PendingIntent.getBroadcast(OtgApplication.getContext(), 0, new Intent(ACTION_USB_PERMISSION), 0);
  // 进行权限申请
  usbManager.requestPermission(device.getUsbDevice(), pendingIntent);
 }

可以看到我们在申请权限的时候,传入了一个 PendingIntent,PendingIntent 里面传入我们自定义的广播 ACTION_USB_PERMISSION,等到权限申请完成,便会发出这条广播,然后我们可以在广播接收器中接收并处理,从而进行后续的操作。

case ACTION_USB_PERMISSION:
  UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
  if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
   if (usbDevice != null) {
    // 读取 U 盘相关的信息
    readDevice(getUsbMass(usbDevice));
   } else {
    showToast(context, "没有插入 U 盘");
   }
  } else {
   showToast(context, "未获取到 U 盘权限");
  }
  break;

为了简化相关的代码,我导入 Github 上开源的 libaums ,所以需要在 build.gradle 里面加上

compile 'com.github.mjdev:libaums:0.5.5'

通过接收我们自定义的广播,便可以从 Intent 里面获取相应的包含 U 盘信息的 UsbDevice

private void readDevice(UsbMassStorageDevice device) {
   device.init(); 
   // 设备分区
   Partition partition = device.getPartitions().get(0);
   // 文件系统
   FileSystem currentFs = partition.getFileSystem();
   // 获取 U 盘的根目录
   mRootFolder = currentFs.getRootDirectory();
   // 获取 U 盘的容量
   long capacity = currentFs.getCapacity();
   // 获取 U 盘的剩余容量
   long freeSpace = currentFs.getFreeSpace();
   // 获取 U 盘的标识
   String volumeLabel = currentFs.getVolumeLabel();
 }

二、将文件导入到 U 盘中

通常我们将手机跟 U 盘通过 OTG 线进行连接,都是为了将手机里面的文件导入到 U 盘中,我们就以图片为例子,看看怎样将图片导出到 U 盘中。

将图片导出到 U 盘中,我们可以通过流来实现,先在 U 盘对应的目录,创建新的 jpg/png 格式的文件,然后通过 BitmapFactory 将图片转换成 Bitmap,再进一步拿到对应图片的 ByteArrayOutputStream,最后将对应的字节写入文件中。

public static void savePictureToUsb(String picturePath, UsbFile root) {
  UsbFile newDir = root.createDirectory("Haoz" + System.currentTimeMillis());
  UsbFile file = newDir.createFile("Haoz" + System.currentTimeMillis() + ".jpg");
  Bitmap bitmap = BitmapFactory.decodeFile(picturePath);
  OutputStream outputStream = new UsbFileOutputStream(file);
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
  outputStream.write(out.toByteArray());
  outputStream.flush();
  outputStream.close();
  file.flush();
  file.close();
 }

可以看到我们传入图片的路径以及 U 盘的根目录,便可以将图片写入到 U 盘中,在上一节中,我们已经通过广播拿到 U 盘的根目录,所以直接用就行了。将文件从 U 盘中导入到手机中,其实思路也是一样的。毕竟当 U 盘插入手机的那一刻,将 U 盘当成手机的一个普通的目录来处理就行了。

三、该注意的地方

虽然说,U 盘跟手机之间的通信相对来说不是很难,但其实也有很多需要注意的地方,也是笔者在开发过程中踩过的坑,这里都记录出来,供大家参考。

3.1 获取图片的路径

我们通过图片选择库或者照相机回调出来的,很多时候都是图片的 Uri,而要得到图片对应的 Bitmap 需要的是图片的真实路径,我们可以通过以下方法进行转换。

public static String getPath(ContentResolver resolver, Uri uri) {
  if (uri == null) {
   return null;
  }

  if (SCHEME_CONTENT.equals(uri.getScheme())) {
   Cursor cursor = null;
   try {
    cursor = resolver.query(uri, new String[]{MediaStore.Images.ImageColumns.DATA},
      null, null, null);
    if (cursor == null || !cursor.moveToFirst()) {
     return null;
    }
    return cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA));
   } finally {
    if (cursor != null) {
     cursor.close();
    }
   }
  }
  return uri.getPath();
 }

3.2 文件相关的读写操作

文件相关的读写操作都是比较耗时的,特别是当文件比较大的时候。所以我们不能在主线程中进行文件的读写,必须将其放在子线程中,等 I/O 操作完成了,再转换到主线程中进行操作。

3.3 广播的注册与移除

因为我们是自定义广播接收器来接收相应的广播,所以需要在 Activity 中进行广播的动态注册,将对应 Action 进行过滤。最后不要忘记了在 onDestroy() 中移除广播,防止内存泄露。

private void registerUDiskReceiver() {
  IntentFilter usbDeviceFileter = new IntentFilter();
  usbDeviceFileter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
  usbDeviceFileter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
  usbDeviceFileter.addAction(Intent.ACTION_MEDIA_MOUNTED);
  registerReceiver(mOtgReceiver, usbDeviceFileter);
  // 注册监听自定义广播
  IntentFilter filter = new IntentFilter(OtgReceiver.ACTION_USB_PERMISSION);
  registerReceiver(mOtgReceiver, filter);
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  unregisterReceiver(mOtgReceiver);
 }

感谢你能够认真阅读完这篇文章,希望小编分享的“Android中App与U盘通信的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持创新互联,关注创新互联行业资讯频道,更多相关知识等着你来学习!

网页名称:Android中App与U盘通信的示例分析
网页地址:https://www.cdcxhl.com/article26/ijojjg.html

成都网站建设公司_创新互联,为您提供网站内链定制网站自适应网站服务器托管电子商务营销型网站建设

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

成都网页设计公司