Android App 与 U 盘通信示例详解

Android App 与 U 盘通信示例详解,第1张

概述前言对于U盘的了解,相信大多数人应该只停留在跟U盘跟电脑通信的阶段,其实现在通过OTG线就可以实现手机跟U盘之间的数据 *** 作,不仅可以将U盘中的文件读取到手机中来,还能将手机中的文件导出到U盘中,从而实现手机与

前言

对于 U 盘的了解,相信大多数人应该只停留在跟 U 盘跟电脑通信的阶段,其实现在通过OTG 线就可以实现手机跟 U 盘之间的数据 *** 作,不仅可以将 U 盘中的文件读取到手机中来,还能将手机中的文件导出到 U 盘中,从而实现手机与 U 盘之间的通信。本文将从 AndroID App 入手,通过相关的代码,带大家一步步了解手机与 U 盘之间的通信。代码我已经放上 Github 了,有需要的点击这里 。

一、自定义广播接收器接收 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(),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);    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 盘通信示例详解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1143119.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存