ממשק API של הצעות Wi-Fi לחיבור אינטרנט

במכשירים עם Android 10 (רמת API‏ 29) ומעלה, האפליקציה יכולה להוסיף פרטי כניסה לרשת כדי שהמכשיר יתחבר אוטומטית לנקודת גישה ל-Wi-Fi. אתם יכולים לספק הצעות לגבי הרשת שאליה כדאי להתחבר באמצעות WifiNetworkSuggestion. בסופו של דבר, הפלטפורמה בוחרת את נקודת הגישה שתתקבל על סמך הקלט מהאפליקציה שלכם ומאפליקציות אחרות.

ב-Android מגרסה 11 (רמת API 30) ואילך:

  • המסגרת אוכפת דרישות בעלות להצעות של EAP-SIM לארגונים (EAP-SIM, ‏ EAP-AKA, ‏ EAP-AKA-PRIME). הצעות כאלה מותרות רק באפליקציות שחתומות על ידי ספק הסלולר.
  • המסגרת מקצה באופן אוטומטי הצעות שסופקו על ידי אפליקציה עם חתימה של ספק סלולר, מזהה ספק סלולר שמתאים לחתימה של ספק סלולר של האפליקציה. ההצעות האלה מושבתות אוטומטית אם כרטיס ה-SIM המתאים מוסר מהמכשיר.

ב-Android מגרסה 12 (רמת API 31) ואילך:

  • אפשר להפעיל פרטיות נוספת באמצעות רנדומיזציה לא קבועה של כתובות MAC, שמבצעת רנדומיזציה מחדש של כתובת ה-MAC האקראית מדי פעם. משתמשים בערך setMacRandomizationSetting כדי לציין את רמת האקראיות של הרשת.

  • isPasspointTermsAndConditionsSupported(): ‫Terms and conditions היא תכונה של Passpoint שמאפשרת לפריסות רשת להחליף פורטלים פתוחים לא מאובטחים, שמשתמשים ברשתות פתוחות, ברשת Passpoint מאובטחת. המשתמש רואה הודעה כשנדרש ממנו לאשר את התנאים וההגבלות. אפליקציות שמציעות רשתות Passpoint שמוגבלות על ידי תנאים והגבלות חייבות לקרוא קודם ל-API הזה כדי לוודא שהמכשיר תומך ביכולת הזו. אם המכשיר לא תומך ביכולת הזו, הוא לא יוכל להתחבר לרשת הזו, ותצטרכו להציע רשת חלופית או רשת מדור קודם.

  • isDecoratedIdentitySupported(): כשמבצעים אימות לרשתות עם קידומת מעוטרת, קידומת הזהות המעוטרת מאפשרת למפעילי רשת לעדכן את מזהה הגישה לרשת (NAI) כדי לבצע ניתוב מפורש דרך כמה שרתי proxy בתוך רשת AAA (מידע נוסף זמין ב-RFC 7542).

    ב-Android 12, התכונה הזו מיושמת בהתאם למפרט של WBA בנוגע לתוספים של PPS-MO. אפליקציות שמציעות רשתות Passpoint שדורשות זהות מעוטרת צריכות לקרוא קודם ל-API הזה כדי לוודא שהמכשיר תומך ביכולת הזו. אם המכשיר לא תומך ביכולת הזו, הזהות לא תעבור עיטור והאימות לרשת עלול להיכשל.

כדי ליצור הצעה ל-Passpoint, האפליקציות צריכות להשתמש במחלקות PasspointConfiguration,‏ Credential ו-HomeSp. המחלקות האלה מתארות את פרופיל Passpoint, שמוגדר במפרט Passpoint של Wi-Fi Alliance.

בדוגמה הבאה של קוד אפשר לראות איך מספקים פרטי כניסה לרשת פתוחה אחת, לרשת WPA2 אחת, לרשת WPA3 אחת ולרשת Passpoint אחת:

Kotlin

val suggestion1 = WifiNetworkSuggestion.Builder()
        .setSsid("test111111")
        .setIsAppInteractionRequired(true) // Optional (Needs location permission)
        .build();

val suggestion2 = WifiNetworkSuggestion.Builder()
        .setSsid("test222222")
        .setWpa2Passphrase("test123456")
        .setIsAppInteractionRequired(true) // Optional (Needs location permission)
        .build();

val suggestion3 = WifiNetworkSuggestion.Builder()
        .setSsid("test333333")
        .setWpa3Passphrase("test6789")
        .setIsAppInteractionRequired(true) // Optional (Needs location permission)
        .build();

val passpointConfig = PasspointConfiguration(); // configure passpointConfig to include a valid Passpoint configuration
val suggestion4 = WifiNetworkSuggestion.Builder()
        .setPasspointConfig(passpointConfig)
        .setIsAppInteractionRequired(true) // Optional (Needs location permission)
        .build();

val suggestionsList = listOf(suggestion1, suggestion2, suggestion3, suggestion4);

val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager;

val status = wifiManager.addNetworkSuggestions(suggestionsList);
if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
    // do error handling here
}

// Optional (Wait for post connection broadcast to one of your suggestions)
val intentFilter = IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);

val broadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (!intent.action.equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
            return;
        }
        // do post connect processing here
    }
};
context.registerReceiver(broadcastReceiver, intentFilter);

Java

final WifiNetworkSuggestion suggestion1 =
  new WifiNetworkSuggestion.Builder()
  .setSsid("test111111")
  .setIsAppInteractionRequired(true) // Optional (Needs location permission)
  .build();

final WifiNetworkSuggestion suggestion2 =
  new WifiNetworkSuggestion.Builder()
  .setSsid("test222222")
  .setWpa2Passphrase("test123456")
  .setIsAppInteractionRequired(true) // Optional (Needs location permission)
  .build();

final WifiNetworkSuggestion suggestion3 =
  new WifiNetworkSuggestion.Builder()
  .setSsid("test333333")
  .setWpa3Passphrase("test6789")
  .setIsAppInteractionRequired(true) // Optional (Needs location permission)
  .build();

final PasspointConfiguration passpointConfig = new PasspointConfiguration();
// configure passpointConfig to include a valid Passpoint configuration

final WifiNetworkSuggestion suggestion4 =
  new WifiNetworkSuggestion.Builder()
  .setPasspointConfig(passpointConfig)
  .setIsAppInteractionRequired(true) // Optional (Needs location permission)
  .build();

final List<WifiNetworkSuggestion> suggestionsList =
  new ArrayList<WifiNetworkSuggestion> {{
    add(suggestion1);
    add(suggestion2);
    add(suggestion3);
    add(suggestion4);
  }};

final WifiManager wifiManager =
  (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

final int status = wifiManager.addNetworkSuggestions(suggestionsList);
if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
// do error handling here…
}

// Optional (Wait for post connection broadcast to one of your suggestions)
final IntentFilter intentFilter =
  new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);

final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
    if (!intent.getAction().equals(
      WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
      return;
    }
    // do post connect processing here...
  }
};
context.registerReceiver(broadcastReceiver, intentFilter);

מיד אחרי שהאפליקציה מציבה הצעה בפעם הראשונה, המשתמש מקבל הודעה. סוג ההתראה תלוי בגרסת Android שפועלת במכשיר:

  • ב-Android 11 (API ברמה 30) ומעלה, אם האפליקציה פועלת בחזית, המשתמש רואה תיבת דו-שיח, ואם האפליקציה פועלת ברקע, המשתמש רואה התראה.
  • ב-Android 10 (API ברמה 29), המשתמש רואה התראה, בלי קשר לשאלה אם האפליקציה פועלת בחזית או ברקע.

כשהפלטפורמה מתחברת לאחת מההצעות לרשת, בהגדרות מוצג טקסט שמשייך את חיבור הרשת לאפליקציה המתאימה שהציעה את ההצעה.

טיפול בניתוקים של משתמשים

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

שינוי סטטוס האישור של אפליקציה

אם המשתמש דוחה את ההתראה על הצעת הרשת, ההרשאה CHANGE_WIFI_STATEמוסרת מהאפליקציה. המשתמש יכול לאשר את ההרשאה הזו מאוחר יותר דרך תפריט השליטה ב-Wi-Fi (הגדרות > אפליקציות והתראות > גישה מיוחדת לאפליקציה > שליטה ב-Wi-Fi > App name).