Я создал плагин Java, который использует устройства UsbManager для связи с указанным последовательным устройством. Я использую Android Studio для запуска плагина и могу писать на нужное устройство, но не понимаю, как интегрировать свой код с Unity. Я передаю контекст в конструкторе, чтобы создать UsbManager, но я не знаю, как это сделать в Unity и есть ли другой способ получить контекст.
Как правильно передать контекст из Unity в мой плагин? Я также не уверен, работает ли моя функция в Unity, потому что я не знаю, нужны ли разрешения для USB в файле манифеста.
Код единства:
void Start()
{
ajc = new AndroidJavaObject("com.company.dg.USBController");
int connected = ajc.Call<int>("startUSB");
}
Код Java:
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;
}
};




What's the proper way to pass the Context from Unity to my plugin?
Сторона C#:
В вашем классе USBController есть конструктор, который принимает Context в качестве аргумента. Перед вызовом функции startUSB получите Unity Context, а затем отправьте его конструктору при создании экземпляра USBController.
Получить контекст Unity:
AndroidJavaClass unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject unityActivity = unityClass.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject unityContext = unityActivity.Call<AndroidJavaObject>("getApplicationContext");
Отправьте контекст в свой Java-код при создании его экземпляра:
ajc = new AndroidJavaObject("com.bebopsensors.dg.USBController", unityContext);
Теперь вы можете вызвать функцию startUSB:
int connected = ajc.Call<int>("startUSB");
Сторона Java:
В вашей функции startUSB теперь вы можете использовать Context с getSystemService. Я заметил, что вы это прокомментировали. Обратите внимание, что context.USB_SERVICE должен быть Context.USB_SERVICE. c в Context следует писать с заглавной буквы.
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.
Не совсем уверен в этом, но я считаю, что вызова функции requestPermission, которую вы сделали, должно быть достаточно, чтобы справиться с этим. Если это не работает, я предлагаю вам протестировать свою программу Java только на Android и без Unity, чтобы убедиться, что она работает. Если это сработает, предложенное мной решение тоже должно сработать.
Что вы считаете «работающим» и что сейчас происходит на стороне Unity?
В функции startUSB я использую последовательный порт для записи сообщения байтового массива, которое сигнализирует устройству о включении. Это также приведет к включению светодиода, но в Unity он никогда не доходит до точки записи, что заставляет меня думать, что мой класс загружен неправильно или что-то не так, прежде чем я вызову функцию в Unity. В Unity приложение запускается, но данные для чтения от устройства не поступают, и устройство никогда не получает сообщение записи.
Первое, что я предлагаю вам сделать сейчас, - это проверить, не возникает ли секретная ошибка Android при запуске вашей программы. Сообщение Этот показывает, как получить журнал ошибок с Android.
Привет, @karamazovbros, у тебя все получилось? Я пытаюсь сделать то же самое и нашел ваш пост. Спасибо!
@ Привет, вот и все заработало. Насколько я помню, я забыл включить файл манифеста Android в папку плагинов Unity. К сожалению, я переключился с последовательных устройств, поэтому у меня нет текущего кода для показа, но этот пример выглядит правильным.
спасибо за помощь, но со стороны Unity он по-прежнему не работает. Это работает, когда я делаю сборку из Android Studio и использую приложение с подключенным последовательным устройством, но в Unity это не работает.