在 USB 主机模式下将数据从 android 发送到连接的 USB 存储设备

Send data from android to connected Usb storage device in Usb Host Mode

在我的应用程序中,我使用的是 USB 主机模式,它提供有关连接的 USB 大容量存储设备的信息 Usb Flash Drive 在我的使用中 case.Now 我需要在连接的闪存驱动器上创建一个文件并保存文件中的一些数据。到目前为止,我发现正在连接到如下设备,

MainActivity.java

public class MainActivity extends AppCompatActivity {

        private static final String TAG = MainActivity.class.getSimpleName();
        private Button mCheckForDevice;
        private TextView mDeviceInfo;
        private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
        private PendingIntent mPermissionIntent;
        private UsbManager mUsbManager;
        private UsbDevice mDeviceFound;
        private UsbDeviceConnection mConnection;
        private UsbInterface mUsbInterface = null;
        private UsbEndpoint mInputEndpoint = null;
        private UsbEndpoint mOutputEndpoint = null;

        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mCheckForDevice = (Button) findViewById(R.id.check);
            mDeviceInfo = (TextView) findViewById(R.id.deviceInfo);
            count=0;

            mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
            mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);

            final HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
            Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
            IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
            registerReceiver(mUsbReceiver, filter);


            while (deviceIterator.hasNext()) {
                final UsbDevice device = deviceIterator.next();
                mDeviceFound = device;
                i += "\n" +
                        "DeviceID: " + device.getDeviceId() + "\n" +
                        "DeviceName: " + device.getDeviceName() + "\n" +
                        "VendorID: " + device.getVendorId() + "\n" +
                        "ProductID: " + device.getProductId() + "\n" +
                        "Serial Number: " + device.getSerialNumber() + "\n";
            }
            mCheckForDevice.setOnClickListener(new View.OnClickListener() {
                @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
                @Override
                public void onClick(View v) {
                    if(deviceList.size() > 0){
                        checkInfo(mDeviceFound);
                    }else{
                        Toast.makeText(getApplicationContext(), "No device found", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
        String i = "";
        private int count ;
        private void checkInfo(UsbDevice device) {
            count++;
            if(count == 1) {
                mUsbManager.requestPermission(device, mPermissionIntent);
                mDeviceInfo.setText(i);

            } else
                Toast.makeText(this, "Already connected", Toast.LENGTH_SHORT).show();
        }

        @Override
        protected void onPause() {
            super.onPause();
            count=0;
            try {
                unregisterReceiver(mUsbReceiver);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
//            Toast.makeText(context, "onReceive", Toast.LENGTH_SHORT).show(); writeToFile("onReceive");
                if (ACTION_USB_PERMISSION.equals(action)) {
                    synchronized (this) {
                        UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                        if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                            Toast.makeText(context, "Permission Granted", Toast.LENGTH_SHORT).show();
                            connectUsb(device);
                        } else {
                            Log.d(TAG, "permission denied for device " + device);
                            Toast.makeText(context, "permission denied for device" + device, Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            }
        };


        private void connectUsb(UsbDevice device) {
            if(device != null){
                for(int i=0;i<device.getInterfaceCount();i++){
                    mUsbInterface = device.getInterface(i);
                    UsbEndpoint tOut = null;
                    UsbEndpoint tIn = null;
                    int usbEndPointCount = mUsbInterface.getEndpointCount();
                    if(usbEndPointCount >=2){
                        for(int j =0;j<usbEndPointCount;j++){
                            if(mUsbInterface.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK){
                                if(mUsbInterface.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_OUT){
                                    tOut = mUsbInterface.getEndpoint(j);
                                }else if(mUsbInterface.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_IN){
                                    tIn = mUsbInterface.getEndpoint(j);
                                }
                            }
                        }
                        if(tIn!=null & tOut !=null){
                            mInputEndpoint = tIn;
                            mOutputEndpoint = tOut;
                        }
                    }
                }
                mConnection = mUsbManager.openDevice(device);
                if (mConnection.claimInterface(mUsbInterface, true)) {
                    Toast.makeText(this, "Connected to device", Toast.LENGTH_SHORT).show();

                    String msg = "Hello world";
                    byte[] byteArray = msg.getBytes();
                    int dataTransfered = mConnection.bulkTransfer(mOutputEndpoint,byteArray,byteArray.length, 0);

                    int controlTransfer = mConnection.controlTransfer( UsbConstants.USB_DIR_OUT, 1,0,0,byteArray,byteArray.length,0);
                    Toast.makeText(this, "controlTransfer " +controlTransfer, Toast.LENGTH_SHORT).show();

                } else {
                    Log.i(TAG, "Could not connect!");
                    Toast.makeText(this, "Could not connect", Toast.LENGTH_SHORT).show();
                }
            }else{
                Toast.makeText(this, "Null", Toast.LENGTH_SHORT).show();
            }
        }

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <Button
        android:id="@+id/check"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Search for devices "
        android:textColor="@color/black"
        android:textSize="15sp" />

    <TextView
        android:id="@+id/deviceInfo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/check"
        android:layout_marginTop="14dp"
        android:textColor="@color/black"
        android:textSize="15sp" />
</RelativeLayout>

在上面的示例中,我尝试将 String 值发送到连接的设备,返回的 int 值是发送的字符数。但是这些信息存储在连接设备上的什么位置?

是否可以在与设备建立连接后在连接的设备上创建文件?指向相关博客文章的链接很有帮助。

我在堆栈上找到 this,但解决方案没有任何帮助。

任何帮助都是appreciated.Thanks。

您正在搜索批量端点,这意味着您正在尝试使用 BBB 扇区 read/write(请参阅大容量存储的 USB 规格 class BBB)。

Now I need to create a file on the connected flash drive and save some data in the file.
使用端点执行 sector read/write 但你必须在其上编写文件系统驱动程序(如 FAT32 或 EXT4 等)。 文件创建是一个文件系统操作,而不是扇区级别read/write。

Is there a way to create a file on connected device once the connection to the device is established?
您必须使用 Android 文件系统安装工具,然后使用通用文件 API 来创建文件。

在采纳了所有建议的想法后,我找到了可以接受的解决方案。使用UsbHost Api获取设备相关信息,然后 使用存储访问框架执行归档操作。