P2P 연결을 위한 Wi-Fi 네트워크 요청 API

Android 10 (API 수준 29) 이상 기기에서는 새로운 P2P API를 사용하여 Chromecast 및 Google Home 하드웨어와 같은 보조 기기의 구성을 부트스트랩할 수 있습니다. 이 기능을 사용하면 앱에서 요청된 네트워크의 속성을 설명하는 WifiNetworkSpecifier를 사용하여 기기가 연결된 액세스 포인트를 변경하라는 메시지를 사용자에게 표시할 수 있습니다.

이 API를 사용하는 방법은 다음과 같습니다.

  1. WifiNetworkSpecifier.Builder를 사용하여 Wi-Fi 네트워크 지정자를 생성합니다.

  2. 필수 사용자 인증 정보와 함께 연결할 네트워크와 일치하도록 네트워크 필터를 설정합니다.

  3. SSID, SSID pattern, BSSID, BSSID pattern의 조합을 결정하여 다음 요구사항에 따라 각 요청에서 네트워크 필터를 설정합니다.

    • 각 요청은 SSID, SSID pattern, BSSID, BSSID pattern 중 하나 이상을 제공해야 합니다.
    • 각 요청은 SSID 또는 SSID pattern 중 하나만 설정할 수 있습니다.
    • 각 요청은 BSSID 또는 BSSID pattern 중 하나만 설정할 수 있습니다.
  4. 요청 상태를 추적하려면 NetworkCallback 인스턴스와 함께 네트워크 요청에 지정자를 추가합니다.

    사용자가 요청을 수락하고 네트워크가 연결되면 콜백 객체에서 NetworkCallback.onAvailable()가 호출됩니다. 사용자가 요청을 거부하거나 네트워크 연결이 실패하면 콜백 객체에서 NetworkCallback.onUnavailable()가 호출됩니다.

피어 기기 연결 요청을 시작하면 동일한 기기에서 대화상자가 실행되며 이 대화상자에서 기기 사용자가 연결 요청을 수락할 수 있습니다.

사용자 승인 우회

사용자가 특정 앱의 요청에 응답하여 네트워크를 연결하도록 승인하면 기기는 특정 액세스 포인트에 관한 승인을 저장합니다. 앱이 해당 액세스 포인트에 다시 연결하기 위한 특정 요청을 하면 기기는 사용자 승인 단계를 건너뛰고 네트워크에 자동으로 연결합니다. 사용자가 API에서 요청한 네트워크에 연결되어 있는 동안 네트워크를 삭제하면 해당 앱과 네트워크의 조합에 관한 저장된 승인이 삭제되며 앱의 향후 요청은 사용자의 승인을 다시 받아야 합니다. 앱이 SSID 또는 BSSID 패턴을 사용하는 등 구체적이지 않은 요청을 하면 사용자가 요청을 승인해야 합니다.

코드 샘플

다음 코드 샘플은 SSID 접두사가 "test"이고 BSSID OUI가 "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);