ממשק API לבקשת רשת Wi-Fi לקישוריות עמית-לעמית

ב-Android 10 (רמת API 29) ובמכשירים מתקדמים יותר, אפשר להשתמש ב-API חדש מקצה לקצה (P2P) כדי להפעיל הגדרת אתחול במכשירים משניים כמו Chromecast וחומרה של Google Home. התכונה הזו מאפשרת לאפליקציה לבקש מהמשתמש לשנות את נקודת הגישה שאליה המכשיר מחובר, באמצעות שימוש ב-WifiNetworkSpecifier כדי לתאר את המאפיינים של הרשת המבוקשת.

כדי להשתמש ב-API הזה:

  1. יוצרים ספציפי רשת Wi-Fi באמצעות WifiNetworkSpecifier.Builder.

  2. מגדירים מסנן רשת שיתאים לרשתות שאליהן רוצים להתחבר, יחד עם פרטי הכניסה הנדרשים.

  3. בוחרים שילוב של SSID,‏ SSID pattern,‏ BSSID ו-BSSID pattern כדי להגדיר את מסנן הרשת בכל בקשה, בכפוף לדרישות הבאות:

    • בכל בקשה צריך לציין לפחות אחד מהערכים הבאים: SSID,‏ SSID pattern,‏ BSSID או BSSID pattern.
    • בכל בקשה אפשר להגדיר רק אחד מהערכים SSID או SSID pattern
    • בכל בקשה אפשר להגדיר רק אחד מהערכים BSSID או BSSID pattern
  4. מוסיפים את המציינים לבקשת הרשת יחד עם מכונה של NetworkCallback כדי לעקוב אחרי סטטוס הבקשה.

    אם המשתמש מאשר את הבקשה והחיבור לרשת מצליח, מתבצעת קריאה ל-NetworkCallback.onAvailable() באובייקט ה-callback. אם המשתמש דוחה את הבקשה או שהחיבור לרשת נכשל, מתבצעת קריאה ל-NetworkCallback.onUnavailable() באובייקט ה-callback.

כשמפעילים את בקשת ההתחברות למכשיר עם אפליקציה תואמת תיפתח תיבת דו-שיח באותו מכשיר, שבה המשתמש יוכל לאשר את בקשת החיבור.

עקיפת אישור המשתמש

אחרי שהמשתמש מאשר רשת להתחברות בתגובה לבקשה מאפליקציה ספציפית, המכשיר שומר את האישור לנקודת הגישה הספציפית. אם האפליקציה שולחת בקשה ספציפית להתחבר שוב לנקודת הגישה הזו, המכשיר ידלג על שלב אישור המשתמש ויתחבר אוטומטית לרשת. אם המשתמש יבחר לשכוח את הרשת בזמן שהוא מחובר לרשת שביקשה ה-API, האישור שנשמר לשילוב הזה של האפליקציה והרשת יוסר, וכל בקשה עתידית מהאפליקציה תצטרך לקבל אישור שוב מהמשתמש. אם האפליקציה שולחת בקשה לא ספציפית, למשל עם דפוס SSID או BSSID, המשתמש צריך לאשר את הבקשה.

דוגמת קוד

בדוגמת הקוד הבאה מוסבר איך להתחבר לרשת פתוחה עם קידומת SSID‏ "test" ו-OUI של BSSID‏ "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);