usbmanger android 底下USB的工作模式


Android USB開發麻煩還是比較多的。

第一種:host模式

這種模式比較不錯,由Android設備提供電源,然后與外部設備通信。舉個例子來說:電腦連接USB設備,都是這個模式,非常常見的模式。

但是有一個萬惡的問題,android接外部USB設備的時候,驅動怎么辦?又有那款芯片敢說Android系統支持他們家的芯片,又有哪個廠家說不動android系統裝上他們家的驅動,他們家的設備就可以在Android上使用,或許這點上Android很難超越windows。

造成想現狀:想加外部設備,都要:重新自己做底層驅動程序--->編譯系統--->刷機--->編寫android程序--->接入硬件實現功能。

整個一套下來飯都吃好幾頓了。還是希望以后android發展發展能向window一樣支持多設備驅動吧。

 

第二種:Accessory模式

這個模式比較揪心,外部設備要供給電源,數據間通信:電腦---手機就是這種模式,手機作為Accessory設備,電腦供給它電源,同時進行數據通信。

恰巧我也是用了這種模式:

程序需要做的:

(1)添加Action BoardCast

private static final String ACTION_USB_PERMISSION ="com.ukey.USB_PERMISSION";

 

[java]
        /***********************USB handling******************************************/
        usbmanager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        
        filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);        
        context.registerReceiver(mUsbReceiver, filter);
        inputstream = null;
        outputstream = null;

 

(2)編寫對應的boradCaset信息

 

    /***********USB broadcast receiver*******************************************/
    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() 
    {
        @Override
        public void onReceive(Context context, Intent intent) 
        {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) 
            {
                synchronized (this)
                {
                    UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
                    {
                        Toast.makeText(global_context, "Allow USB Permission", Toast.LENGTH_SHORT).show();
                        OpenAccessory(accessory);    
                        
                    }else{
                        Toast.makeText(global_context, "Deny USB Permission", Toast.LENGTH_SHORT).show();
                    }
                    mPermissionRequestPending = false;
                }
            } 
            else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)){
                DestroyAccessory(true);
            }else{
                Log.d("LED", "....");
            }
        }
    };

 

 

 
(3)又來一個比較麻煩的事

 

android每次使用Accessory的時候都會詢問你是否允許設備訪問,這會點擊是或否的結果又(2)中代碼

 

if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))

啟動請求。

 

(4)openAccessory功能

 

    public int OpenAccessory()
    {
        // Intent intent = getIntent();
        if (inputstream != null && outputstream != null) {
            return 1;
        }
        UsbAccessory[] accessories = usbmanager.getAccessoryList();
        if(accessories != null){
            Toast.makeText(global_context, "Accessory Attached", Toast.LENGTH_SHORT).show();
        }else{
            // return 2 for accessory detached case
            return 2;
        }
        UsbAccessory accessory = (accessories == null ? null : accessories[0]);
        if (accessory != null) {
            if( -1 == accessory.toString().indexOf(ManufacturerString)){
                Toast.makeText(global_context, "Manufacturer is not matched!", Toast.LENGTH_SHORT).show();
                return 1;
            }
            if( -1 == accessory.toString().indexOf(ModelString1) && -1 == accessory.toString().indexOf(ModelString2))
            {
                Toast.makeText(global_context, "Model is not matched!", Toast.LENGTH_SHORT).show();
                return 1;
            }if( -1 == accessory.toString().indexOf(VersionString))
            {
                Toast.makeText(global_context, "Version is not matched!", Toast.LENGTH_SHORT).show();
                return 1;
            }
            Toast.makeText(global_context, "Manufacturer, Model & Version are matched!", Toast.LENGTH_SHORT).show();
            if (usbmanager.hasPermission(accessory)) {
                OpenAccessory(accessory);
            }else{
                synchronized (mUsbReceiver) {
                    if (!mPermissionRequestPending) {
                        Toast.makeText(global_context, "Request USB Permission", Toast.LENGTH_SHORT).show();
                        usbmanager.requestPermission(accessory,mPermissionIntent);
                        mPermissionRequestPending = true;
                    }
                }
            }
        }
        return 0;
    }

 

跟設備一起工作

當用戶把USB設備接入到Android設備上時,Android系統能夠判斷你的應用程序是否對接入的設備感興趣。如果是你的應用程序感興趣的設備,你就可以跟你期望的設備建立通信。以下是你的應用程序必須要做的工作:

1.使用以下兩種方法之一來發現接入的UDB設備:

A.使用Intent過濾器,過濾用戶接入USB設備時所發出的通知;

B.列舉已經接入的USB設備。

2.如果沒獲取接入USB設備的權限,會向用戶請求接入USB設備的權限。

3.通過讀寫對應接口端點上的數據來跟USB設備通信。

發現設備

用戶既可以通過使用用戶接入USB設備時所發出Intent過濾通知,也可以通過列舉已經接入的USB設備,來發現USB設備。如果你希望你的應用程序能夠自動的檢測到你所期望的USB設備,那么要使用Intent過濾器。如果你想要過的接入的所有的已經接入的設備列表,或者是你的應用程序沒有過濾對應的Intent對象,那么要使用列舉的方法。

使用Intent過濾器

為了讓你的應用程序發現一個特殊的USB設備,你可以指定一個android.hardware.usb.action.USB_DEVICE_ATTACHED類型的Intent過濾器。跟這個Intent過濾器一起,你還需要指定一個指定了USB設備屬性的資源文件,如果產品和供應商ID。當用戶接入的設備跟你的設備過濾器匹配的時候,系統會顯示一個對話框,詢問你是否允許它們啟動你的應用程序。如果用戶接收,應用程序會自動的被授予訪問設備的權限,一直到設備斷開連接。

以下示例演示了如何聲明Intent過濾器:

<activity ...>

...

<intent-filter>

<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />

</intent-filter>

 

<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"

android:resource="@xml/device_filter" />

</activity>

以下示例演示了如何聲明對應的你感興趣的USB設備的資源文件:

<?xml version="1.0" encoding="utf-8"?>

 

<resources>

<usb-device vendor-id="1234" product-id="5678" />

</resources>

 

在你的Activity中,按照如下的方法,你可以從Intent對象中獲得一個代表接入的設備的UsbDevice對象:

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

 

列舉設備

當你的應用程序要在運行時檢測當前接入的所有的USB設備時,它可以列舉總線上的設備。使用getDeviceList()方法來獲取已經接入的所有的USB設備的hash map。該hash map使用USB設備的名稱做key:

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

...

HashMap<String, UsbDevice> deviceList = manager.getDeviceList();

UsbDevice device = deviceList.get("deviceName");

 

如果你願意,也可以使用hash map的迭代器來處理每個設備:

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

...

HashMap<String, UsbDevice> deviceList = manager.getDeviceList();

Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();

while(deviceIterator.hasNext()){

UsbDevice device = deviceIterator.next()

//your code

}

 

跟設備一起工作

當用戶把USB設備接入到Android設備上時,Android系統能夠判斷你的應用程序是否對接入的設備感興趣。如果是你的應用程序感興趣的設備,你就可以跟你期望的設備建立通信。以下是你的應用程序必須要做的工作:

1.使用以下兩種方法之一來發現接入的UDB設備:

A.使用Intent過濾器,過濾用戶接入USB設備時所發出的通知;

B.列舉已經接入的USB設備。

2.如果沒獲取接入USB設備的權限,會向用戶請求接入USB設備的權限。

3.通過讀寫對應接口端點上的數據來跟USB設備通信。

發現設備

用戶既可以通過使用用戶接入USB設備時所發出Intent過濾通知,也可以通過列舉已經接入的USB設備,來發現USB設備。如果你希望你的應用程序能夠自動的檢測到你所期望的USB設備,那么要使用Intent過濾器。如果你想要過的接入的所有的已經接入的設備列表,或者是你的應用程序沒有過濾對應的Intent對象,那么要使用列舉的方法。

使用Intent過濾器

為了讓你的應用程序發現一個特殊的USB設備,你可以指定一個android.hardware.usb.action.USB_DEVICE_ATTACHED類型的Intent過濾器。跟這個Intent過濾器一起,你還需要指定一個指定了USB設備屬性的資源文件,如果產品和供應商ID。當用戶接入的設備跟你的設備過濾器匹配的時候,系統會顯示一個對話框,詢問你是否允許它們啟動你的應用程序。如果用戶接收,應用程序會自動的被授予訪問設備的權限,一直到設備斷開連接。

以下示例演示了如何聲明Intent過濾器:

<activity ...>

...

<intent-filter>

<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />

</intent-filter>

 

<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"

android:resource="@xml/device_filter" />

</activity>

 

 

以下示例演示了如何聲明對應的你感興趣的USB設備的資源文件:

<?xml version="1.0" encoding="utf-8"?>

 

<resources>

<usb-device vendor-id="1234" product-id="5678" />

</resources>

 

在你的Activity中,按照如下的方法,你可以從Intent對象中獲得一個代表接入的設備的UsbDevice對象:

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

列舉設備

當你的應用程序要在運行時檢測當前接入的所有的USB設備時,它可以列舉總線上的設備。使用getDeviceList()方法來獲取已經接入的所有的USB設備的hash map。該hash map使用USB設備的名稱做key:

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

...

HashMap<String, UsbDevice> deviceList = manager.getDeviceList();

UsbDevice device = deviceList.get("deviceName");

 

如果你願意,也可以使用hash map的迭代器來處理每個設備:

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

...

HashMap<String, UsbDevice> deviceList = manager.getDeviceList();

Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();

while(deviceIterator.hasNext()){

UsbDevice device = deviceIterator.next()

//your code

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM