I am creating an Unity app which will be controlling Numato GPIO USB powered controller through smartphone USB connection. Since I have to connect the controller to phone I have no debug log so I have no idea what is going on. Thus, I include plugin code and a custom manifest which I use in Unity.
I get questioned by the App if I want to grant permission to control the device (Shows right device name etc) and after I grant the permission app crashes immediately.
Is there a way to check what causes the error? Or maybe I don't see something obvious here.
public class PluginInstance extends Activity {
private static Activity unityActivity;
private static Context unityContext;
public Gpio laser1;
public static void receiveUnityActivity(Activity tActivity) {
unityActivity = tActivity;
}
public static void receiveUnityContext(Context tContext) { unityContext = tContext; }
//Debugging purposes
public void Toast(String msg) {
Toast.makeText(unityActivity, msg, Toast.LENGTH_SHORT).show();
}
//Action Usb Permission
public static final String ACTION_USB_PERMISSION = "com.unity3d.player.UnityPlayerActivity.USB_PERMISSION";
public DevicesManager mDevicesManager;
//USB permission
public final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
Bundle deviceIndexBundle = intent.getExtras();
if (deviceIndexBundle == null) {
return;
}
int deviceIndex = deviceIndexBundle.getInt(AppConstant.EXTRA_DEVICE_INDEX);
Toast.makeText(unityActivity, "Usb permission granted", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(unityActivity, "Usb permission declined", Toast.LENGTH_SHORT).show();
}
unregisterReceiver(mUsbReceiver);
}
}
}
};
public void InstantiateManager() {
mDevicesManager = DevicesManager.getInstance();
}
public void GetGpios() {
NumatoUSBDevice numatoUSBDevice = mDevicesManager.getDevices().get(0);
Gpio lazer1 = numatoUSBDevice.mGpios.get(1);
}
public void GpioOn() {
laser1.setCurrentOutputState(true);
laser1.setState(true);
}
public void GpioOff() {
laser1.setCurrentOutputState(false);
laser1.setState(false);
}
public void EnumerateDevices() {
UsbManager manager = (UsbManager) unityActivity.getSystemService(Context.USB_SERVICE);
int index = 0;
ArrayList<UsbDevice> cdcAcmDevices = CdcAcmDriver.ListDevices(manager);
mDevicesManager.clearDevices();
ArrayList<Integer> supportedDevices = NumatoUSBDevice.GetSupportedProductIds();
if(!cdcAcmDevices.isEmpty()){
for (UsbDevice cdcAcmDevice : cdcAcmDevices){
int vendorId = cdcAcmDevice.getVendorId();
if(vendorId == NumatoUSBDevice.VID_NUMATOLAB && supportedDevices.contains(cdcAcmDevice.getProductId())){
mDevicesManager.addDevice(new NumatoUSBDevice(index, cdcAcmDevice, manager));
index++;
}
}
}
}
public void MakeConnection() {
NumatoUSBDevice numatoUSBDevice = mDevicesManager.getDevices().get(0);
UsbManager manager = (UsbManager) unityActivity.getSystemService(Context.USB_SERVICE);
//TODO unityContext in mPermissionIntent
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(unityContext, 0,
new Intent(ACTION_USB_PERMISSION).putExtra(AppConstant.EXTRA_DEVICE_INDEX, 0), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
unityActivity.registerReceiver(mUsbReceiver, filter);
manager.requestPermission(numatoUSBDevice.getDevice(), mPermissionIntent);
}
}
And the manifest file:
<?xml version="1.0" encoding="utf-8"?>
<!-- GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN-->
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unity3d.player"
xmlns:tools="http://schemas.android.com/tools">
<application>
<activity android:name="com.unity3d.player.UnityPlayerActivity"
android:theme="@style/UnityThemeSelector">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter"/>
</activity>
</application>
</manifest>
Edit: I managed to access debug log through wifi and this is what I get:
FATAL EXCEPTION: main
Process: com.jonquil.A2NumatoController, PID: 16837
java.lang.RuntimeException: Error receiving broadcast Intent { act=com.unity3d.player.UnityPlayerActivity.USB_PERMISSION flg=0x10 (has extras) } in com.jonquil.unityplugin.PluginInstance$1@7d45921
at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1689)
at android.app.LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7838)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.content.Context.unregisterReceiver(android.content.BroadcastReceiver)' on a null object reference
at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:769)
at com.jonquil.unityplugin.PluginInstance$1.onReceive(PluginInstance.java:63)
at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1679)
... 9 more
This looks like there is a problem with broadcast receiver since error is caused by invoking method on a null object reference.