3
votes

In my application am using USB host mode which gives the information about connected USB mass storage device say Usb Flash Drive in my use case.Now I need to create a file on the connected flash drive and save some data in the file. So far I have found is connecting to the device as below,

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>

In the above example I have tried to send the String value to the connected device and the int value returned is number of characters sent. But Where do this information is stored on the connected device I mean location?

Is there a way to create a file on connected device once the connection to the device is established? Links to related blog posts are helpful.

I have found this on stack but the solution not helped in any way.

Any help is appreciated.Thanks.

2
But Where do this information is stored on the connected device I mean location?. Well you could have a look on the device by other mean.s. Then you would soon discover what changed.greenapps
Please react to the point to my comment.greenapps
mOutputEndpoint = tOut; Of both variables you dont show the type. Why did you declare them somewhere else?greenapps
You could have told that before of course. Where is it that you wanted the bytes to be stored? Which place did you indicate?greenapps
Why dont you use the Storage Access Framework or Storage Volumes to do so?greenapps

2 Answers

4
votes

You are searching bulk endpoints which means you are trying to sector read/write using BBB (See USB Specs for Mass Storage class BBB).

Now I need to create a file on the connected flash drive and save some data in the file.
Using endpoints you perform sector read/write but you have to write filesystem driver (Like FAT32 or EXT4 etc) on top of it. File creation is a filesystem operation, not sector level read/write.

Is there a way to create a file on connected device once the connection to the device is established?
You have to use Android filesystem mounting facility and then use the generic file API to create files.

0
votes

After going with all suggested ideas I have found the solution which works as accepted. Use UsbHost Api to get the device related information and then use Storage Access Framework to perform the filing operation.