Android

您所在的位置:网站首页 小米如何读取u盘文件 Android

Android

2024-06-24 16:05| 来源: 网络整理| 查看: 265

Android关于读写U盘文件-操作外置sd卡 一、背景二、可行性分析关于问题1关于问题2关于问题2,我们可以采取四种方式操作:实现效果依赖build.gradle布局文件activity_u.xml权限AndroidManifest.xml一个类UsbActivity 三、参考文章四、DEMO

一、背景

很久以前做过这个功能,一直没有总结。碰巧最近有网友问到,就总结一下。 项目要求实现两个功能: 1、读取U盘里的apk文件并安装 2、导出数据,生成Excel表格到U盘

二、可行性分析 关于问题1

第一个问题很简单,读取U盘里的内容并安装是不需要系统权限的。动态获取到读权限就可以了

关于问题2

我们需要获取到

但是即使我们获取了写入权限,写入的时候,依旧会失败,会提示permission denied。 原因是: Android5.0以上系统已经不支持开发者随便写手机的外部存储(包含tf卡、otg外接u盘等),必须用特定的方法去读写。即5.0以下我们还是可以直接读写的(直接拿到U盘文件路径也可以操作)。

关于问题2,我们可以采取四种方式操作:

1、使用google提供的特定方式,SAF框架操作外置sd卡,关键字DocumentFile. 2、只操作固定的目录:Android/data/包名/…,这里面你可以随便做操作,不过app删了,这些数据也会自动删掉。 3、使用第三方的框架libaums 4、系统签名,成为系统应用

//目前最新版本为0.7.0,但是该版本的兼容库已迁移至androidx implementation 'com.github.mjdev:libaums:0.6.0'

我最后采取的是第四种方式。 但是这个文章主要是为第三种方式提供demo。 注意:当时调研的时候发现libaums这个框架对于nfts格式的U盘读取是有问题的,貌似只支持FAT32。 我没有去研究libaums的源码,并不知道它是如何在没有权限的情况下写入成功的。观测情况是,一旦授予权限,文件管理器是看不到这个U盘的。所以我估计,它可能是把U盘挂载到了其他地方。 以上都是废话,下面是经测可用的demo。

实现效果

把挂载到Android设备的U盘,遍历文件并输出。进行简单的读写操作。 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

依赖build.gradle compile 'com.github.mjdev:libaums:0.5.5' 布局文件activity_u.xml 权限AndroidManifest.xml 一个类UsbActivity package com.example.pc.testeverything.Activity; import android.Manifest; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.widget.TextView; import com.example.pc.testeverything.R; import com.github.mjdev.libaums.UsbMassStorageDevice; import com.github.mjdev.libaums.fs.FileSystem; import com.github.mjdev.libaums.fs.UsbFile; import com.github.mjdev.libaums.fs.UsbFileStreamFactory; import com.github.mjdev.libaums.partition.Partition; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.Locale; import static android.hardware.usb.UsbManager.ACTION_USB_DEVICE_ATTACHED; import static android.hardware.usb.UsbManager.ACTION_USB_DEVICE_DETACHED; /** * 写了一个简单测试 * * @author Rachel */ public class UsbActivity extends AppCompatActivity { private static final String TAG = "Rachel_test"; private static final String ACTION_USB_PERMISSION = "com.demo.otgusb.USB_PERMISSION"; private UsbMassStorageDevice[] storageDevices; private TextView logTv; /** * 监听USB设备的广播 */ BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String intentAction = intent.getAction(); UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); switch (intentAction) { case ACTION_USB_PERMISSION: //自定义Action if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { logShow("用户同意USB设备访问权限"); readDevice(getUsbMass(device)); } else { logShow("用户拒绝USB设备访问权限"); } break; case ACTION_USB_DEVICE_ATTACHED: logShow("U盘设备插入"); if (device != null) { redUDiskDeviceList(); } break; case ACTION_USB_DEVICE_DETACHED: logShow("U盘设备移除"); break; default: Log.i(TAG, "----------------------------------"); } } }; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_u); logTv = (TextView) findViewById(R.id.log_tv); init(); } /** * 动态申请读写权限 */ private void init() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 111); } registerUsbReceiver(); redUDiskDeviceList(); } /** * 权限申请回调 * * @param requestCode 标识码 */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 111) { registerUsbReceiver(); redUDiskDeviceList(); } } /** * 动态注册监听USB设备的广播。 * 由于耗电等原因,8.0不能对大部分的广播进行静态注册 */ private void registerUsbReceiver() { IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); filter.addAction("android.hardware.usb.action.USB_STATE"); filter.addAction("android.hardware.usb.action.USB_DEVICE_ATTACHED"); filter.addAction("android.hardware.usb.action.USB_DEVICE_DETACHED"); registerReceiver(mUsbReceiver, filter); } /** * 获取存储设备 * * @param usbDevice 与android设备连接在一起的USB设备 * @return Usb设备的一个包装类 */ private UsbMassStorageDevice getUsbMass(UsbDevice usbDevice) { for (UsbMassStorageDevice device : storageDevices) { if (usbDevice.equals(device.getUsbDevice())) { return device; } } return null; } /** * 初始化USB设备 * * @param device USB设备 */ private void readDevice(UsbMassStorageDevice device) { try { device.init();//初始化 //设备分区 Partition partition = device.getPartitions().get(0); //文件系统 FileSystem currentFs = partition.getFileSystem(); //可以获取到设备的标识 currentFs.getVolumeLabel(); //通过FileSystem可以获取当前U盘的一些存储信息,包括剩余空间大小,容量等等 Log.e("Volume Label: ", currentFs.getVolumeLabel()); Log.e("Capacity: ", fSize(currentFs.getCapacity())); Log.e("Occupied Space: ", fSize(currentFs.getOccupiedSpace())); Log.e("Free Space: ", fSize(currentFs.getFreeSpace())); Log.e("Chunk size: ", fSize(currentFs.getChunkSize())); readAndWriteTest(currentFs); } catch (Exception e) { e.printStackTrace(); } } /** * USB设备读取 */ private void redUDiskDeviceList() { Context context = this; //设备管理器 UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); //获取U盘存储设备 storageDevices = UsbMassStorageDevice.getMassStorageDevices(context); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0); //一般手机只有1个OTG插口 if (storageDevices.length


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3