列舉裝置

Windows.Devices.Enumeration API 可讓您尋找內部連接至系統、外部連接,或可透過無線或網路通訊協定偵測到的裝置。

Samples

列舉所有可用裝置最簡單的方法是使用 FindAllAsync 指令擷取快照(以下章節會有詳細說明)。

async void enumerateSnapshot(){
  DeviceInformationCollection collection = await DeviceInformation.FindAllAsync();
}

請參閱 裝置列舉與配對範例,以查看 Windows.Devices.Enumeration API 的更進階範例。

列舉 API

Windows。Devices.列舉命名空間允許您尋找系統內部連接、外部連接,或可透過無線或網路協定偵測的裝置。 這些 API 支援的一些功能包括:

  • 找到一個裝置來連接你的應用程式。
  • 取得系統連接或可偵測裝置的資訊。
  • 讓應用程式在裝置新增、連接、斷線、更改線上狀態或其他屬性時收到通知。
  • 讓應用程式在裝置連接、斷線、更改線上狀態或更改其他屬性時,會收到背景觸發。

這些 API 可以在以下任一協定與匯流排上列舉裝置,前提是該裝置及其執行該應用程式的系統支援該技術。 這並非完整清單,且特定裝置可能支援其他協定。

在許多情況下,你不必擔心使用列舉 API。 這是因為許多使用裝置的 API 會自動選擇適當的預設裝置,或提供更簡化的列舉 API。 例如,MediaElement會自動使用預設的音訊渲染器裝置。 只要你的應用程式能使用預設裝置,就不需要在應用程式中使用列舉 API。 列舉 API 提供一種通用且靈活的方式,讓你能發現並連接可用裝置。 本主題提供關於枚舉裝置的資訊,並說明四種常見的枚舉裝置方式。

  • 使用 DevicePicker 介面
  • 列舉系統目前可偵測的裝置快照
  • 列舉目前可偵測的裝置並留意變化
  • 列舉目前可被發現的裝置,並觀察背景任務的變化

DeviceInformation 物件

使用列舉 API 時,你經常需要使用 DeviceInformation 物件。 這些物件包含了大部分關於該裝置的可用資訊。 下表說明了你會感興趣的一些 DeviceInformation 屬性。 完整清單請參閱 DeviceInformation 的參考頁面。

Property 附註
DeviceInformation.Id 這是裝置的唯一識別碼,並以字串變數形式提供。 大多數情況下,這是一個不透明的數值,你只需從一種方法傳遞到另一種,用來指示你感興趣的特定裝置。 你也可以在關閉應用程式再重新開啟後,使用這個屬性和 DeviceInformation.Kind 屬性。 這樣可以確保你能復原並重複使用同一個 DeviceInformation 物件。
裝置資訊。種類 這表示 DeviceInformation 物件所代表的裝置物件種類。 這不是裝置類別或裝置類型。 單一裝置可由多個不同類型的 DeviceInformation 物件表示。 此屬性的可能值列於 DeviceInformationKind 中,並列出它們之間的關係。
裝置資訊.屬性 此屬性袋包含DeviceInformation物件所請求的資訊。 最常見的屬性很容易被參考為 DeviceInformation 物件的屬性,例如 DeviceInformation.Name。 欲了解更多資訊,請參閱 裝置資訊屬性

 

DevicePicker 使用者介面

DevicePicker 是由 Windows 提供的一個控制項,能建立一個小型使用者介面,讓使用者能從清單中選擇裝置。 它可以透過幾種方式進行客製化,例如:

  • 透過將 SupportedDeviceSelectorsSupportedDeviceClasses 或兩者同時新增至 DevicePicker.Filter,即可控制 UI 中顯示的裝置。 大多數情況下,你只需要新增一個選擇器或職業,但如果需要多個,也可以加多個。 如果你真的加入多個選擇器或類別,它們會用 OR 邏輯函數串聯起來。
  • 指定你想為裝置取得的屬性。 你可以透過在 DevicePicker.RequestedProperties 中新增屬性來達成這個目標。
  • 使用 Appearance 變更 DevicePicker 的外觀。
  • 在顯示 DevicePicker 時,請指定其大小與位置。

雖然顯示 DevicePicker,但若裝置被新增、移除或更新,介面內容會自動更新。

Note

你無法用 DevicePicker 來指定 DeviceInformationKind。 如果你想要取得特定 DeviceInformationKind 類型的裝置,就需要建構一個 DeviceWatcher,並自行提供使用者介面。

投放媒體內容和 DIAL 也各自提供專屬的選取器,供你在需要時使用。 它們分別是 CastingDevicePickerDialDevicePicker

列舉裝置快照

在某些情況下,DevicePicker 不適合你的需求,你需要更靈活的方案。 也許你想建立自己的 UI,或是需要列舉裝置但不讓使用者看到 UI。 在這些情況下,你可以列舉裝置快照。 這需要檢視目前連接或配對系統的裝置。 不過你要注意,這個方法只會查看可用裝置的快照,所以你在列舉清單後,無法找到有連線的裝置。 裝置更新或移除時,也不會通知您。 另一個潛在缺點是,這種方法會延遲結果,直到整個列舉完成。 因此,當你對 AssociationEndpointAssociationEndpointContainerAssociationEndpointService 物件感興趣時,不應使用此方法,因為它們是透過網路或無線協定找到的。 完成時間可能長達30秒。 在這種情況下,你應該使用 DeviceWatcher 物件來枚舉可能的裝置。

若要透過裝置快照列舉,請使用 FindAllAsync 方法。 此方法等待整個列舉過程完成,並將所有結果作為一個 DeviceInformationCollection 物件回傳。 這個方法也提供多載版本,讓你可使用多種選項來篩選結果,並將結果限制為你感興趣的裝置。 你可以透過提供 DeviceClass 或輸入裝置選擇器來達成。 裝置選擇器是一個進階查詢語法(AQS)字串,用來指定你想要列舉的裝置。 欲了解更多資訊,請參閱 「建構裝置選擇器」。

除了限制結果外,你也可以指定想要為裝置檢索的屬性。 如果這樣做,則該集合中傳回的每個 DeviceInformation 物件,其指定的屬性即可在屬性包中取得。 值得注意的是,並非所有裝置類型都能取得所有屬性。 欲了解每種裝置類型可用的屬性,請參閱 裝置資訊屬性

列出並監看裝置

一種更強大且靈活的裝置列舉方法是建立 DeviceWatcher。 這個選項在列舉裝置時提供了最大的彈性。 它允許你列舉目前存在的裝置,並且當符合你裝置選擇器的裝置被新增、移除或屬性變更時,也會收到通知。 當你建立 DeviceWatcher 時,你會提供一個裝置選擇器。 欲了解更多裝置選擇器的資訊,請參閱 「建構裝置選擇器」。 建立監視器後,您將收到符合您條件的任何裝置的以下通知。

  • 新增裝置時加入通知。
  • 當您感興趣的房產變更時,更新通知。
  • 當裝置不再可用或不再符合你的過濾器時,請移除通知。

在大多數情況下,當你使用 DeviceWatcher,你是在維護一個裝置清單,並在監視者收到你所監視裝置的更新時,新增、移除或更新項目。 當您收到更新通知時,更新後的資訊將以 DeviceInformationUpdate 物件的形式提供。 若要更新您的裝置清單,請先找出已變更的 DeviceInformation。 接著呼叫該物件的 Update 方法,並提供 DeviceInformationUpdate 物件。 這是一個方便的功能,會自動更新你的 DeviceInformation 物件。

由於 DeviceWatcher 會在裝置到達以及發生變更時傳送通知,因此如果您對 AssociationEndpointAssociationEndpointContainerAssociationEndpointService 物件有興趣,則應使用這種列舉裝置的方法,因為這些物件是透過網路或無線通訊協定列舉的。

要建立 DeviceWatcher,請使用 CreateWatcher 方法之一。 這些方法會被超載,讓你能指定你感興趣的裝置。 你可以透過提供 DeviceClass 或輸入裝置選擇器來達成。 裝置選擇器是 AQS 字串,用來指定你想列舉的裝置。 欲了解更多資訊,請參閱 「建構裝置選擇器」。 你也可以指定想要為裝置取得且感興趣的屬性。 如果這樣做,則該集合中傳回的每個 DeviceInformation 物件,其指定的屬性即可在屬性包中取得。 值得注意的是,並非所有裝置類型都能取得所有屬性。 欲了解不同裝置類型可用的屬性,請參閱 裝置資訊屬性

作為背景任務的手錶裝置

以背景工作監看裝置,與如上所述建立 DeviceWatcher 非常相似。 事實上,你仍然需要先建立一個正常的 DeviceWatcher 物件,如前一節所述。 建立之後,應呼叫 GetBackgroundTrigger,而不是 DeviceWatcher.Start。 當你呼叫 GetBackgroundTrigger 時,必須指定你感興趣的通知:新增、移除或更新。 若未同時要求新增,就不能要求更新或移除。 一旦你註冊觸發器, DeviceWatcher 會立即在背景開始執行。 從現在起,每當系統收到一則針對你的應用程式且符合你所設定條件的新通知時,背景任務就會觸發,並提供自上次觸發你的應用程式以來的最新變更。

Important

DeviceWatcherTrigger 第一次觸發您的應用程式時,會是在監看程式到達 EnumerationCompleted 狀態時。 這表示它會包含所有初始結果。 未來每次觸發你的應用程式時,只會包含自上次觸發以來的新增、更新和移除通知。 這與前景DeviceWatcher物件略有不同,因為初始結果不會逐一出現,而是在達到 EnumerationCompleted 後以組合形式呈現。

有些無線協定在背景掃描與前景掃描時行為不同,甚至可能根本不支援背景掃描。 關於背景掃描,有三種可能性。 下表列出了這些可能性以及這對您的申請可能產生的影響。 例如,藍牙和 Wi-Fi Direct 不支援背景掃描,因此也無法支援 DeviceWatcherTrigger

行為 影響
背景中同樣的行為 None
只能在背景中進行被動掃描 在等待被動掃描期間,裝置可能會花更長時間才能被發現。
不支援背景掃描 DeviceWatcherTrigger不會偵測到任何裝置,也不會報告任何更新。

 如果你的 DeviceWatcherTrigger 包含不支援掃描作為背景任務的協定,你的觸發器仍然會運作。 不過,你無法透過該方案獲得任何更新或結果。 其他協定或裝置的更新仍會正常被偵測到。

使用 DeviceInformationKind

在大多數情況下,您不必擔心 DeviceInformation 物件的 DeviceInformationKind。 這是因為你所使用的裝置 API 傳回的裝置選擇器,通常能確保你取得可搭配該 API 使用的正確類型裝置物件。 不過,在某些情況下,你會想要取得裝置 資訊 ,但沒有對應的裝置 API 來提供裝置選擇器。 在這些情況下,你將需要自行建立選擇器。 例如,Web Services on Devices 沒有專用的 API,但你可以使用 Windows.Devices.Enumeration API 來探索這些裝置並取得其相關資訊,然後再使用通訊端 API 來使用這些裝置。

如果你正在建立自己的裝置選取器,以列舉裝置物件,DeviceInformationKind 會是你必須了解的重要概念。 所有可能的類型及其彼此關係,皆在 DeviceInformationKind 的參考頁面上有說明。 DeviceInformationKind 最常見的用途之一是,在與裝置選擇器一起提交查詢時,指定你要搜尋哪種裝置。 透過這樣做,可確保只枚舉符合指定 DeviceInformationKind 的裝置。 舉例來說,你可以找到一個 DeviceInterface 物件,然後執行查詢以取得父 裝置 物件的資訊。 該父物件可能包含額外資訊。

值得注意的是,DeviceInformation 物件之屬性包中可用的屬性會因裝置的 DeviceInformationKind 而異。 某些屬性僅適用於特定種類。 欲了解更多關於哪些屬性適用於不同類型,請參閱 裝置資訊屬性。 因此,在上述範例中,搜尋父 裝置 將讓你獲得更多 DeviceInterface 裝置物件無法取得的資訊。 因此,當你建立 AQS 濾波器字串時,務必確保你列舉的 DeviceInformationKind 物件所請求的屬性可用。 欲了解更多關於建立過濾器的資訊,請參閱 「建構裝置選擇器」。

當你列舉 AssociationEndpointAssociationEndpointContainerAssociationEndpointService 物件時,你是在無線或網路協定上枚舉。 在這種情況下,我們建議你不要使用 FindAllAsync ,而是使用 CreateWatcher。 這是因為透過網路進行搜尋時,搜尋作業通常在產生 EnumerationCompleted 之前,10 秒或更久都不會逾時。 FindAllAsync 直到 EnumerationCompleted 被觸發後才會完成操作。 如果你使用 DeviceWatcher,無論何時呼叫 EnumerationCompleted,都能接近即時獲得結果。

將裝置保存以備後用

任何 DeviceInformation 物件都可藉由兩項資訊的組合加以唯一識別:DeviceInformation.IdDeviceInformation.Kind。 如果你保留這兩項資訊,可以在遺失後將 DeviceInformation 物件提供給 CreateFromIdAsync 來重建。 如果你這麼做,可以儲存使用者偏好設定,讓裝置能與你的應用程式整合。