Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
122 views
in Technique[技术] by (71.8m points)

android - USBdevice recognise as storage device and find path

How can I detect a mounted device such as a Pen-Drive, that can be used for storage? How can I find the path for the mounted storage device so I may read files from it?

I've used following broadcast receiver taking the permission to access mounted device:

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()+""+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);
                }
            }
        }
    }
};

Manifest file:

<?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>

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Accordig to this pdf refrencing this library. Every mass storage device has at least one interface descriptor with the class code 08h, which stands for the mass storage class. The mass storage class is not defined in the device descriptor! The USB interface has exactly two endpoint descriptors. One IN endpoint to read from the device and one OUT endpoint to write to the device2. Reading and writing in this case does not necessarily mean reading or writing on the actual storage medium, this is described later. There are two different types regarding the mass storage class. There is the bulk-only transport (BBB) mechanism which is the most common one. All newer devices follow that standard. Then there is the Control/Bulk/Interrupt (CBI) standard which is no longer important, because the USB-IF recommends using the BBB approach

UsbDevice is recognized as massStorage Device If:

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

and

usbInterface.getEndpointCount() == 2

where one of endpoint must satisfy following:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...