How to implement Android Open Accessory mode as a service?

I played with the Android Open Accessory Development Kit. Following the DemoKit examples provided by Google , I had no problems adapting the solution to my application. I can detect, share and disconnect the accessory just fine.

However, I would need to run all this as a service. I have an underlying asset that is launched using the USB_ACCESSORY_ATTACHED intent (that is, when the accessory is connected), and this works fine. But as soon as I start my service and run the identical code in it compared to my working solution as part of the usual action, I get an IOException ("there is no such device") whenever I try to contact the accessory (arduino monitoring shows a successful USB connection ) This happens even if I specified the correct BroadcastReceiver inside the service, registered it in the onStartCommand callback method, and configured the communication endpoints using openAccessory() . The corresponding code is as follows.

 @Override public void onCreate() { Log.d(TAG, "ONCREATE"); manager = UsbManager.getInstance(this); mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent( ACTION_USB_PERMISSION), 0); // Register broadcastreceiver for filtering accessory events IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED); registerReceiver(mUsbReceiver,filter); super.onCreate(); } public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "ONSTARTCOMMAND METHOD ACCESSED"); if (mInputStream != null && mOutputStream != null) { return START_NOT_STICKY; } UsbAccessory[] accessories = manager.getAccessoryList(); mAccessory = (accessories == null ? null : accessories[0]); if (mAccessory != null) { if (manager.hasPermission(mAccessory)) { openAccessory(); } else { synchronized (mUsbReceiver) { if (!mPermissionRequestPending) { manager.requestPermission(mAccessory, mPermissionIntent); mPermissionRequestPending = true; } } } } else { Log.d(TAG, "mAccessory is null"); } return START_NOT_STICKY; } 

openAccessory method:

 /** * Open the accessory */ private void openAccessory() { Log.d(TAG, "openAccessory: "+mAccessory); mFileDescriptor = manager.openAccessory(mAccessory); if (mFileDescriptor != null) { FileDescriptor fd = mFileDescriptor.getFileDescriptor(); mInputStream = new FileInputStream(fd); mOutputStream = new FileOutputStream(fd); Thread thread = new Thread(null,this,"AccessoryThread"); thread.start(); } } 

Any ideas for a possible solution?

+4
source share
2 answers

The solution was simple.

 if (intent.getAction().equals(USB_ACCESSORY_ATTACHED)) { Intent i = new Intent(this, YourServiceName.class); i.putExtras(intent); startService(i); } 

Basically, copy the intention that you received when you started your activity, which you use to start the service, since this intention contains information about the accessory that is required to implement the ADK.

Then, in the service, we proceed to implement the rest of the ADK in the same way as before.

+3
source

At the moment, I cannot give you a suitable solution to your problem. But maybe this github example shows you how to solve your problem:

I am going to analyze the code provided on github to implement the same thing that you are going to do.

0
source

Source: https://habr.com/ru/post/1379075/


All Articles