將手機中的文件復(fù)制到u盤中,需要u盤讀取權(quán)限和文件讀寫權(quán)限
1.添加權(quán)限
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
2.添加第三方依賴庫
implementation 'com.github.mjdev:libaums:0.5.5'
3.編寫界面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android盒子外接U盤文件讀寫測試DEMO"
android:layout_gravity="center"
android:layout_margin="10dp"
/>
<EditText
android:id="@+id/u_disk_edt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:hint="輸入要保存到U盤中的文字內(nèi)容"/>
<Button
android:id="@+id/u_disk_write"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:text="往U盤中寫入數(shù)據(jù)"/>
<Button
android:id="@+id/u_disk_read"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:text="從U盤中讀取數(shù)據(jù)"/>
<TextView
android:id="@+id/u_disk_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
/>
</LinearLayout>
4.在activity中編寫功能
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//輸入的內(nèi)容
private EditText u_disk_edt;
//寫入到U盤
private Button u_disk_write;
//從U盤讀取
private Button u_disk_read;
//顯示讀取的內(nèi)容
private TextView u_disk_show;
//自定義U盤讀寫權(quán)限
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
//當(dāng)前處接U盤列表
private UsbMassStorageDevice[] storageDevices;
//當(dāng)前U盤所在文件目錄
private UsbFile cFolder;
private final static String U_DISK_FILE_NAME = "u_disk.txt";
@SuppressLint("HandlerLeak")
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("讀取到的數(shù)據(jù)是:" + txt);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
initViews();
registerUDiskReceiver();
}
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);
}
}
}
}
/**
* @description 保存數(shù)據(jù)到U盤,目前是保存到根目錄的
* @author ldm
* @time 2017/9/1 17:17
*/
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);
}
}
/**
* @description OTG廣播注冊
* @author ldm
* @time 2017/9/1 17:19
*/
private void registerUDiskReceiver() {
//監(jiān)聽otg插入 拔出
IntentFilter usbDeviceStateFilter = new IntentFilter();
usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(mOtgReceiver, usbDeviceStateFilter);
//注冊監(jiān)聽自定義廣播
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mOtgReceiver, filter);
}
/**
* @description OTG廣播,監(jiān)聽U盤的插入及拔出
* @author ldm
* @time 2017/9/1 17:20
* @param
*/
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);
//允許權(quán)限申請
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (usbDevice != null) {
//用戶已授權(quán),可以進(jìn)行讀取操作
readDevice(getUsbMass(usbDevice));
} else {
showToastMsg("沒有插入U盤");
}
} else {
showToastMsg("未獲取到U盤權(quán)限");
}
break;
case UsbManager.ACTION_USB_DEVICE_ATTACHED://接收到U盤設(shè)備插入廣播
UsbDevice device_add = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device_add != null) {
//接收到U盤插入廣播,嘗試讀取U盤設(shè)備數(shù)據(jù)
redUDiskDevsList();
}
break;
case UsbManager.ACTION_USB_DEVICE_DETACHED://接收到U盤設(shè)設(shè)備拔出廣播
showToastMsg("U盤已拔出");
break;
}
}
};
/**
* @description U盤設(shè)備讀取
* @author ldm
* @time 2017/9/1 17:20
*/
private void redUDiskDevsList() {
//設(shè)備管理器
UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
//獲取U盤存儲設(shè)備
storageDevices = UsbMassStorageDevice.getMassStorageDevices(this);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
//一般手機只有1個OTG插口
for (UsbMassStorageDevice device : storageDevices) {
//讀取設(shè)備是否有權(quán)限
if (usbManager.hasPermission(device.getUsbDevice())) {
readDevice(device);
} else {
//沒有權(quán)限,進(jìn)行申請
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();//初始化
//設(shè)備分區(qū)
Partition partition = device.getPartitions().get(0);
//文件系統(tǒng)
FileSystem currentFs = partition.getFileSystem();
currentFs.getVolumeLabel();//可以獲取到設(shè)備的標(biāo)識
//通過FileSystem可以獲取當(dāng)前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();//設(shè)置當(dāng)前文件對象為根目錄
} 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;
//讀取文件內(nèi)容
InputStream is = new UsbFileInputStream(descFile);
//讀取秘鑰中的數(shù)據(jù)進(jìn)行匹配
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();
}
}
}
}
5.添加文件處理工具類
public class FileUtil {
public static final String DEFAULT_BIN_DIR = "usb";
/**
* 檢測SD卡是否存在
*/
public static boolean checkSDcard() {
return Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState());
}
/**
* 從指定文件夾獲取文件
*
* @return 如果文件不存在則創(chuàng)建, 如果如果無法創(chuàng)建文件或文件名為空則返回null
*/
public static File getSaveFile(String folderPath, String fileNmae) {
File file = new File(getSavePath(folderPath) + File.separator
+ fileNmae);
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
/**
* 獲取SD卡下指定文件夾的絕對路徑
*
* @return 返回SD卡下的指定文件夾的絕對路徑
*/
public static String getSavePath(String folderName) {
return getSaveFolder(folderName).getAbsolutePath();
}
/**
* 獲取文件夾對象
*
* @return 返回SD卡下的指定文件夾對象,若文件夾不存在則創(chuàng)建
*/
public static File getSaveFolder(String folderName) {
File file = new File(getExternalStorageDirectory()
.getAbsoluteFile()
+ File.separator
+ folderName
+ File.separator);
file.mkdirs();
return file;
}
/**
* 關(guān)閉流
*/
public static void closeIO(Closeable... closeables) {
if (null == closeables || closeables.length <= 0) {
return;
}
for (Closeable cb : closeables) {
try {
if (null == cb) {
continue;
}
cb.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void redFileStream(OutputStream os, InputStream is) throws IOException {
int bytesRead = 0;
byte[] buffer = new byte[1024 * 8];
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.flush();
os.close();
is.close();
}
/**
* @description 把本地文件寫入到U盤中
* @author ldm
* @time 2017/8/22 10:22
*/
public static void saveSDFile2OTG(final File f, final UsbFile usbFile) {
UsbFile uFile = null;
FileInputStream fis = null;
try {//開始寫入
fis = new FileInputStream(f);//讀取選擇的文件的
if (usbFile.isDirectory()) {//如果選擇是個文件夾
UsbFile[] usbFiles = usbFile.listFiles();
if (usbFiles != null && usbFiles.length > 0) {
for (UsbFile file : usbFiles) {
if (file.getName().equals(f.getName())) {
file.delete();
}
}
}
uFile = usbFile.createFile(f.getName());
UsbFileOutputStream uos = new UsbFileOutputStream(uFile);
try {
redFileStream(uos, fis);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (final Exception e) {
e.printStackTrace();
}
}
}