Unity Android Usb 通信

Unity 监听安卓USB得插拔,以及数据通信(安卓是主)

因为不想通过Android 继承 Unity的activity这种方式实现(需要修改manifest)。

所以具体实现方式是在Unity的Update中获取所有usb设备,然后自己判断插拔。

   usbManager=(UsbManager)context.getSystemService(Context.USB_SERVICE);
  public  List  GetUsbDevice()
    {
        List alldevice = new ArrayList<>();
        HashMap deviceMap=usbManager.getDeviceList();
        Iterator iterator=deviceMap.values().iterator();
        while(iterator.hasNext()){
            UsbDevice nowDevice=iterator.next();
            alldevice.add(nowDevice);
        }
        return  alldevice;
    }

这是获取所有设备的代码。设备可以通过pid和vid 判断,然后也可以获取到设备类型,具体可以参考Android UsbDevice这个类。

我做法是直接把UsbDevice这个类返回到了Unity,然后就可以在Unity中获取这些数据了。

要打开UsbDevice需要申请权限,每次插拔设备后,都要重新获取权限。获取权限的方式,就是弹窗提示用户授权

   ACTION_USB_PERMISSION =  context.getPackageName() + ".USB_PERMISSION";
   private void GetPermission()
    {
        if(targetDevice == null)
            return;
        if (!usbManager.hasPermission(targetDevice)) {
            IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
            context.registerReceiver(mUsbPermissionReceiver, filter);
            PendingIntent pi = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
            usbManager.requestPermission(targetDevice, pi);
        }
        else
        {
            usbDeviceInit();
        }
    }


  private BroadcastReceiver mUsbPermissionReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            context.unregisterReceiver(mUsbPermissionReceiver);
            if (ACTION_USB_PERMISSION.equals(action)) {
                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    //获得了usb使用权限
                    usbDeviceInit();
                }
                else
                {
                    callback.DeviceError(0);
                    Close();
                }
            }
        }
    };

有了权限后,就可以获取设备的UsbEndpoint,设备有UsbConstants.USB_DIR_OUT和UsbConstants.USB_DIR_IN,一个是发送,一个是接收

 private void usbDeviceInit() {
        int interfaceCount = targetDevice.getInterfaceCount();
        for (int i = 0; i < interfaceCount; i++) {
            usbInterface = targetDevice.getInterface(i);
        }
        if (usbInterface != null) {
            connection = usbManager.openDevice(targetDevice);
            if (connection != null) {
                if (connection.claimInterface(usbInterface, true)) {
                    for (int j = 0; j < usbInterface.getEndpointCount(); j++) {
                        UsbEndpoint endpoint = usbInterface.getEndpoint(j);
                        if (endpoint.getDirection() == UsbConstants.USB_DIR_OUT) {
                            outendpoint = endpoint;
                        } else  if (endpoint.getDirection() == UsbConstants.USB_DIR_IN) {
                            inendpoint = endpoint;
                        }
                    }
                }
            }

        }
        StartRecive();
    }

   public byte[]  GetMessage()
    {
        int inMax = inendpoint.getMaxPacketSize();

        ByteBuffer byteBuffer = ByteBuffer.allocate(inMax);
        UsbRequest usbRequest = new UsbRequest();
        usbRequest.initialize(connection, inendpoint);
        usbRequest.queue(byteBuffer, inMax);
        UsbRequest waitRequest = connection.requestWait();
        if (waitRequest == usbRequest) {
            byte[] retData = byteBuffer.array();
            return  retData;
        }
        else if(waitRequest == null)
        {
            Close();
        }
        return null;
    }

public void SendMessage(byte[] data) {

        final byte[] _data = data;
        Thread thread = new Thread(new Runnable()
        {
            @Override
            public void run() {
                byte[] bytes = _data;
                if (outendpoint == null || connection == null) {
                    callback.DeviceError(5);
                }
                UsbInterface intf = targetDevice.getInterface(0);
                UsbEndpoint endpoint = intf.getEndpoint(0);
                UsbDeviceConnection connection = usbManager.openDevice(targetDevice);
                connection.claimInterface(intf, forceClaim);
                int ret = connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT);
                if (ret < 0) {
                    callback.DeviceError(7);
                }
            }
        });
    }

代码有部分截取,接收需要自己创建一个线程。

上面部分是Android端的,Unity端的获取数据和调用安卓的方式,可以参考我以前的文章。

上传的unitypacket中,安卓代码打包成了aar,可以自己在Androidstudio中打开查看。

如果有问题请自己留言,不要私信,你的问题可能也是别人的问题,谢谢!

你可能感兴趣的:(Unity,AndroidStudio,结合)