Android的联通性---USB主机模式(三)

获取跟设备通信的权限

在跟USB设备进行通信之前,你的应用程序必须要获取用户的许可。

注意:如果你的应用程序使用Intent过滤器来发现接入的USB设备,而且用户允许你的应用程序处理该Intent,那么它会自动的接收权限,否则,在你的应用程序接入该设备之前,必须明确的申请权限。

明确的申请权限在某些情况下是必须的,如你的应用程序列举已经接入的USB设备并想要跟其中的一个设备通信的时候。在试图跟一个设备通信之前,你必须要检查是否有访问设备的权限。否则,如果用户拒绝了你访问该设备的请求,你会收到一个运行时错误。

要明确的获取这个权限,首先要创建一个广播接收器。这个接收器用于监听你调用requestPermission()方法时,系统所发出的Intent对象。调用requestPermission()方法时,系统会显示一个对话框,询问用户是否允许跟该USB设备进行连接。下列代码演示如何创建这个广播接收器:

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

                   }

                }

                else {

                    Log.d(TAG, "permission denied for device " + device);

                }

            }

        }

    }

};

在你的Activity中的onCreate()方法中添加注册该广播接收器的代码:

UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);

private static final String ACTION_USB_PERMISSION =

    "com.android.example.USB_PERMISSION";

...

mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);

IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);

registerReceiver(mUsbReceiver, filter);

调用requestPermission()方法,显示申请接入设备的权限的对话框:

UsbDevice device;

...

mUsbManager.requestPermission(device, mPermissionIntent);

当用户应答了该对话框时,你的广播接收器就会收到一个包含EXTRA_PERMISSINO_GRANTED类型附加字段的Intent对象,该字段用一个布尔值来代表回答结果。在连接该设备之前,要检查这个字段的值是否是true。

跟设备进行通信

跟USB设备的通信既可以是异步的,也可以是同步的。在异步的情况下,你应该创建一个线程来执行所有的数据传输,以便不至于阻塞UI线程。要正确的建立跟设备的通信,你需要获得准备与其通信的设备所对应的UsbInterface和UsbEndpoint对象,并且使用UsbDeviceConnection对象把请求发送给这个端点。通常步骤如下:

1.       检查UsbDevice对象的属性,如产品ID、供应商ID、或者设备的分类,判断该设备是否是你所想要的设备;

2.       当你确认它是你想要与其通信的设备时,就要找到该设备对应的UsbInterface对象以及跟该接口对象一起的UsbEndpoint对象。接口可以有一个或多个端点,通常会有用于双工通信的输入和输出端点;

3.       当你找正确的端点时,就可以打开一个该端点上的UsbDeviceConnection对象;

4.       使用bulkTransfer()或controlTransfer()方法,把你想要传输的数据提供给端点。你应该在另外一个线程中执行本步骤的操作,以便防止阻塞主UI线程。

以下代码片段是一个普通的同步传输数据的方法。你的代码应该有更多的逻辑用于查找用来通信的正确的接口和端点,并且还应该在一个不同于主UI线程的线程中来进行数据传输:

private Byte[] bytes

private static int TIMEOUT = 0;

private boolean forceClaim = true;

 

...

 

UsbInterface intf = device.getInterface(0);

UsbEndpoint endpoint = intf.getEndpoint(0);

UsbDeviceConnection connection = mUsbManager.openDevice(device);

connection.claimInterface(intf, forceClaim);

connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT); //do in another thread

要异步的发送数据,就要使用UsbRequest类来进行初始化,并发送一个异步请求,让后用requestWait()方法等待结果。

更多的信息请看Adb test sample,它显示了怎样进行异步块数据数据传输,MissleLauncher sample显示了如何监听异步的中断端点。

中断跟设备的通信

在你完成跟设备的通信,或者设备被分离时,就要调用releaseInterface()方法和close()方法来关闭UsbInterface和UsbDeviceConnection对象。创建下面这样的广播接收器来监听分离事件:

BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

    public void onReceive(Context context, Intent intent) {

        String action = intent.getAction();

 

      if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {

            UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

            if (device != null) {

                // call your method that cleans up and closes communication with the device

            }

        }

    }

};

如果在应用程序中创建广播接收器,但没有在清单中注册,那么就允许你的应用程序只在运行时处理分离事件。这种情况下,分离事件只会发送给当前运行的应用程序,并且不是广播给所有的应用程序
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值