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

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

على نظام التشغيل Android 11 (المستوى 30 لواجهة برمجة التطبيقات) والإصدارات الأحدث:

  • تتيح واجهة برمجة التطبيقات الخاصة بالاقتراحات توفير PasspointConfiguration. قبل الإصدار 11 من نظام التشغيل Android، كان توفير PasspointConfiguration يتطلّب استخدام واجهة برمجة التطبيقات addOrUpdatePasspointConfiguration() API.
  • يفرض إطار العمل متطلبات الأمان على الاقتراحات الخاصة بالمؤسسات المستندة إلى بروتوكول أمان طبقة النقل (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(): الأحكام والشروط هي إحدى ميزات Passpoint التي تتيح عمليات نشر الشبكات استبدال المداخل المشروطة الوصول إليها غير الآمنة، والتي تستخدم شبكات مفتوحة، بشبكة Passpoint آمنة. يتم عرض إشعار للمستخدم عندما يكون من المطلوب قبول الأحكام والشروط. يجب أن تطلب التطبيقات التي تقترح شبكات Passpoint محظورة بموجب البنود والشروط استخدام واجهة برمجة التطبيقات هذه أولاً للتأكّد من أنّ الجهاز يتيح هذه الإمكانية. إذا كان الجهاز لا يتوافق مع هذه الإمكانية، لن يتمكّن من الاتصال بهذه الشبكة، ويجب اقتراح شبكة بديلة أو شبكة قديمة.

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

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

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

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

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

التعامل مع حالات قطع اتصال المستخدمين

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

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

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