您好,登錄后才能下訂單哦!
這篇文章主要介紹了Android中App與U盤通信的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
一、自定義廣播接收器接收 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盤通信的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。