API คำแนะนำ Wi-Fi สำหรับการเชื่อมต่ออินเทอร์เน็ต

อุปกรณ์ที่ใช้ Android 10 (API ระดับ 29) ขึ้นไปจะอนุญาตให้แอปเพิ่มข้อมูลเข้าสู่ระบบเครือข่าย เพื่อให้อุปกรณ์เชื่อมต่อกับจุดเข้าใช้งาน Wi-Fi โดยอัตโนมัติ คุณสามารถระบุคำแนะนำสำหรับเครือข่ายที่จะเชื่อมต่อได้โดยใช้ WifiNetworkSuggestion ท้ายที่สุดแล้ว แพลตฟอร์มจะเลือกจุดเข้าถึงที่จะยอมรับตาม ข้อมูลที่ป้อนจากแอปของคุณและแอปอื่นๆ

ใน Android 11 (API ระดับ 30) ขึ้นไป ให้ทำดังนี้

  • API คำแนะนำรองรับการจัดสรร PasspointConfiguration ก่อน Android 11 การจัดสรร PasspointConfiguration ต้องใช้ addOrUpdatePasspointConfiguration() API
  • เฟรมเวิร์กจะบังคับใช้ข้อกำหนดด้านความปลอดภัยกับคำแนะนำสำหรับองค์กรที่ใช้ TLS (EAP-TLS, EAP-TTLS และ EAP-PEAP) คำแนะนำสำหรับเครือข่ายดังกล่าวต้องตั้งค่า Root CA certificate และ server domain name
  • เฟรมเวิร์กบังคับใช้ข้อกำหนดด้านความเป็นเจ้าของสำหรับคำแนะนำระดับองค์กรที่อิงตาม EAP-SIM (EAP-SIM, EAP-AKA, EAP-AKA-PRIME) โดยอนุญาตให้แอปที่ผู้ให้บริการลงนามเท่านั้นที่ใช้คำแนะนำดังกล่าวได้
  • สำหรับคำแนะนำที่แอปซึ่งผู้ให้บริการลงนามให้ Framework จะกำหนดรหัสผู้ให้บริการที่สอดคล้องกับการลงนามของผู้ให้บริการของแอปโดยอัตโนมัติ ระบบจะปิดใช้คำแนะนำดังกล่าวโดยอัตโนมัติหากนำซิมที่เกี่ยวข้องออกจากอุปกรณ์

ใน Android 12 (API ระดับ 31) ขึ้นไป ให้ทำดังนี้

  • คุณเปิดใช้ความเป็นส่วนตัวเพิ่มเติมได้ผ่านการสุ่ม MAC แบบไม่ถาวร ซึ่งจะสุ่มที่อยู่ MAC แบบสุ่มอีกครั้งเป็นระยะ ใช้ setMacRandomizationSetting เพื่อระบุระดับการสุ่มสำหรับเครือข่าย

  • isPasspointTermsAndConditionsSupported(): ข้อกำหนดและเงื่อนไขเป็นฟีเจอร์ Passpoint ที่ช่วยให้การติดตั้งใช้งานเครือข่ายสามารถแทนที่แคพทีฟพอร์ทัลที่ไม่ปลอดภัย ซึ่งใช้เครือข่ายแบบเปิดด้วยเครือข่าย Passpoint ที่ปลอดภัย ระบบจะแสดงการแจ้งเตือนต่อผู้ใช้เมื่อต้องยอมรับข้อกำหนดและเงื่อนไข แอปที่แนะนำเครือข่าย Passpoint ซึ่งมีข้อกำหนดและเงื่อนไข ต้องเรียกใช้ API นี้ก่อนเพื่อให้แน่ใจว่าอุปกรณ์รองรับความสามารถดังกล่าว หากอุปกรณ์ไม่รองรับความสามารถดังกล่าว ก็จะเชื่อมต่อกับเครือข่ายนี้ไม่ได้ และต้องแนะนำเครือข่ายอื่นหรือเครือข่ายเดิม

  • isDecoratedIdentitySupported(): เมื่อตรวจสอบสิทธิ์ในเครือข่ายที่มีการตกแต่งคำนำหน้า คำนำหน้าที่ตกแต่งแล้ว จะช่วยให้ผู้ให้บริการเครือข่ายอัปเดตตัวระบุการเข้าถึงเครือข่าย (NAI) เพื่อทำการกำหนดเส้นทางที่ชัดเจนผ่านพร็อกซีหลายรายการภายใน เครือข่าย AAA (ดูข้อมูลเพิ่มเติมได้ที่ RFC 7542)

    Android 12 ใช้ฟีเจอร์นี้เพื่อให้เป็นไปตามข้อกำหนดของ WBA สำหรับ ส่วนขยาย PPS-MO แอปที่แนะนำเครือข่าย Passpoint ซึ่งต้องมีข้อมูลประจำตัวที่ตกแต่งแล้วจะต้องเรียกใช้ API นี้ก่อนเพื่อให้แน่ใจว่าอุปกรณ์รองรับความสามารถดังกล่าว หาก อุปกรณ์ไม่รองรับความสามารถนี้ ระบบจะไม่ตกแต่งข้อมูลประจำตัว และการตรวจสอบสิทธิ์ในเครือข่ายอาจล้มเหลว

หากต้องการสร้างคำแนะนำ Passpoint แอปต้องใช้คลาส PasspointConfiguration Credential และ HomeSp คลาสเหล่านี้อธิบายโปรไฟล์ Passpoint ซึ่งกำหนดไว้ในข้อกำหนด Passpoint ของ Wi-Fi Alliance

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีระบุข้อมูลเข้าสู่ระบบสำหรับเครือข่ายแบบเปิด 1 เครือข่าย, WPA2 1 เครือข่าย, WPA3 1 เครือข่าย และ Passpoint 1 เครือข่าย

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)