【发布时间】:2014-04-28 03:47:16
【问题描述】:
我正在使用 Android Studio 0.5.2 开发一个 Android 应用程序。
我的应用程序正在运行一个看似正常运行的 USB 主机 - 除非在应用程序启动时设备已连接(并且尚未授予权限)。
一般来说,当 USB 连接时(应用程序运行时)会发生什么:
“onResume”被调用 - 这会检测设备并请求许可。创建一个意图过滤器以捕获 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();
}
【问题讨论】:
标签: java usb android-studio intentfilter android-permissions