Reputation: 979
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
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