【问题标题】:USB Accessory not communicating after restart重启后 USB 附件无法通信
【发布时间】:2018-01-17 09:18:10
【问题描述】:

我试图弄清楚为什么我的应用程序在手机重启后没有开始与 USB 附件通信。如果我拔下电缆并将其重新插入,通信将恢复。该应用程序针对 Android API 19。

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

所以当我重新启动手机时,应用程序会自动打开,它会通过检查权限(usbmanager.hasPermission)的步骤,它实际上有权限,没有出现任何警报,但通信没有在@987654322 开始@方法。

清单:

        <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();
        }
    }

【问题讨论】:

    标签: android multithreading usb accessory


    【解决方案1】:

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

    如果这些事件/动作发生,代码将被执行并且应用程序工作

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

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

    要规避这一点并不容易,因为应用程序只能通过 ACTION_USB_ACCESSORY_ATTACHED 意图获取 UsbAccessory 类的实例:

    这个类的一个实例通过 ACTION_USB_ACCESSORY_ATTACHED 意图。然后应用程序可以调用 openAccessory(UsbAccessory) 打开一个文件描述符进行读取和 向附件写入数据和从附件写入数据。

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

    如果应用没有实例,则应用无法使用类(附件)...

    【讨论】:

    • 实际上,广播接收器被调用并获得访问附件的权限,并且代码通过 OpenAccessory 进行,但通信仍未重新启动。我尝试了您的两种选择,但都没有运气。
    • 是的,这是可能的。这是 android 的安全限制之一。另一种可能性是手动触发动作ACTION_USB_ACCESSORY_ATTACHED,但这似乎也不可能,参见stackoverflow.com/questions/26654844/…我编辑答案....
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    • 2018-03-29
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    相关资源
    最近更新 更多