Android的联通性---USB主机模式(三)
獲取跟設(shè)備通信的權(quán)限
在跟USB設(shè)備進行通信之前,你的應(yīng)用程序必須要獲取用戶的許可。
注意:如果你的應(yīng)用程序使用Intent過濾器來發(fā)現(xiàn)接入的USB設(shè)備,而且用戶允許你的應(yīng)用程序處理該Intent,那么它會自動的接收權(quán)限,否則,在你的應(yīng)用程序接入該設(shè)備之前,必須明確的申請權(quán)限。
明確的申請權(quán)限在某些情況下是必須的,如你的應(yīng)用程序列舉已經(jīng)接入的USB設(shè)備并想要跟其中的一個設(shè)備通信的時候。在試圖跟一個設(shè)備通信之前,你必須要檢查是否有訪問設(shè)備的權(quán)限。否則,如果用戶拒絕了你訪問該設(shè)備的請求,你會收到一個運行時錯誤。
要明確的獲取這個權(quán)限,首先要創(chuàng)建一個廣播接收器。這個接收器用于監(jiān)聽你調(diào)用requestPermission()方法時,系統(tǒng)所發(fā)出的Intent對象。調(diào)用requestPermission()方法時,系統(tǒng)會顯示一個對話框,詢問用戶是否允許跟該USB設(shè)備進行連接。下列代碼演示如何創(chuàng)建這個廣播接收器:
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);
調(diào)用requestPermission()方法,顯示申請接入設(shè)備的權(quán)限的對話框:
UsbDevice device;
...
mUsbManager.requestPermission(device, mPermissionIntent);
當(dāng)用戶應(yīng)答了該對話框時,你的廣播接收器就會收到一個包含EXTRA_PERMISSINO_GRANTED類型附加字段的Intent對象,該字段用一個布爾值來代表回答結(jié)果。在連接該設(shè)備之前,要檢查這個字段的值是否是true。
跟設(shè)備進行通信
跟USB設(shè)備的通信既可以是異步的,也可以是同步的。在異步的情況下,你應(yīng)該創(chuàng)建一個線程來執(zhí)行所有的數(shù)據(jù)傳輸,以便不至于阻塞UI線程。要正確的建立跟設(shè)備的通信,你需要獲得準備與其通信的設(shè)備所對應(yīng)的UsbInterface和UsbEndpoint對象,并且使用UsbDeviceConnection對象把請求發(fā)送給這個端點。通常步驟如下:
1.?????? 檢查UsbDevice對象的屬性,如產(chǎn)品ID、供應(yīng)商ID、或者設(shè)備的分類,判斷該設(shè)備是否是你所想要的設(shè)備;
2.?????? 當(dāng)你確認它是你想要與其通信的設(shè)備時,就要找到該設(shè)備對應(yīng)的UsbInterface對象以及跟該接口對象一起的UsbEndpoint對象。接口可以有一個或多個端點,通常會有用于雙工通信的輸入和輸出端點;
3.?????? 當(dāng)你找正確的端點時,就可以打開一個該端點上的UsbDeviceConnection對象;
4.?????? 使用bulkTransfer()或controlTransfer()方法,把你想要傳輸?shù)臄?shù)據(jù)提供給端點。你應(yīng)該在另外一個線程中執(zhí)行本步驟的操作,以便防止阻塞主UI線程。
以下代碼片段是一個普通的同步傳輸數(shù)據(jù)的方法。你的代碼應(yīng)該有更多的邏輯用于查找用來通信的正確的接口和端點,并且還應(yīng)該在一個不同于主UI線程的線程中來進行數(shù)據(jù)傳輸:
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
要異步的發(fā)送數(shù)據(jù),就要使用UsbRequest類來進行初始化,并發(fā)送一個異步請求,讓后用requestWait()方法等待結(jié)果。
更多的信息請看Adb test sample,它顯示了怎樣進行異步塊數(shù)據(jù)數(shù)據(jù)傳輸,MissleLauncher sample顯示了如何監(jiān)聽異步的中斷端點。
中斷跟設(shè)備的通信
在你完成跟設(shè)備的通信,或者設(shè)備被分離時,就要調(diào)用releaseInterface()方法和close()方法來關(guān)閉UsbInterface和UsbDeviceConnection對象。創(chuàng)建下面這樣的廣播接收器來監(jiān)聽分離事件:
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
???????????}
???????}
???}
};
如果在應(yīng)用程序中創(chuàng)建廣播接收器,但沒有在清單中注冊,那么就允許你的應(yīng)用程序只在運行時處理分離事件。這種情況下,分離事件只會發(fā)送給當(dāng)前運行的應(yīng)用程序,并且不是廣播給所有的應(yīng)用程序
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的Android的联通性---USB主机模式(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: H.264视频编解码的代码移植和优化
- 下一篇: Android数据存储之SQLite