通过Android USB主机模式从笔式驱动器读取数据

时间:2012-10-15 12:17:48

标签: android usb-drive usb-mass-storage usb-otg

我需要从笔式驱动器读取文件,我的代码如下:

private static final String ACTION_USB_PERMISSION = "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";

private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
    @Override
    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
                    }
                } else {
                    Log.d(TAG, "permission denied for device " + device);
                }
            }
        }
    }
};

要检测我使用的设备:

mgr = (UsbManager) getSystemService(Context.USB_SERVICE);
devs = new HashMap<String, UsbDevice>();
devs = mgr.getDeviceList();

获得设备和接口后,我得到如下端点:

public void getEndpointCount(View v) {
    itf = value.getInterface(0);
    endPointCount = itf.getEndpointCount();

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("No. of Endpoints: " + endPointCount)
            .setTitle("Endpoint Count").setCancelable(true)
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }
            });
    AlertDialog alert = builder.create();
    alert.show();
    ((Button) findViewById(R.id.button4)).setEnabled(true);
}

public void getEndpointDirections(View v) {
    endPoint = null;


    UsbDeviceConnection conn = null;

    if (mgr.hasPermission(value)) {
        conn = mgr.openDevice(value);
        conn.claimInterface(itf, true);
    }

    String str = null;
    for (int i = 0; i < endPointCount; i++) {
        ((TextView) findViewById(R.id.tvLoopVal)).setText("" + i);
        endPoint = itf.getEndpoint(i);
        str = str + " Endpoint: " + i + " - " + endPoint.getDirection()
                + "\n";

if (endPoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
            ((TextView) findViewById(R.id.tvLoopVal)).setText("" + (i - 1));
            if (endPoint.getDirection() == UsbConstants.USB_DIR_IN) {
                Toast.makeText(this, "epin", Toast.LENGTH_SHORT).show();
                epIn = endPoint;
            } else {
                epOut = endPoint;
                Toast.makeText(this, "epout", Toast.LENGTH_SHORT).show();
            }
        }

    }

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage(
            str + " Mac packet Size = " + endPointUsed.getMaxPacketSize())
            .setTitle("Endpoints Directions").setCancelable(true)
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }
            });
    AlertDialog alert = builder.create();
    alert.show();

}

最后,我得到了端点,现在我被困住了,下一步是将数据读取或写入pendrive。我对此一无所知,需要指导现在的目标。

此外,如果我没有将任何USB设备连接到我的平板电脑上,它仍然会找到1个设备,当我通过OTG电缆连接pendrive时,它说2个设备找到!!这也很奇怪

编辑:

我也使用USB请求方法初始化了请求,但我仍然没有得到它的工作原理

public void initializeRequest(View v) {
    UsbRequest uReq = new UsbRequest();
    Toast.makeText(this, "" + uReq.initialize(conn, epIn),
            Toast.LENGTH_SHORT).show();
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage(
            " Is Request Initialized: = " + uReq.initialize(conn, epIn))
            .setTitle("Request Initialization").setCancelable(true)
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }
            });
    AlertDialog alert = builder.create();
    alert.show();
    byte[] bb = new String("Hello").getBytes();
    ByteBuffer bBuffer = ByteBuffer.allocate(5);
    // bBuffer.put(bb);
    uReq.queue(bBuffer, 5);

    UsbRequest request = conn.requestWait();
    // Object obj = uReq.getClientData();
    // Log.v("Client Data", "" + obj.toString());
    if (request != null) {
        Toast.makeText(this, "Not null request", Toast.LENGTH_SHORT).show();
        Log.v("Response of request wait", ""
                + request.getClientData().toString());
        request.close();
    }
    uReq.close();

    // Log.v("Response of request wait", "" + conn.requestWait());
    // uReq.close();
}

我验证了端点正在被分配,但是当这个方法被执行时,应用程序只是等待,什么都不做。一段时间后Android要求关闭应用程序。 是因为requestWait()函数应用程序等待某种类型的事件?

修改

好吧,如果我们忘记从笔式驱动器读取并且只需要从USB设备获取音频流,那么就说麦克风在哪里我什么都不读,我会抓住麦克风会给出的任何东西,然后我还是要做那么我在这里做了什么?

2 个答案:

答案 0 :(得分:1)

看起来你实际上并没有阅读任何数据。如果您有从设备到主机的EndPoint,您应该能够使用bulkTransfer方法从中读取数据。

我对低级USB通信并不熟悉,但我认为您需要自己处理文件系统解析。如果您读取驱动器上的第一个扇区(512字节),并且该扇区的最后两个字节是0x55,0xAA,则驱动器可能使用FAT文件系统格式化,您必须从那里开始工作。

答案 1 :(得分:0)

由于没有接受答案,我会发布我的。

有一个名为libaums的开源库,它为Android和Fat32文件系统实现了usb海量存储模式(UMS)。您可以在Android应用程序中使用此库来读取/写入USB设备中的文件。该库处理与USB设备的低级通信..

https://github.com/magnusja/libaums

基本示例:

UsbMassStorageDevice[] devices = UsbMassStorageDevice.getMassStorageDevices(this /* Context or Activity */);

for(UsbMassStorageDevice device: devices) {

   // before interacting with a device you need to call init()!
   device.init();

   // Only uses the first partition on the device
   FileSystem currentFs = device.getPartitions().get(0).getFileSystem();
   Log.d(TAG, "Capacity: " + currentFs.getCapacity());
   Log.d(TAG, "Occupied Space: " + currentFs.getOccupiedSpace());
   Log.d(TAG, "Free Space: " + currentFs.getFreeSpace());
   Log.d(TAG, "Chunk size: " + currentFs.getChunkSize());
}