繁体   English   中英

Android USB权限,onPause,onResume - 不幸的是,系统UI已停止“

[英]Android USB Permissions, onPause, onResume - Unfortunately, System UI has stopped"

我正在使用Android Studio 0.5.2开发Android应用程序。

我的应用程序正在运行USB主机,它似乎可以正常运行 - 除非设备已连接(并且尚未授予权限)应用程序启动时。

通常,USB连接时会发生什么(当应用程序运行时):

  • 调用“onResume” - 这会检测设备并请求权限。 创建一个intent过滤器以捕获USB连接,分离或许可授予的时间

  • 显示权限请求,选择确定

  • 再次调用“onResume”。 这个功能的第一行是“super.onResume()”

  • 一旦我跨过super.onResume,“不幸的是,系统UI已停止”消息显示并且Android UI崩溃

  • 我的应用程序继续正常工作

如果我在应用程序运行时连接设备则没有问题 - 只有在启动时连接USB时才会出现这种情况。

任何洞察可能导致此问题的原因或如何进一步缩小问题将不胜感激。 我在下面附上了值得注意的代码。 我通常不是Java开发人员,所以我怀疑这个问题与暂停/恢复行为,接收器,意图过滤器或权限有关。

// *************************************************************
// ************************* USB Stuff *************************
// *************************************************************
boolean resumePermissionBlocked = false;
PendingIntent pendingIntent = null;
BroadcastReceiver receiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        // Get the information about what action caused this event
        try {
            String action = intent.getAction();
            Log.i(TAG, "$EC: action:" + action);

            if ("com.android.example.USB_PERMISSION".equals(action)) {
                UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if (device != null) {


                        if (device.getProductId() == 0xAAAA) {
                            if (device.getVendorId() == 0xBBBB) {
                                // see if we have permission
                                UsbManager openManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);

                                // send a message to the worker thread to begin opening a connection to this device
                                ThreadMsg msg = new ThreadMsg();
                                msg.request = MsgRequest.openConnection;
                                msg.objectA = device;
                                msg.objectB = openManager;
                                sendMessageToWorker(msg);

                            }
                        }
                    }
                } else {
                    if (device != null)
                        Log("USB Permission denied", TextFormat.StrongWarning_withTime);
                }
            }
            if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
                UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                if (device == null) return;
                if (device.getProductId() == 0x003C) {
                    if (device.getVendorId() == 0x04D8) {
                        // see if we have permission
                        UsbManager openManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
                        if (!openManager.hasPermission(device)) {
                            resumePermissionBlocked = true; // block the resume function from trying to re-ask for permission
                            openManager.requestPermission(device, mPermissionIntent);
                            return;
                        }
                        ThreadMsg msg = new ThreadMsg();
                        msg.request = MsgRequest.openConnection;
                        msg.objectA = device;
                        msg.objectB = openManager;
                        sendMessageToBootloader(msg);
                    }
                }
            } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                // If it was a USB device detach event, then get the USB device
                // that caused the event from the intent.
                UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                ThreadMsg msg = new ThreadMsg();
                msg.request = MsgRequest.closeConnection;
                msg.objectA = device;
                sendMessageToBootloader(msg);
            }
        } catch (Exception e) {
            Log.i(TAG, "onResume catch: " + e.toString());
        }
    }

};

boolean receiverHasBeenRegistered = false;

PendingIntent mPermissionIntent;
@Override
public void onResume(){
    try {

        super.onResume();

        if (resumePermissionBlocked) {
            // this was resumed from a permission request - don't try to connect to the device now, leave it for the USB_PERMISSION_GRANTED intent
            resumePermissionBlocked = false;    // clear the flag
        } else {
            UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
            HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
            if (deviceList != null) {
                Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
                Log.i(TAG, "$EC: Begin iteration");

                while (deviceIterator.hasNext()) {
                    // Is this the device we are after?
                    UsbDevice device = deviceIterator.next();
                    if (device == null) return;
                    if (device.getProductId() == 0xAAAA) {
                        if (device.getVendorId() == 0xBBBB) {
                            // see if we have permission
                            UsbManager openManager = (UsbManager) this.getSystemService(Context.USB_SERVICE);
                            if (!openManager.hasPermission(device)) {
                                resumePermissionBlocked = true;         // block the subsequent call to this (between the application resuming and permission being granted)
                                openManager.requestPermission(device, mPermissionIntent);
                                return;
                            }
                            ThreadMsg msg = new ThreadMsg();
                            msg.request = MsgRequest.openConnection;
                            msg.objectA = device;
                            msg.objectB = openManager;
                            sendMessageToWorker(msg);
                        }
                    }
                }
            }
        }
    } catch (Exception e)
    {
        Log.i(TAG, "onResume catch: " + e.toString());
    }

    if (!receiverHasBeenRegistered) {
        // this line is for permissions
        mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent("com.android.example.USB_PERMISSION"), 0);

        //Create a new filter to detect USB device events
        IntentFilter filter = new IntentFilter();
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        filter.addAction("com.android.example.USB_PERMISSION");
        registerReceiver(receiver, filter);
        pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(getPackageName() + ".USB_PERMISSION"), 0);
        receiverHasBeenRegistered = true;
    }
}

@Override
public void onPause() {
    /* unregister any receivers that we have */
    try {
        if (receiver != null && receiverHasBeenRegistered) {
            unregisterReceiver(receiver);
            receiverHasBeenRegistered = false;
        }
    } catch (Exception e) {
        // if this happens, then the receiver was probably never registered in the first place
        Log.i(TAG, "onPause catch: " + e.toString());
    }
    super.onPause();
}
  1. 在onResume方法的末尾尝试super.onResume
  2. 警报用户在应用程序启动时连接usb设备(主要活动的onCreate)如果设备未连接,则提供警报消息并完成/关闭主要活动
  3. 在清单文件中添加意图过滤器,允许应用程序在连接设备时自动启动
  4. 尝试在显示UI停止消息时捕获异常printstacktrack,并从异常中进一步调试。
  5. 请务必按照Android doc https://developer.android.com/guide/topics/connectivity/usb/host.html中的步骤操作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM