ממשק 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).