简体   繁体   English

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

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

I am developing an Android application using Android Studio 0.5.2. 我正在使用Android Studio 0.5.2开发Android应用程序。

My application is operating a USB host which appears to operate correctly - unless the device is connected (and permissions have not yet been granted) when the app starts. 我的应用程序正在运行USB主机,它似乎可以正常运行 - 除非设备已连接(并且尚未授予权限)应用程序启动时。

Generally, what happens when the USB is connected (while app is running): 通常,USB连接时会发生什么(当应用程序运行时):

  • "onResume" is called - this detects the device and asks for permission. 调用“onResume” - 这会检测设备并请求权限。 An intent filter is created to catch when the USB is attached, detached or permission granted 创建一个intent过滤器以捕获USB连接,分离或许可授予的时间

  • Permission request is shown, select Ok 显示权限请求,选择确定

  • "onResume" is called again. 再次调用“onResume”。 The first line of this funciton is "super.onResume()" 这个功能的第一行是“super.onResume()”

  • As soon as I step over super.onResume, "Unfortunately, System UI has stopped" message is displayed and the Android UI crashes 一旦我跨过super.onResume,“不幸的是,系统UI已停止”消息显示并且Android UI崩溃

  • My application continues to work correctly 我的应用程序继续正常工作

If I connect the device while the application is already running there is no issue - this only occurs when the USB is connected on launch. 如果我在应用程序运行时连接设备则没有问题 - 只有在启动时连接USB时才会出现这种情况。

Any insight into what could be causing this or how to further narrow down on the problem would be greatly appreciated. 任何洞察可能导致此问题的原因或如何进一步缩小问题将不胜感激。 I have attached the notable code below. 我在下面附上了值得注意的代码。 I am not normally a Java developer, so I suspect the issue is something to do with the pause/resume behaviour, receivers, intent filters or permissions. 我通常不是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. Try super.onResume at the end of onResume method 在onResume方法的末尾尝试super.onResume
  2. Alert user to connect the usb device on application start (main activity's onCreate) if device is not connected, toast an alert msg and finish/close the main activity 警报用户在应用程序启动时连接usb设备(主要活动的onCreate)如果设备未连接,则提供警报消息并完成/关闭主要活动
  3. Add intend filter in manifest file allowing the app to start automatically on connecting the device 在清单文件中添加意图过滤器,允许应用程序在连接设备时自动启动
  4. Try to capture exception printstacktrack when the UI stopped message is shown and debug further from the exception. 尝试在显示UI停止消息时捕获异常printstacktrack,并从异常中进一步调试。
  5. Make sure to follow the steps from android doc https://developer.android.com/guide/topics/connectivity/usb/host.html 请务必按照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