تسمح الأجهزة التي تعمل بالإصدار 10 من Android (المستوى 29 لواجهة برمجة التطبيقات) والإصدارات الأحدث لتطبيقك بإضافة بيانات اعتماد الشبكة لجهاز من أجل الاتصال تلقائيًا بنقطة وصول لاسلكية. يمكنك تقديم
اقتراحات بشأن الشبكة التي تريد الاتصال بها باستخدام
WifiNetworkSuggestion.
تختار المنصة في النهاية نقطة الوصول التي تريد قبولها استنادًا إلى البيانات التي يُدخلها تطبيقك وتطبيقات أخرى.
في الإصدار 11 من Android (المستوى 30 لواجهة برمجة التطبيقات) والإصدارات الأحدث:
- تتيح واجهة برمجة التطبيقات للاقتراحات إمكانية توفير
PasspointConfiguration. قبل الإصدار 11 من Android، كان توفيرPasspointConfigurationيتطلب استخدام واجهة برمجة التطبيقاتaddOrUpdatePasspointConfiguration(). - يفرض الإطار متطلبات الأمان على اقتراحات المؤسسات المستندة إلى بروتوكول أمان طبقة النقل (EAP-TLS وEAP-TTLS وEAP-PEAP). يجب أن تضبط الاقتراحات المقدّمة لهذه الشبكات
Root CA certificateوserver domain name.
- يفرض الإطار متطلبات الملكية على اقتراحات المؤسسات المستندة إلى بروتوكول المصادقة القابلة للتوسيع (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 الشخصي، الذي تم تحديده في مواصفات
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 الذي يعمل على الجهاز:
- في الإصدار 11 من Android (المستوى 30 لواجهة برمجة التطبيقات) والإصدارات الأحدث، يظهر للمستخدم مربّع حوار إذا كان التطبيق قيد التشغيل في المقدّمة، وإشعار إذا كان التطبيق قيد التشغيل في الخلفية.
- في الإصدار 10 من Android (المستوى 29 لواجهة برمجة التطبيقات)، يظهر للمستخدم إشعار، بغض النظر عمّا إذا كان التطبيق قيد التشغيل في المقدّمة أو الخلفية.
عندما تتصل المنصة بأحد اقتراحات الشبكة، تعرض الإعدادات نصًا ينسب الاتصال بالشبكة إلى التطبيق المقترِح المقابل.
التعامل مع حالات قطع الاتصال من قِبل المستخدم
إذا استخدم المستخدم أداة اختيار شبكة Wi-Fi لقطع الاتصال صراحةً بأحد اقتراحات الشبكة عندما يكون متصلاً بها، يتم تجاهل هذه الشبكة عندما تكون لا تزال ضمن النطاق. خلال هذه الفترة، لن يتم أخذ هذه الشبكة في الاعتبار للاتصال التلقائي، حتى إذا أزال التطبيق اقتراح الشبكة المقابل للشبكة وأعاد إضافته. إذا استخدم المستخدم أداة اختيار شبكة Wi-Fi للاتصال صراحةً بشبكة تم قطع الاتصال بها سابقًا، سيتم أخذ هذه الشبكة في الاعتبار للاتصال التلقائي على الفور.
تغيير حالة الموافقة على التطبيق
إذا رفض المستخدم إشعار اقتراح الشبكة، تتم إزالة الإذن
CHANGE_WIFI_STATE من التطبيق. ويمكن للمستخدم منح هذه الموافقة
لاحقًا من خلال الانتقال إلى قائمة التحكّم في شبكة Wi-Fi (الإعدادات >
التطبيقات والإشعارات > أذونات خاصة للتطبيقات
> التحكّم في شبكة Wi-Fi > App name).