karamazovbros
karamazovbros

Reputation: 979

Android Java USB serial communication plugin for Unity not running

I created a Java plugin that utilizes the UsbManager devices to communicate with a specified serial device. I'm using Android Studio to run the plugin and can write to the proper device, but I don't understand how to integrate my code with Unity. I pass the Context in the constructor so I can create the UsbManager, but I don't know how to this in Unity or if there's another way to get the Context.

What's the proper way to pass the Context from Unity to my plugin? I'm also not sure if my function is working in Unity, because I don't know if permissions are needed for USB as well in the manifest file.

Unity Code:

void Start()
{
        ajc = new AndroidJavaObject("com.company.dg.USBController");
        int connected = ajc.Call<int>("startUSB");
}

Java Code:

public class USBController {

    private Context context;
    private static final String ACTION_USB_PERMISSION = "com.company.dg.USB_PERMISSION";
    private final int BAUD_RATE = 19200;

    private int bytesRead;
    private byte[] readBuffer;
    private UsbManager usbManager;
    private UsbDeviceConnection connection;
    private UsbSerialDevice serial;
    private UsbDevice dg = null;

    public USBController(Context context){
        this.context = context;
    }

    public int startUSB(){
        //usbManager = (UsbManager) context.getSystemService(context.USB_SERVICE);
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        UsbDevice dg = null;

        if(deviceList.size() == 0){
            return -2;
        }
        // 1st and only device
        dg = deviceList.values().iterator().next();

        if(dg != null){
            PendingIntent pi = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
            usbManager.requestPermission(dataglove, pi);
            UsbDeviceConnection connection = usbManager.openDevice(dataglove);

            UsbSerialDevice serial = UsbSerialDevice.createUsbSerialDevice(dg, connection);
            serial.open();
            serial.setBaudRate(BAUD_RATE);
            serial.setDataBits(UsbSerialInterface.DATA_BITS_8);
            serial.setStopBits(UsbSerialInterface.STOP_BITS_1);
            serial.setParity(UsbSerialInterface.PARITY_NONE);
            serial.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
            serial.read(callback);
        } else {
            return -1;
        }
        return 0;
    }

    private UsbSerialInterface.UsbReadCallback callback = new UsbSerialInterface.UsbReadCallback() {
        @Override
        public void onReceivedData(byte[] data) {
            bytesRead = data.length;
            readBuffer = data;
        }
    };

Upvotes: 2

Views: 1267

Answers (1)

Programmer
Programmer

Reputation: 125255

What's the proper way to pass the Context from Unity to my plugin?

C# side:

Your USBController class has a constructor that takes Context as an argument. Before calling the startUSB function, obtain the Unity Context then send it to the constructor when you're creating an instance of USBController.

Get Unity Context:

    AndroidJavaClass unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    AndroidJavaObject unityActivity = unityClass.GetStatic<AndroidJavaObject>("currentActivity");
    AndroidJavaObject unityContext = unityActivity.Call<AndroidJavaObject>("getApplicationContext");

Send the Context to your Java code when creating an instance of it:

ajc = new AndroidJavaObject("com.bebopsensors.dg.USBController", unityContext);

Now, you can call your startUSB function:

int connected = ajc.Call<int>("startUSB");

Java Side:

In your startUSB function, you can now use the Context with the getSystemService. I noticed you commented that out. Note that the context.USB_SERVICE should be Context.USB_SERVICE. The c in Context should be capitalized.

public int startUSB()
{
    usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
    ....
    ....
}

Don't know if permissions are needed for USB as well in the manifest file.

Not really sure about that but I believe that calling the requestPermission function which you did should be enough to handle that. If this is not working then I suggest you test your Java program in Android only and Without Unity to see if it's working. If it works there, the solution I suggested should also work.

Upvotes: 1

Related Questions