Wi-Fi Network Request API cho kết nối ngang hàng

Trên các thiết bị Android 10 (API cấp 29) trở lên, bạn có thể sử dụng API ngang hàng mới để định cấu hình khởi động cho các thiết bị phụ như Chromecast và thiết bị Google Home. Tính năng này cho phép ứng dụng của bạn nhắc người dùng thay đổi điểm truy cập mà thiết bị được kết nối bằng cách sử dụng WifiNetworkSpecifier để mô tả các thuộc tính của mạng được yêu cầu.

Để sử dụng API này, hãy làm như sau:

  1. Tạo thông số mạng Wi-Fi bằng cách sử dụng WifiNetworkSpecifier.Builder.

  2. Thiết lập bộ lọc mạng để khớp với các mạng cần kết nối, cùng với thông tin đăng nhập bắt buộc.

  3. Quyết định kết hợp SSID, SSID pattern, BSSIDBSSID pattern để đặt bộ lọc mạng trong mỗi yêu cầu, tuân theo các yêu cầu sau:

    • Mỗi yêu cầu phải cung cấp ít nhất một trong các giá trị sau: SSID, SSID pattern, BSSID hoặc BSSID pattern
    • Mỗi yêu cầu chỉ có thể đặt một trong hai giá trị SSID hoặc SSID pattern
    • Mỗi yêu cầu chỉ có thể đặt một trong hai giá trị BSSID hoặc BSSID pattern
  4. Thêm thông số kỹ thuật vào yêu cầu mạng cùng với thực thể NetworkCallback để theo dõi trạng thái của yêu cầu.

    Nếu người dùng chấp nhận yêu cầu và kết nối mạng thành công, thì NetworkCallback.onAvailable() sẽ được gọi trên đối tượng gọi lại. Nếu người dùng từ chối yêu cầu hoặc nếu kết nối mạng không thành công, NetworkCallback.onUnavailable() sẽ được gọi trên đối tượng gọi lại.

Việc bắt đầu yêu cầu kết nối với một thiết bị ngang hàng sẽ khởi chạy một hộp thoại trên cùng một thiết bị mà từ đó người dùng của thiết bị đó có thể chấp nhận yêu cầu kết nối.

Bỏ qua sự phê duyệt của người dùng

Sau khi người dùng phê duyệt một mạng cần kết nối theo yêu cầu của một ứng dụng cụ thể, thiết bị sẽ lưu trữ quyết định phê duyệt cho điểm truy cập cụ thể đó. Nếu ứng dụng đưa ra một yêu cầu cụ thể để kết nối lại với điểm truy cập đó, thì thiết bị sẽ bỏ qua giai đoạn phê duyệt của người dùng và tự động kết nối với mạng. Nếu người dùng chọn quên mạng trong khi kết nối với một mạng mà API yêu cầu, thì quyết định phê duyệt đã lưu trữ này đối với tổ hợp ứng dụng và mạng đó sẽ bị xoá, đồng thời mọi yêu cầu sau này của ứng dụng phải được người dùng phê duyệt lại. Nếu ứng dụng đưa ra một yêu cầu không cụ thể, chẳng hạn như với mẫu SSID hoặc BSSID, thì người dùng phải phê duyệt yêu cầu.

Mã mẫu

Mã mẫu sau đây cho biết cách kết nối với một mạng mở có tiền tố SSID là "test" và OUI BSSID là "10:03:23":

Kotlin

val specifier = WifiNetworkSpecifier.Builder()
    .setSsidPattern(PatternMatcher("test", PatternMatcher.PATTERN_PREFIX))
    .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"), MacAddress.fromString("ff:ff:ff:00:00:00"))
    .build()

val request = NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    .setNetworkSpecifier(specifier)
    .build()

val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

val networkCallback = object : ConnectivityManager.NetworkCallback() {
    ...
    override fun onAvailable(network: Network?) {
        // do success processing here..
    }

    override fun onUnavailable() {
        // do failure processing here..
    }
    ...
}
connectivityManager.requestNetwork(request, networkCallback)
...
// Release the request when done.
connectivityManager.unregisterNetworkCallback(networkCallback)

Java

final NetworkSpecifier specifier =
  new WifiNetworkSpecifier.Builder()
  .setSsidPattern(new PatternMatcher("test", PatternMatcher.PATTERN_PREFIX))
  .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"), MacAddress.fromString("ff:ff:ff:00:00:00"))
  .build();

final NetworkRequest request =
  new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
  .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
  .setNetworkSpecifier(specifier)
  .build();

final ConnectivityManager connectivityManager = (ConnectivityManager)
  context.getSystemService(Context.CONNECTIVITY_SERVICE);

final NetworkCallback networkCallback = new NetworkCallback() {
  ...
  @Override
  void onAvailable(...) {
      // do success processing here..
  }

  @Override
  void onUnavailable(...) {
      // do failure processing here..
  }
  ...
};
connectivityManager.requestNetwork(request, networkCallback);
...
// Release the request when done.
connectivityManager.unregisterNetworkCallback(networkCallback);