واجهة برمجة تطبيقات لاقتراح Wi-Fi للاتصال بالإنترنت

إنّ الأجهزة التي تعمل بنظام التشغيل Android 10 (المستوى 29 من واجهة برمجة التطبيقات) والإصدارات الأحدث تسمح لتطبيقك بإضافة بيانات اعتماد الشبكة لجهاز للاتصال التلقائي بنقطة وصول Wi-Fi. يمكنك تقديم اقتراحات للشبكة التي تريد الاتصال بها باستخدام WifiNetworkSuggestion. تختار المنصة في النهاية نقطة الوصول التي يتم قبولها بناءً على البيانات الواردة من تطبيقك والتطبيقات الأخرى.

في نظام التشغيل Android 11 (المستوى 30) والإصدارات الأحدث:

  • تتوافق إدارة حسابات PasspointConfiguration مع واجهة برمجة تطبيقات الاقتراحات. قبل الإصدار Android 11، تتطلب توفير المتطلبات اللازمة في PasspointConfiguration استخدام واجهة برمجة التطبيقات addOrUpdatePasspointConfiguration().
  • يفرض إطار العمل متطلبات الأمان على اقتراحات المؤسسات المستندة إلى بروتوكول أمان طبقة النقل (TLS) (EAP-TLS وEAP-TTLS وEAP-PEAP)، ويجب ضبط الاقتراحات لهذه الشبكات على ضبط Root CA certificate وserver domain name.
  • يفرض إطار العمل متطلبات الملكية لاقتراحات المؤسسات المستندة إلى EAP-SIM (EAP-SIM، EAP-AKA، EAP-AKA-PRIME)، لا يُسمح بهذه الاقتراحات إلا في التطبيقات الموقَّعة من مشغِّل شبكة الجوّال.
  • بالنسبة إلى الاقتراحات التي يقدّمها تطبيق موقَّع من مشغّل شبكة الجوّال، يعيّن إطار العمل تلقائيًا رقم تعريف مشغّل شبكة الجوّال وفقًا لتوقيع مشغِّل شبكة الجوّال في التطبيق. يتم إيقاف هذه الاقتراحات تلقائيًا في حال إزالة شريحة SIM المقابلة من الجهاز.

على نظام التشغيل Android 12 (المستوى 31) والإصدارات الأحدث:

  • يمكن تفعيل خصوصية إضافية من خلال التوزيع العشوائي غير الدائم لعنوان MAC، الذي يعيد ترتيب عنوان MAC العشوائي بشكل عشوائي. استخدِم setMacRandomizationSetting لتحديد مستوى التوزيع العشوائي لشبكتك.

  • isPasspointTermsAndConditionsSupported(): الأحكام والشروط هي ميزة نقطة مرور تسمح لعمليات النشر على الشبكة باستبدال البوابات المقيّدة غير الآمنة التي تستخدم الشبكات المفتوحة بشبكة نقطة مرور آمنة. يظهر إشعار للمستخدم عندما تكون الأحكام والشروط مطلوبة. يجب أن تطلب التطبيقات التي تقترح شبكات نقطة المرور المُحاطة بالأحكام والشروط واجهة برمجة التطبيقات هذه أولاً للتأكّد من أنّ الجهاز يوفّر هذه الإمكانية. إذا كان الجهاز لا يتيح هذه الميزة، لن يتمكّن من الاتصال بهذه الشبكة، ويجب اقتراح شبكة بديلة أو قديمة.

  • isDecoratedIdentitySupported(): عند المصادقة على الشبكات مع إضافة بادئة إلى الشبكات، تسمح بادئة الهوية المزخرفة لمشغّلي الشبكات بتعديل "معرّف الوصول إلى الشبكة" (NAI) لتنفيذ التوجيه الصريح من خلال عدة خوادم وكيلة داخل شبكة AAA (راجِع RFC 7542 للمزيد من المعلومات حول هذا الموضوع).

    ينفِّذ Android 12 هذه الميزة للتوافق مع مواصفات WBA لإضافات PPS-MO. يجب أن تستدعي التطبيقات التي تقترح شبكات نقطة مرور تتطلب هوية مزينة بواجهة برمجة التطبيقات هذه أولاً للتأكد من أن الجهاز يتوافق مع هذه الإمكانية. وإذا كان الجهاز لا يتيح هذه الميزة، لن يتم تزيين الهوية وقد تتعذر المصادقة على الشبكة.

لإنشاء اقتراح "نقطة مرور"، يجب أن تستخدم التطبيقات الصفوف PasspointConfiguration وCredential وHomeSp. تصف هذه الفئات الملف الشخصي لنقطة مرور، والمحدّد في مواصفات نقطة مرور تحالف Wi-Fi.

يوضح نموذج الرمز التالي كيفية توفير بيانات الاعتماد لشبكة WPA2 واحدة وWPA2 واحدة وشبكة WPA3 واحدة وشبكة نقطة مرور واحدة:

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 (المستوى 30 لواجهة برمجة التطبيقات) والإصدارات الأحدث، يظهر للمستخدم مربّع حوار إذا كان التطبيق يعمل في المقدّمة، وسيعرض إشعارًا إذا كان التطبيق يعمل في الخلفية.
  • في نظام التشغيل Android 10 (مستوى واجهة برمجة التطبيقات 29)، يرى المستخدم إشعارًا، بغض النظر عمّا إذا كان التطبيق يعمل في المقدّمة أم في الخلفية.

عندما تتصل المنصة بأحد اقتراحات الشبكة، تعرض الإعدادات النص الذي ينسب الاتصال بالشبكة إلى تطبيق المُحيل المقابل.

التعامل مع عمليات إلغاء ربط المستخدمين

إذا كان المستخدم يستخدم "أداة اختيار Wi-Fi" لقطع الاتصال بشكل صريح بأحد اقتراحات الشبكة عند الاتصال بها، سيتم تجاهل هذه الشبكة عندما تكون في النطاق. وخلال هذه الفترة، لن يتم اعتبار هذه الشبكة في الاتصال التلقائي، حتى إذا أزال التطبيق اقتراح الشبكة المتوافق مع الشبكة وأعاد إضافته. إذا كان المستخدم يستخدم "أداة اختيار Wi-Fi" للاتصال صراحةً بشبكة تم قطع اتصالها سابقًا، سيتم اعتبار هذه الشبكة في الاعتبار الاتصال التلقائي على الفور.

تغيير حالة الموافقة على التطبيق

يؤدي رفض المستخدم لإشعار اقتراح الشبكة إلى إزالة إذن CHANGE_WIFI_STATE من التطبيق. يمكن للمستخدم منح هذه الموافقة لاحقًا من خلال الانتقال إلى قائمة التحكم في شبكة Wi-Fi (الإعدادات > التطبيقات والإشعارات > وصول خاص إلى التطبيقات > التحكُّم في شبكة Wi-Fi > App name).