USB设备识别为存储设备并查找路径

时间:2017-01-27 09:06:07

标签: android file file-manager

如何检测可用于存储的已安装设备(如Pen-Drive)?如何找到已安装存储设备的路径,以便从中读取文件?

我使用了以下广播接收器获取访问已安装设备的权限:

private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION_USB_PERMISSION.equals(action)) {
            synchronized (this) {
                UsbDevice device = (UsbDevice) intent
                        .getParcelableExtra(UsbManager.EXTRA_DEVICE);
                if (intent.getBooleanExtra(
                        UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if (device != null) {
                        // call method to set up device communication

                        Log.d(TAG, "onReceive: "+intent.getExtras().toString());
                        Log.d(TAG, "onReceive: "+intent.getData());
                        LinearLayout layoutUsbList = (LinearLayout)findViewById(R.id.layout_usb_list);
                        Button btn = new Button(MainActivity.this);
                        btn.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                        layoutUsbList.addView(btn);
                        btn.setText(device.getDeviceId()+"\t"+device.getDeviceName());
                        Log.d(TAG, "onReceive: "+intent.getExtras().toString());
                        final String path = intent.getData().getPath();
                        Log.e(TAG, "onReceive: path of device received from intent: "+ path );
                        btn.setOnClickListener(new OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                File file = new File(path);
                                Toast.makeText(MainActivity.this, "file exists --> "+file.exists()+"", Toast.LENGTH_SHORT).show();
                                Toast.makeText(MainActivity.this, "file is directory --> "+file.isDirectory()+"", Toast.LENGTH_SHORT).show();
                                Log.d(TAG, "onClick: file is directory --> "+file.isDirectory()+"");
                                try{
                                    Toast.makeText(MainActivity.this, file.listFiles().length+"", Toast.LENGTH_LONG).show();
                                }catch(Exception e){
                                    Toast.makeText(MainActivity.this, "error while showing total items", Toast.LENGTH_SHORT).show();
                                }

                            }
                        });

                    }
                } else {
                    Log.d("ERROR", "permission denied for device " + device);
                }
            }
        }
    }
};

清单文件:

<?xml version="1.0" encoding="utf-8"?>

<uses-feature android:name="android.hardware.usb.host"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:configChanges="keyboard|orientation"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>


        <intent-filter>
            <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
        </intent-filter>

        <meta-data
            android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
            android:resource="@xml/device_filter"/>

        <intent-filter>
            <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"/>
        </intent-filter>


        <!---->
        <!---->
        <!---->
        <intent-filter>
            <action android:name="android.intent.action.MEDIA_MOUNTED"/>
            <data android:scheme="file"/>
        </intent-filter>
    </activity>

</application>

1 个答案:

答案 0 :(得分:1)

根据这个pdf 改编此library。 每个大容量存储设备至少有一个接口描述符,类代码为08h, 它代表大容量存储类。大容量存储类未在设备中定义 描述! USB接口只有两个端点描述符。一个IN端点到 从设备和一个OUT端点读取以写入设备2。读写 在这种情况下,并不一定意味着在实际存储介质上读取或写入, 这将在后面描述。 关于大容量存储类有两种不同的类型。只有大量的 运输(BBB)机制是最常见的机制。所有较新的设备都遵循这一点 标准。然后是控制/批量/中断(CBI)标准,不再是 很重要,因为USB-IF建议使用BBB方法

UsbDevice被认为是massStorage Device If:

usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_MASS_STORAGE
                        || usbInterface.getInterfaceSubclass() == INTERFACE_SUBCLASS // int 6
                        || usbInterface.getInterfaceProtocol() == INTERFACE_PROTOCOL // int 80

usbInterface.getEndpointCount() == 2

,其中 端点之一必须满足以下要求:

endPoint direction == 0
endPoint type = UsbConstants.USB_ENDPOINT_XFER_BULK //int 2