ProgramingTip

기기에서 읽은 Android USB 호스트

bestdevel 2021. 1. 8. 23:05
반응형

기기에서 읽은 Android USB 호스트


호스트 모드에있는 Android 휴대폰에 USB 장치에서 일부 데이터를 가져 오려고합니다. 읽기가 실패합니다.

가지 몇 예를 살펴보고 할 수있는 모든 것을 시도했지만 USB 통신에 대한 경험은 없지만 지금은 조금 알고 있으며 인정할만큼 오래 머물 렀습니다 .

엔드 포인트 구성에 잘 모르지만 내 장치가 CDC 유형의 통신 방법을 사용하고 출력 (전화에서 장치로)과 입력이 모두 등록하고 알고 있습니다.

유일한 장치로 USB 연결을 관리하는 전체 수업이 있습니다. 어떤 방법으로도 완료되지 않았는지 더 이상 진행하기 전에 읽기 부분이 작동하고 싶습니다.

public class UsbCommunicationManager
{
    static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

    UsbManager usbManager;
    UsbDevice usbDevice;
    UsbInterface intf = null;
    UsbEndpoint input, output;
    UsbDeviceConnection connection;

    PendingIntent permissionIntent;

    Context context;

    byte[] readBytes = new byte[64];

    public UsbCommunicationManager(Context context)
    {
        this.context = context;
        usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);

        // ask permission from user to use the usb device
        permissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        context.registerReceiver(usbReceiver, filter);
    }

    public void connect()
    {
        // check if there's a connected usb device
        if(usbManager.getDeviceList().isEmpty())
        {
            Log.d("trebla", "No connected devices");
            return;
        }

        // get the first (only) connected device
        usbDevice = usbManager.getDeviceList().values().iterator().next();

        // user must approve of connection
        usbManager.requestPermission(usbDevice, permissionIntent);
    }

    public void stop()
    {
        context.unregisterReceiver(usbReceiver);
    }

    public String send(String data)
    {
        if(usbDevice == null)
        {
            return "no usb device selected";
        }

        int sentBytes = 0;
        if(!data.equals(""))
        {
            synchronized(this)
            {
                // send data to usb device
                byte[] bytes = data.getBytes();
                sentBytes = connection.bulkTransfer(output, bytes, bytes.length, 1000);
            }
        }

        return Integer.toString(sentBytes);
    }

    public String read()
    {
        // reinitialize read value byte array
        Arrays.fill(readBytes, (byte) 0);

        // wait for some data from the mcu
        int recvBytes = connection.bulkTransfer(input, readBytes, readBytes.length, 3000);

        if(recvBytes > 0)
        {
            Log.d("trebla", "Got some data: " + new String(readBytes));
        }
        else
        {
            Log.d("trebla", "Did not get any data: " + recvBytes);
        }

        return Integer.toString(recvBytes);
    }

    public String listUsbDevices()
    {
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();

        if(deviceList.size() == 0)
        {
            return "no usb devices found";
        }

        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        String returnValue = "";
        UsbInterface usbInterface;

        while(deviceIterator.hasNext())
        {
            UsbDevice device = deviceIterator.next();
            returnValue += "Name: " + device.getDeviceName();
            returnValue += "\nID: " + device.getDeviceId();
            returnValue += "\nProtocol: " + device.getDeviceProtocol();
            returnValue += "\nClass: " + device.getDeviceClass();
            returnValue += "\nSubclass: " + device.getDeviceSubclass();
            returnValue += "\nProduct ID: " + device.getProductId();
            returnValue += "\nVendor ID: " + device.getVendorId();
            returnValue += "\nInterface count: " + device.getInterfaceCount();

            for(int i = 0; i < device.getInterfaceCount(); i++)
            {
                usbInterface = device.getInterface(i);
                returnValue += "\n  Interface " + i;
                returnValue += "\n\tInterface ID: " + usbInterface.getId();
                returnValue += "\n\tClass: " + usbInterface.getInterfaceClass();
                returnValue += "\n\tProtocol: " + usbInterface.getInterfaceProtocol();
                returnValue += "\n\tSubclass: " + usbInterface.getInterfaceSubclass();
                returnValue += "\n\tEndpoint count: " + usbInterface.getEndpointCount();

                for(int j = 0; j < usbInterface.getEndpointCount(); j++)
                {
                    returnValue += "\n\t  Endpoint " + j;
                    returnValue += "\n\t\tAddress: " + usbInterface.getEndpoint(j).getAddress();
                    returnValue += "\n\t\tAttributes: " + usbInterface.getEndpoint(j).getAttributes();
                    returnValue += "\n\t\tDirection: " + usbInterface.getEndpoint(j).getDirection();
                    returnValue += "\n\t\tNumber: " + usbInterface.getEndpoint(j).getEndpointNumber();
                    returnValue += "\n\t\tInterval: " + usbInterface.getEndpoint(j).getInterval();
                    returnValue += "\n\t\tType: " + usbInterface.getEndpoint(j).getType();
                    returnValue += "\n\t\tMax packet size: " + usbInterface.getEndpoint(j).getMaxPacketSize();
                }
            }
        }

        return returnValue;
    }

    private void setupConnection()
    {
        // find the right interface
        for(int i = 0; i < usbDevice.getInterfaceCount(); i++)
        {
            // communications device class (CDC) type device
            if(usbDevice.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA)
            {
                intf = usbDevice.getInterface(i);

                // find the endpoints
                for(int j = 0; j < intf.getEndpointCount(); j++)
                {
                    if(intf.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_OUT && intf.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
                    {
                        // from android to device
                        output = intf.getEndpoint(j);
                    }

                    if(intf.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_IN && intf.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
                    {
                        // from device to android
                        input = intf.getEndpoint(j);
                    }
                }
            }
        }
    }

    private final BroadcastReceiver usbReceiver = new BroadcastReceiver()
    {
        public void onReceive(Context context, Intent intent)
        {
            String action = intent.getAction();
            if(ACTION_USB_PERMISSION.equals(action))
            {
                // broadcast is like an interrupt and works asynchronously with the class, it must be synced just in case
                synchronized(this)
                {
                    if(intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
                    {
                        setupConnection();

                        connection = usbManager.openDevice(usbDevice);
                        connection.claimInterface(intf, true);

                        // set flow control to 8N1 at 9600 baud
                        int baudRate = 9600;
                        byte stopBitsByte = 1;
                        byte parityBitesByte = 0;
                        byte dataBits = 8;
                        byte[] msg = {
                            (byte) (baudRate & 0xff),
                            (byte) ((baudRate >> 8) & 0xff),
                            (byte) ((baudRate >> 16) & 0xff),
                            (byte) ((baudRate >> 24) & 0xff),
                            stopBitsByte,
                            parityBitesByte,
                            (byte) dataBits
                        };

                        connection.controlTransfer(UsbConstants.USB_TYPE_CLASS | 0x01, 0x20, 0, 0, msg, msg.length, 5000);
                    }
                    else
                    {
                        Log.d("trebla", "Permission denied for USB device");
                    }
                }
            }
            else if(UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action))
            {
                Log.d("trebla", "USB device detached");
            }
        }
    };
}

나는 어떤 종류의 오류를 나타내는 방법 -1에서 계속 얻고 있으며 read()항상 시간이 초과됩니다. 문제는 연결 구성에서 비롯된 것일 수 있으며 여러 번 시도해 보았지만 (시행 착오를 읽음) 아무것도 작동하지 않았습니다. 놀랍게도 데이터를 장치로 보내기 위해 구성이 필요하지 않습니다.


편집하다

또한 내가 사용하는 케이블은 마이크로 USB 대 마이크로 USB이며 한 가지 방식으로 만 작동합니다. 즉, 내 장치는 플러그 A가 전화에 연결되고 플러그 B가 그 반대가 아닌 장치 ... 매우 이상해 보입니다. 데이터를 보낼 수 있지만 올바른 방식으로 연결했을 때 수신하지 못한다는 사실은 그대로 남아 있습니다.


2 편집

나는 다른 누군가가 같은 문제를 가지고 있다는 것을 알았지 만 그는 그것을 해결할 수 없었던 것 같습니다.


3 편집

마침내이 페이지 에서 해결책을 찾았습니다 .

또 다른 주요 감독은 호스트 측에 데이터를 수용 할 준비가 된 데이터 싱크가 있음을 호스트가 장치에 알리는 메커니즘이 없다는 것입니다. 이는 호스트가 수신하지 않는 동안 장치가 데이터 전송을 시도하여 전송 루틴에서 긴 차단 시간 초과를 유발할 수 있음을 의미합니다. 따라서 가상 직렬 라인 DTR (Data Terminal Ready) 신호를 사용하여 호스트 응용 프로그램이 데이터를받을 준비가되었는지 확인하는 것이 좋습니다.

따라서 DTR 신호는 필수였으며 인터페이스 구성에 이것을 추가하기 만하면되었습니다.

connection.controlTransfer(0x21, 0x22, 0x1, 0, null, 0, 0);

4 편집

관심이있는 사람이 있다면 프로젝트를 완료하고 오픈 소스이며 GitHub 계정에 게시했습니다 . 그래도 항상 안정적이지는 않으며 ( 노트 참조 ) 더 이상 작업 할 계획은 없지만 작동합니다. 자신의 프로젝트에 자유롭게 사용하십시오.


https://github.com/mik3y/usb-serial-for-android 에서 UsbSerial Lib를 사용할 수 있습니다.

내 예제 코드 :

    UsbManager usbManager = null;
    UsbDeviceConnection connection = null;
    UsbSerialDriver driver = null;
    UsbSerialPort port = null;

    usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);

    List<UsbSerialDriver> availableDrivers =  UsbSerialProber.getDefaultProber().findAllDrivers(manager);
    // Open a connection to the first available driver.

    for (UsbSerialDriver usd : availableDrivers) {
        UsbDevice udv = usd.getDevice(); 
        if (udv.getVendorId()==0x067B || udv.getProductId()==2303){
            driver = usd;
            break;
        }
    }
        connection = usbManager.openDevice(driver.getDevice());

        port = driver.getPorts().get(0);

        driver.getDevice().

    }

        if (connection == null) return;

        try{

            port.open(connection);
            port.setParameters(4800, UsbSerialPort.DATABITS_8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);

                try{

                    byte buffer[] = new byte[250];
                    //Log.d("GPS_REQ", "->");
                    int numBytesRead = port.read(buffer, 500); //5000; 

                }catch (Exception e) {
                    Log.d("GPS_ERR", e.getLocalizedMessage());
                }

참조 URL : https://stackoverflow.com/questions/19736301/android-usb-host-read-from-device

반응형