问题
I'm trying to figure out why my application does not start communicating with the USB accessory after the phone restarts. If I unplug the cable and plug it back in, the communication resumes. The application is targeted at Android API 19.
At the app install I set it to always be the Home app and when I first connect it to the accessory I check the box to always permit the access to the current accessory.
So when I restart the phone, the app opens up automatically, it goes through the steps of checking for permission (usbmanager.hasPermission
) and it actually has the permission without any alert appearing, but the communication is not starting in OpenAccessory
method.
Manifest:
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter"></meta-data>
Comms:
// Init USB Manager
usbmanager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
context.registerReceiver(mUsbReceiver, filter);
// Resume Accessory
if (usbmanager.hasPermission(accessory)) {
OpenAccessory(accessory);
}
else
{
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
Toast.makeText(global_context, "Request USB Permission", Toast.LENGTH_SHORT).show();
usbmanager.requestPermission(accessory,
mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
// Broadcast Receiver
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action))
{
synchronized (this)
{
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
{
Toast.makeText(global_context, "Allow USB Permission", Toast.LENGTH_SHORT).show();
OpenAccessory(accessory);
}
else
{
Toast.makeText(global_context, "Deny USB Permission", Toast.LENGTH_SHORT).show();
Log.d("LED", "permission denied for accessory "+ accessory);
}
mPermissionRequestPending = false;
}
}
else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action))
{
DestroyAccessory(true);
//CloseAccessory();
}else
{
Log.d("LED", "....");
}
}
};
// OpenAccessory
private void OpenAccessory(UsbAccessory accessory)
{
filedescriptor = usbmanager.openAccessory(accessory);
if(filedescriptor != null){
usbaccessory = accessory;
FileDescriptor fd = filedescriptor.getFileDescriptor();
inputstream = new FileInputStream(fd);
outputstream = new FileOutputStream(fd);
/*check if any of them are null*/
if(inputstream == null || outputstream==null){
return;
}
if(READ_ENABLE == false){
READ_ENABLE = true;
readThread = new read_thread(inputstream);
readThread.start();
}
// Initialize the serial port here
SerialComm.getInstance().initPort();
}
}
回答1:
in UsbManager
and IntentFilter
you use ACTION_USB_ACCESSORY_DETACHED
and ACTION_USB_ACCESSORY_ATTACHED
events that are triggered when plugging or unplugging the device.
if these events /actions occur the code is executed and the app works
( https://developer.android.com/reference/android/hardware/usb/UsbManager.html )
the problem is now that when the app is started at reboot these events /actions are not triggered and so the code that is linked to them will not be executed
it is not easy to circumvent this because an application gets an instance of the UsbAccessory
class only via the ACTION_USB_ACCESSORY_ATTACHED
intent :
An instance of this class is sent to the application via the ACTION_USB_ACCESSORY_ATTACHED Intent. The application can then call openAccessory(UsbAccessory) to open a file descriptor for reading and writing data to and from the accessory.
source : https://developer.android.com/reference/android/hardware/usb/UsbAccessory.html
it is not possible for the app to use a class ( the accessory ) if it has no instance of it ...
来源:https://stackoverflow.com/questions/48297467/usb-accessory-not-communicating-after-restart