ממשק 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(): התנאים וההגבלות היא תכונה של 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).