نظرة عامة على Wi-Fi Aware

تتيح إمكانات الاتصال بشبكة Wi-Fi للأجهزة التي تعمل بالإصدار 8.0 من نظام التشغيل Android (المستوى 26 من واجهة برمجة التطبيقات) والإصدارات الأحدث إمكانية اكتشاف بعض الأجهزة والاتصال بها مباشرةً بدون أي نوع آخر من الاتصال بينهما. تُعرف خدمة Wi-Fi أيضًا باسم شبكات الوعي المجاورة (NAN).

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

تتيح واجهات برمجة التطبيقات لخدمة Wi-Fi Aware للتطبيقات تنفيذ العمليات التالية:

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

  • إنشاء اتصال شبكة: بعد اكتشاف جهازين للبعض الآخر، يمكن لجهازين إنشاء اتصال شبكة ثنائي الاتجاه بخدمة Wi-Fi Aware بدون نقطة وصول.

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

تحسينات Android 13 (المستوى 33)

على الأجهزة التي تعمل بالإصدار 13 من نظام التشغيل Android (المستوى 33 لواجهة برمجة التطبيقات) والإصدارات الأحدث التي تتيح وضع الاتصال الفوري، يمكن للتطبيقات استخدام طريقتَي PublishConfig.Builder.setInstantCommunicationModeEnabled() و SubscribeConfig.Builder.setInstantCommunicationModeEnabled() لتفعيل وضع الاتصال الفوري أو إيقافه لجلسة اكتشاف الناشر أو المشترك. يعمل وضع الاتصال الفوري على تسريع عملية تبادل الرسائل واكتشاف الخدمة وإعداد أي مسار بيانات كجزء من جلسة اكتشاف الناشر أو المشترك. لتحديد ما إذا كان الجهاز متوافقًا مع وضع الاتصال الفوري، استخدِم الطريقة isInstantCommunicationModeSupported().

تحسينات Android 12 (المستوى 31)

يضيف الإصدار Android 12 (المستوى 31 من واجهة برمجة التطبيقات) بعض التحسينات إلى خدمة Wi-Fi Aware:

  • على الأجهزة التي تعمل بالإصدار 12 من نظام التشغيل Android (المستوى 31 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث، يمكنك استخدام onServiceLost() معاودة الاتصال ليتم تنبيهك عندما يفقد تطبيقك خدمة تم اكتشافها بسبب توقف الخدمة أو الخروج منها.
  • تم محاكاة إعداد مسارات بيانات Wi-Fi. واستخدمت الإصدارات السابقة المراسلة L2 لتوفير عنوان MAC الخاص ببادئ التشغيل، مما أدى إلى حدوث زمن انتقال. على الأجهزة التي تعمل بنظام التشغيل Android 12 والإصدارات الأحدث، يمكن ضبط المجيب (الخادم) لقبول أي تطبيق مشابه، أي أنّه لا يحتاج إلى معرفة عنوان MAC الخاص ببرنامج تشغيل الرسالة. ويؤدي ذلك إلى تسريع عملية جمع مسار البيانات وتفعيل روابط متعددة من نقطة إلى نقطة بطلب شبكة واحد فقط.
  • يمكن للتطبيقات التي تعمل بنظام التشغيل Android 12 أو الإصدارات الأحدث أن تستخدم طريقة WifiAwareManager.getAvailableAwareResources() للاطّلاع على عدد مسارات البيانات المتوفّرة حاليًا وجلسات النشر وجلسات الاشتراك. يمكن أن يساعد هذا التطبيق في تحديد ما إذا كانت هناك موارد متاحة كافية لتنفيذ الوظائف المطلوبة.

عملية الإعداد الأوّلية

لإعداد تطبيقك من أجل استخدام ميزة الاكتشاف والاتصال بشبكة Wi-Fi Aware، يُرجى اتّباع الخطوات التالية:

  1. اطلب الأذونات التالية في بيان التطبيق:

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- If your app targets Android 13 (API level 33)
         or higher, you must declare the NEARBY_WIFI_DEVICES permission. -->
    <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
                     <!-- If your app derives location information from
                          Wi-Fi APIs, don't include the "usesPermissionFlags"
                          attribute. -->
                     android:usesPermissionFlags="neverForLocation" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
                     <!-- If any feature in your app relies on precise location
                          information, don't include the "maxSdkVersion"
                          attribute. -->
                     android:maxSdkVersion="32" />
    
  2. تحقَّق مما إذا كان الجهاز متوافقًا مع Wi-Fi Aware من خلال واجهة برمجة التطبيقات PackageManager، كما هو موضّح أدناه:

    Kotlin

    context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)
    

    Java

    context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE);
    
  3. تحقّق مما إذا كانت خدمة Wi-Fi Aware متاحة حاليًا. قد تكون خدمة Wi-Fi متاحة على الجهاز، ولكنّها قد لا تكون متاحة حاليًا لأنّ المستخدم أوقف خدمة Wi-Fi أو الموقع الجغرافي. بناءً على إمكانيات الأجهزة والبرامج الثابتة، قد لا تتوافق بعض الأجهزة مع خدمة Wi-Fi Aware في حال استخدام Wi-Fi Direct أو SoftAP أو التوصيل. للتحقّق مما إذا كانت خدمة Wi-Fi Aware متوفّرة حاليًا، يمكنك الاتصال على الرقم isAvailable().

    قد يتغير مدى توفّر خدمة Wi-Fi Aware في أي وقت. يجب أن يسجّل تطبيقك BroadcastReceiver لتلقّي ACTION_WIFI_AWARE_STATE_CHANGED، ويتم إرساله عند تغيّر مدى التوفّر. عندما يتلقّى تطبيقك هدف البث، يجب أن يتجاهل جميع الجلسات الحالية (على افتراض أنّ خدمة Wi-Fi تعطّلت)، ثم تحقَّق من حالة التوفّر الحالية وعدِّل سلوكها وفقًا لذلك. على سبيل المثال:

    Kotlin

    val wifiAwareManager = context.getSystemService(Context.WIFI_AWARE_SERVICE) as WifiAwareManager?
    val filter = IntentFilter(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED)
    val myReceiver = object : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            // discard current sessions
            if (wifiAwareManager?.isAvailable) {
                ...
            } else {
                ...
            }
        }
    }
    context.registerReceiver(myReceiver, filter)
    

    Java

    WifiAwareManager wifiAwareManager = 
            (WifiAwareManager)context.getSystemService(Context.WIFI_AWARE_SERVICE)
    IntentFilter filter =
            new IntentFilter(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED);
    BroadcastReceiver myReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // discard current sessions
            if (wifiAwareManager.isAvailable()) {
                ...
            } else {
                ...
            }
        }
    };
    context.registerReceiver(myReceiver, filter);
    

لمزيد من المعلومات، يُرجى الاطّلاع على عمليات البث.

الحصول على جلسة

لبدء استخدام خدمة Wi-Fi Aware، يجب أن يحصل تطبيقك على WifiAwareSession من خلال الاتصال بـ attach(). تؤدي هذه الطريقة إلى ما يلي:

  • يؤدي هذا الخيار إلى تفعيل أجهزة Wi-Fi Aware.
  • الانضمام إلى مجموعة تتوفّر بها خدمة Wi-Fi Aware أو تشكيلها
  • يتم إنشاء جلسة Wi-Fi Aware مع مساحة اسم فريدة تعمل كحاوية لجميع جلسات الاكتشاف التي يتم إنشاؤها داخلها.

في حال إرفاق التطبيق بنجاح، ينفِّذ النظام عملية معاودة الاتصال onAttached(). توفّر معاودة الاتصال هذه كائن WifiAwareSession الذي يجب أن يستخدمه تطبيقك لجميع العمليات الإضافية للجلسة. يمكن للتطبيق استخدام الجلسة لنشر خدمة أو للاشتراك في خدمة.

يُفترَض أن يتصل تطبيقك بـ attach() مرة واحدة فقط. إذا اتصل تطبيقك بـ attach() عدة مرات، سيتلقّى التطبيق جلسة مختلفة لكل مكالمة، على أن يتضمّن كل منها مساحة اسم خاصة به. قد يكون هذا مفيدًا في سيناريوهات معقدة، ولكن يجب تجنبه بشكل عام.

نشر خدمة

لإتاحة اكتشاف خدمة، يمكنك استدعاء طريقة publish()، التي تستخدم المَعلمات التالية:

  • تحدّد السمة PublishConfig اسم الخدمة وخصائص الإعداد الأخرى، مثل فلتر المطابقة.
  • وتحدّد السمة DiscoverySessionCallback الإجراءات المطلوب تنفيذها عند وقوع الأحداث، مثل تلقّي المشترك رسالة.

إليك مثال على ذلك:

Kotlin

val config: PublishConfig = PublishConfig.Builder()
        .setServiceName(AWARE_FILE_SHARE_SERVICE_NAME)
        .build()
awareSession.publish(config, object : DiscoverySessionCallback() {

    override fun onPublishStarted(session: PublishDiscoverySession) {
        ...
    }

    override fun onMessageReceived(peerHandle: PeerHandle, message: ByteArray) {
        ...
    }
})

Java

PublishConfig config = new PublishConfig.Builder()
    .setServiceName(“Aware_File_Share_Service_Name”)
    .build();

awareSession.publish(config, new DiscoverySessionCallback() {
    @Override
    public void onPublishStarted(PublishDiscoverySession session) {
        ...
    }
    @Override
    public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
        ...
    }
}, null);

إذا نجحت عملية النشر، سيتم استدعاء طريقة معاودة الاتصال onPublishStarted().

بعد النشر، عندما تنتقل الأجهزة التي تشغل تطبيقات المشتركين المطابقة إلى نطاق Wi-Fi لجهاز النشر، يكتشف المشتركون الخدمة. عندما يكتشف المشترك ناشرًا، لا يتلقى الناشر إشعارًا، ولكن إذا أرسل المشترك رسالة إلى الناشر، يتلقى الناشر إشعارًا بذلك. وعند حدوث ذلك، يتم استدعاء طريقة معاودة الاتصال onMessageReceived(). ويمكنك استخدام الوسيطة PeerHandle من هذه الطريقة لإعادة إرسال رسالة إلى المشترك أو إنشاء اتصال بها.

لإيقاف نشر الخدمة، يمكنك الاتصال بـ DiscoverySession.close(). ترتبط جلسات Discovery بالعنصر الرئيسي WifiAwareSession. إذا كانت الجلسة الرئيسية مغلقة، فسيتم أيضًا إغلاق جلسات الاكتشاف المرتبطة بها. مع أنّ العناصر التي تم تجاهلها تكون مغلقة أيضًا، لا يضمن النظام إغلاق الجلسات خارج النطاق، لذا ننصحك باستدعاء طرق close() صراحةً.

الاشتراك في خدمة

للاشتراك في خدمة، استدعِ الطريقة subscribe()، التي تستخدم المعلَمات التالية:

  • تحدّد السمة SubscribeConfig اسم الخدمة المطلوب الاشتراك فيها وخصائص الإعداد الأخرى، مثل فلتر المطابقة.
  • تحدّد السمة DiscoverySessionCallback الإجراءات المطلوب تنفيذها عند وقوع أحداث، مثلاً عند اكتشاف ناشر.

إليك مثال على ذلك:

Kotlin

val config: SubscribeConfig = SubscribeConfig.Builder()
        .setServiceName(AWARE_FILE_SHARE_SERVICE_NAME)
        .build()
awareSession.subscribe(config, object : DiscoverySessionCallback() {

    override fun onSubscribeStarted(session: SubscribeDiscoverySession) {
        ...
    }

    override fun onServiceDiscovered(
            peerHandle: PeerHandle,
            serviceSpecificInfo: ByteArray,
            matchFilter: List<ByteArray>
    ) {
        ...
    }
}, null)

Java

SubscribeConfig config = new SubscribeConfig.Builder()
    .setServiceName("Aware_File_Share_Service_Name")
    .build();

awareSession.subscribe(config, new DiscoverySessionCallback() {
    @Override
    public void onSubscribeStarted(SubscribeDiscoverySession session) {
        ...
    }

    @Override
    public void onServiceDiscovered(PeerHandle peerHandle,
            byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
        ...
    }
}, null);

إذا نجحت عملية الاشتراك، يطلب النظام onSubscribeStarted() معاودة الاتصال في تطبيقك. وبما أنّه يمكنك استخدام وسيطة SubscribeDiscoverySession في رد الاتصال للتواصل مع أحد الناشرين بعد اكتشاف تطبيقك لأحد الناشرين، عليك حفظ هذا المرجع. ويمكنك تعديل جلسة الاشتراك متى شئت من خلال النقر على updateSubscribe() في جلسة الاكتشاف.

في هذه المرحلة، ينتظر اشتراكك وصول الناشرين المطابقين إلى نطاق شبكة Wi-Fi. عند حدوث ذلك، ينفِّذ النظام طريقة معاودة الاتصال onServiceDiscovered(). يمكنك استخدام الوسيطة PeerHandle من معاودة الاتصال هذه من أجل إرسال رسالة أو إنشاء اتصال بهذا الناشر.

لإيقاف الاشتراك في خدمة، يُرجى الاتصال DiscoverySession.close(). ترتبط جلسات Discovery بالعنصر الرئيسي WifiAwareSession. إذا كانت الجلسة الرئيسية مغلقة، فسيتم أيضًا إغلاق جلسات الاكتشاف المرتبطة بها. مع أنّ العناصر التي تم تجاهلها تكون مغلقة أيضًا، لا يضمن النظام إغلاق الجلسات خارج النطاق، لذا ننصحك باستدعاء طرق close() صراحةً.

إرسال رسالة

لإرسال رسالة إلى جهاز آخر، تحتاج إلى العناصر التالية:

  • DiscoverySession يتيح لك هذا الكائن استدعاء sendMessage(). يحصل تطبيقك على DiscoverySession إما عن طريق نشر خدمة أو الاشتراك في خدمة.

  • PeerHandle على الجهاز الآخر لتوجيه الرسالة. يحصل تطبيقك على PeerHandle الخاص بجهاز آخر بإحدى الطريقتين التاليتين:

    • ينشر تطبيقك خدمة ويتلقّى رسالة من أحد المشتركين. يحصل تطبيقك على PeerHandle الخاص بالمشترك من خلال معاودة الاتصال بـ onMessageReceived().
    • اشتراك تطبيقك في إحدى الخدمات وعندما يكتشف تطبيقك ناشرًا مطابقًا، يحصل تطبيقك على PeerHandle الخاصة بالناشر من معاودة الاتصال بـ onServiceDiscovered().

لإرسال رسالة، يمكنك الاتصال بالرقم sendMessage(). قد تحدث بعد ذلك عمليات معاودة الاتصال التالية:

  • عندما يستلم المستخدم الرسالة بنجاح، يطلب النظام onMessageSendSucceeded() معاودة الاتصال في تطبيق الإرسال.
  • عندما يتلقّى المستخدم الآخر رسالة إلكترونية، يطلب النظام onMessageReceived() معاودة الاتصال في تطبيق الاستلام.

على الرغم من أنّ PeerHandle مطلوب للتواصل مع التطبيقات المشابهة، يجب ألّا تعتمد عليه كمعرّف دائم للتطبيقات المشابهة. ويمكن استخدام المعرّفات ذات المستوى الأعلى من خلال التطبيق المضمن في خدمة الاكتشاف نفسها أو في الرسائل اللاحقة. يمكنك تضمين معرّف في خدمة الاكتشاف باستخدام طريقة setMatchFilter() أو setServiceSpecificInfo() PublishConfig أو SubscribeConfig. تؤثر طريقة setMatchFilter() في إمكانية العثور على المحتوى، ولكن طريقة setServiceSpecificInfo() لا تؤثر في إمكانية العثور على المحتوى.

يتضمن تضمين معرِّف في رسالة تعديل مصفوفة بايت الرسالة لتضمين معرِّف (على سبيل المثال، أول زوج من وحدات البايت).

إنشاء عملية ربط

تتوافق خدمة Wi-Fi Aware مع شبكات خادم العميل بين جهازين يتضمنان خدمة Wi-Fi.

لإعداد اتصال خادم العميل:

  1. يمكنك استخدام ميزة اكتشاف Wi-Fi من أجل نشر خدمة (على الخادم) والاشتراك في خدمة (على العميل).

  2. بعد أن يعثر المشترك على الناشر، يمكنك إرسال رسالة من المشترك إلى الناشر.

  3. ابدأ تشغيل ServerSocket على جهاز الناشر وعليك ضبط المنفذ الخاص به أو الحصول عليه:

    Kotlin

    val ss = ServerSocket(0)
    val port = ss.localPort
    

    Java

    ServerSocket ss = new ServerSocket(0);
    int port = ss.getLocalPort();
    
  4. استخدِم ConnectivityManager لطلب شبكة Wi-Fi Aware من الناشر باستخدام WifiAwareNetworkSpecifier، وتحديد جلسة الاكتشاف وPeerHandle الخاص بالمشترك، التي حصلت عليها من الرسالة التي أرسلها المشترك:

    Kotlin

    val networkSpecifier = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle)
        .setPskPassphrase("somePassword")
        .setPort(port)
        .build()
    val myNetworkRequest = NetworkRequest.Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
        .setNetworkSpecifier(networkSpecifier)
        .build()
    val callback = object : ConnectivityManager.NetworkCallback() {
        override fun onAvailable(network: Network) {
            ...
        }
    
        override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
            ...
        }
    
        override fun onLost(network: Network) {
            ...
        }
    }
    
    connMgr.requestNetwork(myNetworkRequest, callback);
    

    Java

    NetworkSpecifier networkSpecifier = new WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle)
        .setPskPassphrase("somePassword")
        .setPort(port)
        .build();
    NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
        .setNetworkSpecifier(networkSpecifier)
        .build();
    ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback() {
        @Override
        public void onAvailable(Network network) {
            ...
        }
    
        @Override
        public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
            ...
        }
    
        @Override
        public void onLost(Network network) {
            ...
        }
    };
    
    ConnectivityManager connMgr.requestNetwork(myNetworkRequest, callback);
    
  5. بعد أن يطلب الناشر شبكة، عليه إرسال رسالة إلى المشترك.

  6. بعد أن يتلقّى المشترك الرسالة من الناشر، اطلب الاتصال بشبكة Wi-Fi على المشترك باستخدام الطريقة نفسها المستخدَمة لدى الناشر. ولا تحدِّد منفذًا عند إنشاء NetworkSpecifier. ويتم استدعاء طرق معاودة الاتصال المناسبة عند توفر الاتصال بالشبكة أو تغييره أو فقدانه.

  7. بعد استدعاء طريقة onAvailable() إلى المشترك، يتوفر عنصر Network يمكنك من خلاله فتح Socket للتواصل مع ServerSocket على الناشر، ولكن عليك معرفة عنوان IPv6 الخاص بـ ServerSocket ومنفذه. وتحصل على هذه القيم من الكائن NetworkCapabilities المقدَّم في ميزة معاودة الاتصال onCapabilitiesChanged():

    Kotlin

    val peerAwareInfo = networkCapabilities.transportInfo as WifiAwareNetworkInfo
    val peerIpv6 = peerAwareInfo.peerIpv6Addr
    val peerPort = peerAwareInfo.port
    ...
    val socket = network.getSocketFactory().createSocket(peerIpv6, peerPort)
    

    Java

    WifiAwareNetworkInfo peerAwareInfo = (WifiAwareNetworkInfo) networkCapabilities.getTransportInfo();
    Inet6Address peerIpv6 = peerAwareInfo.getPeerIpv6Addr();
    int peerPort = peerAwareInfo.getPort();
    ...
    Socket socket = network.getSocketFactory().createSocket(peerIpv6, peerPort);
    
  8. عند الانتهاء من الاتصال بالشبكة، يمكنك الاتصال بالرقم unregisterNetworkCallback().

تصنيف التطبيقات المشابهة والاكتشاف المستند إلى الموقع الجغرافي

يمكن للجهاز الذي تتوفر فيه ميزة الموقع الجغرافي لميزة "مراسلة نصية في الوقت الفعلي" لشبكة Wi-Fi قياس المسافة مباشرةً مع الأجهزة المشابهة واستخدام هذه المعلومات لتقييد إمكانية اكتشاف خدمة Wi-Fi Aware.

تتيح واجهة برمجة التطبيقات Wi-Fi RTT API إمكانية الانتقال المباشر إلى تطبيق مشابه من خلال Wi-Fi Aware باستخدام عنوان MAC أو PeerHandle.

يمكن تقييد اكتشاف Wi-Fi لاكتشاف الخدمات ضمن حدود جغرافية معينة فقط. على سبيل المثال، يمكنك إعداد حدود جغرافية تسمح باكتشاف جهاز ينشر خدمة "Aware_File_Share_Service_Name" لا يبعد أقرب عن 3,000 ملم) ولا يزيد عن 10 أمتار (يُحدَّد على أنّه 10,000 ملم).

لتفعيل وضع حدود جغرافية، على كل من الناشر والمشترك اتخاذ الإجراءين التاليين:

  • يجب أن يفعّل الناشر النطاق على الخدمة المنشورة باستخدام setRangingEnabled(true).

    وإذا لم يفعّل الناشر النطاق، يتم تجاهل أي قيود على الحدود الجغرافية يحدّدها المشترك ويتم تنفيذ الاكتشاف العادي، مع تجاهل المسافة.

  • يجب أن يحدد المشترك سياجًا جغرافيًا باستخدام مزيج من setMinSpaceMm وsetMaxرحلاتMm.

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

عند اكتشاف خدمة نظير داخل سياج جغرافي، يتم تشغيل استدعاء onServiceDiscoveredWithinRange الذي يوفر المسافة التي تم قياسها للنظير. ويمكن بعد ذلك استدعاء واجهة برمجة التطبيقات Direct Wi-Fi RTT API حسب الضرورة لقياس المسافة في الأوقات اللاحقة.