USB配件重启后无法通信

时间:2018-01-17 09:18:10

标签: android multithreading usb accessory

我试图找出手机重启后我的应用程序无法开始与USB配件通信的原因。如果我拔下电缆并将其重新插入,通信将恢复。该应用程序针对Android API 19。

在app安装时,我将其设置为Home应用程序,当我第一次将其连接到附件时,我选中该框以始终允许访问当前附件。

因此,当我重新启动手机时,应用程序会自动打开,它会执行检查权限(usbmanager.hasPermission)的步骤,并且它实际上拥有权限而没有出现任何警报,但是通信未启动OpenAccessory方法。

清单:

        <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>

通讯科:

// 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 个答案:

答案 0 :(得分:0)

UsbManagerIntentFilter中,您使用了在插入或拔出设备时触发的ACTION_USB_ACCESSORY_DETACHEDACTION_USB_ACCESSORY_ATTACHED个事件。

如果发生这些事件/操作,则执行代码并且应用程序正常工作

https://developer.android.com/reference/android/hardware/usb/UsbManager.html

现在的问题是,当应用程序在重新启动时启动时,这些事件/操作不会被触发,因此链接到它们的代码将不会被执行

要避免这种情况并不容易,因为应用程序仅通过UsbAccessory意图获取ACTION_USB_ACCESSORY_ATTACHED类的实例:

  

此类的实例通过以下命令发送到应用程序   ACTION_USB_ACCESSORY_ATTACHED意图。然后应用程序可以调用   openAccessory(UsbAccessory)打开文件描述符进行读取和   向配件写入数据。

来源:https://developer.android.com/reference/android/hardware/usb/UsbAccessory.html

如果没有它的实例,应用程序就无法使用类(附件)......