我正在编写一个Android USB主机应用程序,我试图枚举与平板电脑连接的设备。我按照开发人员站点中的android USB主机文档中的代码进行操作。
我的代码如下
AndroidUSBActivity
public class AndroidUSBActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
USBClass usb = new USBClass();
ArrayList<String> deviceList = usb.GetUSBDevices(getBaseContext());
final CharSequence[] items = deviceList.toArray(new CharSequence[deviceList.size()]);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select a Reader");
builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
String selectedDevice = (String) items[item];
dialog.dismiss();
TextView DeivceName = (TextView)findViewById(R.id.textView1);
DeivceName.setText(selectedDevice);
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
USBClass
public class USBClass {
private static UsbManager mManager = null;
private static HashMap<String, UsbDevice> mdevices;
private static PendingIntent mPermissionIntent;
private static final String ACTION_USB_PERMISSION =
"com.android.example.USB_PERMISSION";
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(device != null){
//call method to set up device communication
Log.i("usb", "permission granted for device " + device);
}
}
else {
Log.i("usb", "permission denied for device " + device);
}
}
}
}
};
public ArrayList<String> GetUSBDevices(Context context){
mManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
mdevices = new HashMap<String, UsbDevice>();
ArrayList<String> deviceList = new ArrayList<String>();
mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent("com.android.example.USB_PERMISSION"), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
context.registerReceiver(mUsbReceiver, filter);
// check for existing devices
for (UsbDevice device : mManager.getDeviceList().values()) {
String deviceName = null;
UsbDeviceConnection connection = null;
if(device.getVendorId() == 0x0123){
mManager.requestPermission(device, mPermissionIntent);
connection = mManager.openDevice(device);
byte rawBuf[] = new byte[255];
int len = connection.controlTransfer(0x80, 0x06, 0x0302, 0x0409, rawBuf, 0x00FF, 60);
rawBuf = Arrays.copyOfRange(rawBuf, 2, len);
deviceName = new String(rawBuf);
deviceList.add(deviceName);
mdevices.put(deviceName, device);
}
}
context.unregisterReceiver(mUsbReceiver);
return deviceList;
}
}
logcat的
06-13 10:13:54.556: D/dalvikvm(2219): Late-enabling CheckJNI
06-13 10:13:54.586: I/System.out(2219): Sending WAIT chunk
06-13 10:13:54.586: W/ActivityThread(2219): Application bri.sample is waiting for the debugger on port 8100...
06-13 10:13:54.596: I/dalvikvm(2219): Debugger is active
06-13 10:13:54.786: I/System.out(2219): Debugger has connected
06-13 10:13:54.786: I/System.out(2219): waiting for debugger to settle...
06-13 10:13:54.986: I/System.out(2219): waiting for debugger to settle...
06-13 10:13:55.186: I/System.out(2219): waiting for debugger to settle...
06-13 10:13:55.406: I/System.out(2219): waiting for debugger to settle...
06-13 10:13:55.596: I/System.out(2219): waiting for debugger to settle...
06-13 10:13:55.796: I/System.out(2219): waiting for debugger to settle...
06-13 10:13:55.996: I/System.out(2219): waiting for debugger to settle...
06-13 10:13:56.206: I/System.out(2219): waiting for debugger to settle...
06-13 10:13:56.406: I/System.out(2219): waiting for debugger to settle...
06-13 10:13:56.645: I/System.out(2219): waiting for debugger to settle...
06-13 10:13:56.846: I/System.out(2219): debugger has settled (1337)
06-13 10:13:57.116: E/UsbManager(2219): exception in UsbManager.openDevice
06-13 10:13:57.116: E/UsbManager(2219): java.lang.SecurityException: User has not given permission to device UsbDevice[mName=/dev/bus/usb/001/004,mVendorId=1254,mProductId=20758,mClass=0,mSubclass=0,mProtocol=0,mInterfaces=[Landroid.hardware.usb.UsbInterface;@41679100]
06-13 10:13:57.116: E/UsbManager(2219): at android.os.Parcel.readException(Parcel.java:1327)
06-13 10:13:57.116: E/UsbManager(2219): at android.os.Parcel.readException(Parcel.java:1281)
06-13 10:13:57.116: E/UsbManager(2219): at android.hardware.usb.IUsbManager$Stub$Proxy.openDevice(IUsbManager.java:340)
06-13 10:13:57.116: E/UsbManager(2219): at android.hardware.usb.UsbManager.openDevice(UsbManager.java:250)
06-13 10:13:57.116: E/UsbManager(2219): at bri.sample.USBClass.GetUSBDevices(USBClass.java:66)
06-13 10:13:57.116: E/UsbManager(2219): at bri.sample.AndroidUSBActivity.onCreate(AndroidUSBActivity.java:19)
06-13 10:13:57.116: E/UsbManager(2219): at android.app.Activity.performCreate(Activity.java:4465)
06-13 10:13:57.116: E/UsbManager(2219): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
06-13 10:13:57.116: E/UsbManager(2219): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
06-13 10:13:57.116: E/UsbManager(2219): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
06-13 10:13:57.116: E/UsbManager(2219): at android.app.ActivityThread.access$600(ActivityThread.java:123)
06-13 10:13:57.116: E/UsbManager(2219): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
06-13 10:13:57.116: E/UsbManager(2219): at android.os.Handler.dispatchMessage(Handler.java:99)
06-13 10:13:57.116: E/UsbManager(2219): at android.os.Looper.loop(Looper.java:137)
06-13 10:13:57.116: E/UsbManager(2219): at android.app.ActivityThread.main(ActivityThread.java:4424)
06-13 10:13:57.116: E/UsbManager(2219): at java.lang.reflect.Method.invokeNative(Native Method)
06-13 10:13:57.116: E/UsbManager(2219): at java.lang.reflect.Method.invoke(Method.java:511)
06-13 10:13:57.116: E/UsbManager(2219): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
06-13 10:13:57.116: E/UsbManager(2219): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
06-13 10:13:57.116: E/UsbManager(2219): at dalvik.system.NativeStart.main(Native Method)
06-13 10:13:57.566: D/dalvikvm(2219): threadid=1: still suspended after undo (sc=1 dc=1)
06-13 10:14:04.266: D/AndroidRuntime(2219): Shutting down VM
06-13 10:14:04.266: W/dalvikvm(2219): threadid=1: thread exiting with uncaught exception (group=0x40a531f8)
06-13 10:14:04.296: E/AndroidRuntime(2219): FATAL EXCEPTION: main
06-13 10:14:04.296: E/AndroidRuntime(2219): java.lang.RuntimeException: Unable to start activity ComponentInfo{bri.sample/bri.sample.AndroidUSBActivity}: java.lang.NullPointerException
06-13 10:14:04.296: E/AndroidRuntime(2219): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
06-13 10:14:04.296: E/AndroidRuntime(2219): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
06-13 10:14:04.296: E/AndroidRuntime(2219): at android.app.ActivityThread.access$600(ActivityThread.java:123)
06-13 10:14:04.296: E/AndroidRuntime(2219): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
06-13 10:14:04.296: E/AndroidRuntime(2219): at android.os.Handler.dispatchMessage(Handler.java:99)
06-13 10:14:04.296: E/AndroidRuntime(2219): at android.os.Looper.loop(Looper.java:137)
06-13 10:14:04.296: E/AndroidRuntime(2219): at android.app.ActivityThread.main(ActivityThread.java:4424)
06-13 10:14:04.296: E/AndroidRuntime(2219): at java.lang.reflect.Method.invokeNative(Native Method)
06-13 10:14:04.296: E/AndroidRuntime(2219): at java.lang.reflect.Method.invoke(Method.java:511)
06-13 10:14:04.296: E/AndroidRuntime(2219): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
06-13 10:14:04.296: E/AndroidRuntime(2219): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
06-13 10:14:04.296: E/AndroidRuntime(2219): at dalvik.system.NativeStart.main(Native Method)
06-13 10:14:04.296: E/AndroidRuntime(2219): Caused by: java.lang.NullPointerException
06-13 10:14:04.296: E/AndroidRuntime(2219): at bri.sample.USBClass.GetUSBDevices(USBClass.java:68)
06-13 10:14:04.296: E/AndroidRuntime(2219): at bri.sample.AndroidUSBActivity.onCreate(AndroidUSBActivity.java:19)
06-13 10:14:04.296: E/AndroidRuntime(2219): at android.app.Activity.performCreate(Activity.java:4465)
06-13 10:14:04.296: E/AndroidRuntime(2219): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
06-13 10:14:04.296: E/AndroidRuntime(2219): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
06-13 10:14:04.296: E/AndroidRuntime(2219): ... 11 more
问题
我已插入设备,然后安装应用程序。 第一次,当应用程序启动时,它会崩溃。
答案 0 :(得分:12)
当您尝试使用
访问设备时发生崩溃connection = mManager.openDevice(device);
由于您未获得用户使用该设备的许可而导致SecurityException
崩溃,因此崩溃了。看起来您试图在此
mManager.requestPermission(device, mPermissionIntent);
但您需要了解对requestPermission()
的调用是异步的。它不会立即返回许可。它的作用是向用户显示一个对话框并询问用户是否将授予您的应用程序权限。一旦用户授予或拒绝权限,对话框将被解除,并且您传递给PendingIntent
的{{1}}用于广播指示已授予(或未授予)权限的Intent。您需要在已注册的requestPermission()
中监听此内容,并且当调用BroadcastReceiver
方法时,您可以检查收到的onReceive()
中的附加内容并决定如何继续。只有用户授予您权限,您才能继续致电Intent
。
这听起来有点复杂,但这就是它的工作方式。
基本上,你需要打电话
openDevice()
然后等到您尝试访问设备之前已经授予权限。