Android的USB枚举Android、USB

2023-09-05 11:05:00 作者:细嫩长腿欧巴.

我写一个Android USB主机应用程序,而我试图枚举与平板电脑连接的设备。我按照code。在开发者网站Android的USB主机文档。

I am writing an android USB host application for which i am trying to enumerate the devices connected with tablet. I follow the code in the android USB host documentation in the developer site.

我的code如下:

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

问题

我有插入的设备,然后我安装应用程序。在第一次应用程序启动时,它就会崩溃。

i have the device plugged in and then i install the application. The first time when the application launches, it gets crashed.

Kndly帮帮我,谢谢

Kndly help me, Thank you

推荐答案

当您试图访问该设备与危机来临

The crash comes when you are trying to access the device with

connection = mManager.openDevice(device);

它崩溃,因为它是抛出一个 SecurityException异常,因为你还没有获得许可的用户使用该设备。它看起来像你试图从该行的用户在此之前

It crashes because it is throwing a SecurityException because you haven't obtained permission from the user to use the device. It looks like you tried to obtain permission from the user in the line before this

mManager.requestPermission(device, mPermissionIntent);

但你要明白,在调用 requestPermission()是异步的。它不立即允许返回。它的作用是,它显示了用户一个对话框,询问用户是否他会授予权限,您的应用程序。一旦用户授予或拒绝权限对话框驳回, PendingIntent ,你传递给 requestPermission()用于广播的意图,表示被授予(或没有)的权限。您需要在注册的BroadcastReceiver 的onReceive()方法被调用,您可以再检查侦听此在收到额外意图并决定如何处理。只有当用户授权您可以移动到调用 openDevice()

But you need to understand that the call to requestPermission() is asynchronous. It doesn't return immediately with the permission. What it does is that it shows the user a dialog and asks the user if he will grant permission to your application. Once the user grants or denies permission the dialog is dismissed and the PendingIntent that you passed to requestPermission() is used to broadcast an Intent indicating the permission was granted (or not). You need to listen for this in a registered BroadcastReceiver and when the onReceive() method is called you can then examine the extras in the received Intent and decide how to proceed. Only if the user grants you permission can you move on to call openDevice().

这听起来有点复杂,不过这就是它的工作方式。

This sounds kinda complicated, but that's the way it works.

基本上,你需要调用

mManager.requestPermission(device, mPermissionIntent);

再等到权限被授予您尝试访问该设备之前。

and then wait until permission has been granted before you try to access the device.