Android AppとUディスク通信の詳細

6788 ワード

前言
Uディスクの理解については、多くの人がUディスクとパソコンとの通信段階にとどまるべきだと信じていますが、実際にはOTC線を通じて携帯電話とUディスクの間のデータ操作を実現することができ、Uディスクの中のファイルを携帯電話に読み取るだけでなく、携帯電話の中のファイルをUディスクに導き出し、携帯電話とUディスクの間の通信を実現することができます.本文はAndroidアプリから始め、関連コードを通じて、携帯電話とUディスクの通信を一歩一歩理解します.コードはもうGithubに置いたので、必要なものがあればここをクリックしてください.
一、カスタム放送受信機はUディスク関連の情報を受信する
USBディスクが挿入または挿入されると、システムは関連するブロードキャストを発行するので、ブロードキャスト受信機をカスタマイズし、この2つのブロードキャストを受信し、対応する処理を行う必要があります.
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_パーミッション申請が完了すると、このブロードキャストが発行され、ブロードキャスト受信機で受信して処理することができ、後続の操作を行うことができます.
   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ディスクのルートディレクトリを手に入れたので、直接使えばいいです.ファイルをUSBメモリから携帯電話に導入するのも、実は考え方は同じです.結局、USBメモリが携帯電話に挿入された瞬間、USBメモリを携帯電話の普通のディレクトリとして処理すればいいのです.
三、注意すべき点
USBメモリと携帯電話との通信は相対的に難しくないが、注意すべき点も多く、筆者が開発中に踏んだ穴でもある.
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非常に簡潔で優雅な日記アプリ
  • Androidはあなたを連れて面白いDoodleView(落書き)
  • を描きます
  • Androidは袖を引っ張って、自分でDialogFragment
  • をパッケージします
  • 手を取ってゼロからきれいなアプリを作るように教えてあげます