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
???????????}
???????}
???}
};
如果在應用程序中創建廣播接收器,但沒有在清單中注冊,那么就允許你的應用程序只在運行時處理分離事件。這種情況下,分離事件只會發送給當前運行的應用程序,并且不是廣播給所有的應用程序
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Android的联通性---USB主机模式(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: H.264视频编解码的代码移植和优化
- 下一篇: android sina oauth2.