ภาพรวมเกี่ยวกับ Wi-Fi Aware

ความสามารถของ Wi-Fi Aware ช่วยให้อุปกรณ์ที่ใช้ Android 8.0 (ระดับ API 26) ขึ้นไปค้นพบและเชื่อมต่อกับอุปกรณ์อื่นๆ ได้โดยตรงโดยไม่ต้องมีการเชื่อมต่อประเภทอื่น Wi-Fi Aware หรือที่เรียกว่า Neighbor Awareness Network (NAN)

เครือข่าย Wi-Fi Aware ทํางานโดยการสร้างคลัสเตอร์กับอุปกรณ์ใกล้เคียง หรือสร้างคลัสเตอร์ใหม่หากอุปกรณ์เป็นอุปกรณ์เครื่องแรกในพื้นที่ ลักษณะการรวมกลุ่มนี้จะมีผลกับทั้งอุปกรณ์และได้รับการจัดการโดยบริการระบบ Wi-Fi Aware แอปไม่มีสิทธิ์ควบคุมลักษณะการรวมกลุ่ม แอปใช้ Wi-Fi Aware API เพื่อสื่อสารกับบริการระบบ Wi-Fi Aware ซึ่งจัดการฮาร์ดแวร์ Wi-Fi Aware ในอุปกรณ์

Wi-Fi Aware API ช่วยให้แอปดำเนินการต่อไปนี้ได้

  • ค้นหาอุปกรณ์อื่นๆ: API มีกลไกในการค้นหาอุปกรณ์อื่นๆ ที่อยู่ใกล้เคียง กระบวนการจะเริ่มขึ้นเมื่ออุปกรณ์ 1 เครื่องเผยแพร่บริการที่ค้นพบได้อย่างน้อย 1 รายการ จากนั้นเมื่ออุปกรณ์สมัครใช้บริการอย่างน้อย 1 อย่างและเข้าสู่ระยะสัญญาณ Wi-Fi ของผู้เผยแพร่ ผู้สมัครใช้บริการจะได้รับการแจ้งเตือนว่าพบผู้เผยแพร่ที่ตรงกัน หลังจากค้นพบผู้เผยแพร่แล้ว ผู้สมัครใช้บริการสามารถส่งข้อความสั้นๆ หรือสร้างการเชื่อมต่อเครือข่ายกับอุปกรณ์ที่ค้นพบ อุปกรณ์สามารถเป็นผู้เผยแพร่และผู้ติดตามได้พร้อมกัน

  • สร้างการเชื่อมต่อเครือข่าย: หลังจากอุปกรณ์ 2 เครื่องค้นพบกันและกันแล้ว อุปกรณ์จะสร้างการเชื่อมต่อเครือข่าย Wi-Fi Aware แบบ 2 ทิศทางได้โดยไม่ต้องมีจุดเข้าใช้งาน

การเชื่อมต่อเครือข่าย Wi-Fi Aware รองรับอัตราการส่งข้อมูลที่สูงกว่าในระยะทางที่ไกลกว่าการเชื่อมต่อ Bluetooth การเชื่อมต่อประเภทนี้มีประโยชน์สําหรับแอปที่แชร์ข้อมูลจํานวนมากระหว่างผู้ใช้ เช่น แอปการแชร์รูปภาพ

การเพิ่มประสิทธิภาพ Android 13 (API ระดับ 33)

ในอุปกรณ์ที่ใช้ Android 13 (API ระดับ 33) ขึ้นไปซึ่งรองรับโหมดการสื่อสารทันใจ แอปสามารถใช้เมธอด PublishConfig.Builder.setInstantCommunicationModeEnabled() และ SubscribeConfig.Builder.setInstantCommunicationModeEnabled() เพื่อเปิดหรือปิดใช้โหมดการสื่อสารทันใจสำหรับเซสชันการค้นพบของผู้เผยแพร่โฆษณาหรือสมาชิก โหมดการสื่อสารแบบทันทีจะเร่งการแลกเปลี่ยนข้อความ การค้นพบบริการ และเส้นทางข้อมูลที่ตั้งค่าไว้เป็นส่วนหนึ่งของเซสชันการค้นพบของผู้เผยแพร่โฆษณาหรือผู้สมัครใช้บริการ หากต้องการระบุว่าอุปกรณ์รองรับโหมดการสื่อสารแบบทันทีหรือไม่ ให้ใช้เมธอด isInstantCommunicationModeSupported()

การเพิ่มประสิทธิภาพ Android 12 (API ระดับ 31)

Android 12 (API ระดับ 31) เพิ่มการปรับปรุงบางอย่างใน Wi-Fi Aware ดังนี้

  • ในอุปกรณ์ที่ใช้ Android 12 (API ระดับ 31) ขึ้นไป คุณสามารถใช้การเรียกกลับ onServiceLost() เพื่อรับการแจ้งเตือนเมื่อแอปสูญเสียบริการที่ค้นพบเนื่องจากบริการหยุดทำงานหรือย้ายออกนอกระยะสัญญาณ
  • การตั้งค่าเส้นทางข้อมูล Wi-Fi Aware เสร็จสมบูรณ์แล้ว เวอร์ชันก่อนหน้านี้ใช้การรับส่งข้อความ L2 เพื่อระบุที่อยู่ MAC ของผู้เริ่ม ซึ่งทำให้เกิดเวลาในการตอบสนอง ในอุปกรณ์ที่ใช้ Android 12 ขึ้นไป คุณสามารถกำหนดค่าอุปกรณ์ที่ตอบกลับ (เซิร์ฟเวอร์) ให้ยอมรับคู่สนทนาใดก็ได้ ซึ่งหมายความว่าอุปกรณ์ไม่จำเป็นต้องทราบที่อยู่ MAC ของผู้เริ่มก่อน ซึ่งจะเร่งความเร็วในการเปิดใช้งานเส้นทางข้อมูลและเปิดใช้ลิงก์แบบจุดต่อจุดหลายรายการด้วยคำขอเครือข่ายเพียงรายการเดียว
  • แอปที่ใช้ Android 12 ขึ้นไปสามารถใช้เมธอด WifiAwareManager.getAvailableAwareResources() เพื่อดูจำนวนเส้นทางข้อมูลที่พร้อมใช้งานในปัจจุบัน เผยแพร่เซสชัน และสมัครใช้บริการเซสชัน ซึ่งจะช่วยให้แอปทราบว่ามีทรัพยากรเพียงพอที่จะดำเนินการตามฟังก์ชันการทำงานที่ต้องการหรือไม่

การตั้งค่าเบื้องต้น

หากต้องการตั้งค่าแอปให้ใช้การค้นพบและเครือข่าย Wi-Fi Aware ให้ทำตามขั้นตอนต่อไปนี้

  1. ขอสิทธิ์ต่อไปนี้ในไฟล์ Manifest ของแอป

    <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 API ตามที่แสดงด้านล่างหรือไม่

    Kotlin

    context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)

    Java

    context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE);
  3. ตรวจสอบว่า Wi-Fi Aware พร้อมใช้งานในขณะนี้หรือไม่ Wi-Fi Aware อาจอยู่ในอุปกรณ์ แต่อาจไม่พร้อมใช้งานในขณะนี้เนื่องจากผู้ใช้ปิดใช้ Wi-Fi หรือตำแหน่งไว้ อุปกรณ์บางรุ่นอาจไม่รองรับ Wi-Fi Aware หากมีการใช้ Wi-Fi Direct, SoftAP หรือการแชร์อินเทอร์เน็ตผ่านมือถือ ทั้งนี้ขึ้นอยู่กับความสามารถของฮาร์ดแวร์และเฟิร์มแวร์ หากต้องการตรวจสอบว่า Wi-Fi Aware พร้อมใช้งานหรือไม่ ให้โทรไปที่ isAvailable()

    ความพร้อมใช้งานของ Wi-Fi Aware อาจเปลี่ยนแปลงได้ทุกเมื่อ แอปของคุณควรลงทะเบียน BroadcastReceiver เพื่อรับ ACTION_WIFI_AWARE_STATE_CHANGED ซึ่งระบบจะส่งทุกครั้งที่มีการเปลี่ยนแปลงความพร้อมจำหน่ายสินค้า เมื่อแอปของคุณได้รับ Intent ของการส่งข้อมูล ควรจะทิ้งเซสชันที่มีอยู่ทั้งหมด (สมมติว่าบริการ Wi-Fi Aware หยุดชะงัก) จากนั้นตรวจสอบสถานะความพร้อมใช้งานปัจจุบันและปรับลักษณะการทํางานให้เหมาะสม เช่น

    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 ที่มีเนมสเปซที่ไม่ซ้ำกันซึ่งทำหน้าที่เป็นคอนเทนเนอร์สำหรับเซสชันการค้นพบทั้งหมดที่สร้างภายใน

หากแนบแอปสำเร็จ ระบบจะเรียกใช้ Callback ของ 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);

หากเผยแพร่สําเร็จ ระบบจะเรียกใช้วิธี Callback ของ onPublishStarted()

หลังจากเผยแพร่แล้ว เมื่ออุปกรณ์ที่ใช้แอปสมาชิกที่ตรงกันเข้ามาอยู่ในระยะสัญญาณ Wi-Fi ของอุปกรณ์ที่เผยแพร่ สมาชิกก็จะค้นพบบริการดังกล่าว เมื่อผู้ติดตามค้นพบผู้เผยแพร่โฆษณา ผู้เผยแพร่โฆษณาจะไม่ได้รับแจ้ง แต่หากผู้ติดตามส่งข้อความถึงผู้เผยแพร่โฆษณา ผู้เผยแพร่โฆษณาก็จะได้รับแจ้ง เมื่อเกิดเหตุการณ์ดังกล่าว ระบบจะเรียกใช้เมธอด Callback ของ onMessageReceived() คุณสามารถใช้อาร์กิวเมนต์ PeerHandle จากเมธอดนี้เพื่อส่งข้อความกลับไปยังผู้ติดตาม หรือสร้างการเชื่อมต่อกับผู้ใช้รายดังกล่าว

หากต้องการหยุดเผยแพร่บริการ ให้โทรไปที่ DiscoverySession.close() เซสชันการค้นพบจะเชื่อมโยงกับ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() Callback ในแอป เนื่องจากคุณสามารถใช้อาร์กิวเมนต์ SubscribeDiscoverySession ใน Callback เพื่อสื่อสารกับผู้เผยแพร่โฆษณาหลังจากที่แอปพบ 1 แอป คุณจึงควรบันทึกการอ้างอิงนี้ คุณสามารถอัปเดตเซสชันการสมัครใช้บริการได้ทุกเมื่อโดยเรียกใช้ updateSubscribe() ในเซสชันการค้นพบ

ณ จุดนี้ การสมัครใช้บริการของคุณจะรอให้ผู้เผยแพร่ที่ตรงกันมีสัญญาณ Wi-Fi ในกรณีนี้ ระบบจะเรียกใช้เมธอด callback ของ onServiceDiscovered() คุณสามารถใช้อาร์กิวเมนต์ PeerHandleจากคอลแบ็กนี้เพื่อส่งข้อความหรือสร้างการเชื่อมต่อกับผู้เผยแพร่โฆษณารายนั้น

หากต้องการหยุดสมัครใช้บริการ ให้โทรไปที่ DiscoverySession.close() เซสชันการค้นพบจะเชื่อมโยงกับWifiAwareSessionหลัก หากเซสชันหลักปิดอยู่ เซสชันการค้นพบที่เกี่ยวข้องก็จะปิดด้วย แม้ว่าระบบจะปิดออบเจ็กต์ที่ทิ้งไปแล้วด้วย แต่ระบบไม่สามารถรับประกันได้ว่าเซสชันที่อยู่นอกขอบเขตจะปิดเมื่อใด เราจึงขอแนะนำให้คุณเรียกใช้เมธอด close()อย่างชัดเจน

ส่งข้อความ

หากต้องการส่งข้อความไปยังอุปกรณ์อื่น คุณต้องมีออบเจ็กต์ต่อไปนี้

  • DiscoverySession ออบเจ็กต์นี้ช่วยให้คุณเรียกใช้ sendMessage() ได้ แอปของคุณจะได้รับ DiscoverySession โดยเผยแพร่บริการหรือสมัครใช้บริการ

  • PeerHandle ของอุปกรณ์เครื่องอื่นเพื่อส่งข้อความ แอปของคุณจะได้รับPeerHandleของอุปกรณ์อื่นด้วยวิธีใดวิธีหนึ่งต่อไปนี้

    • แอปเผยแพร่บริการและรับข้อความจากสมาชิก แอปของคุณจะได้รับ PeerHandle ของผู้ติดตามจาก onMessageReceived() callback
    • แอปของคุณสมัครใช้บริการ จากนั้นเมื่อพบผู้เผยแพร่โฆษณาที่ตรงกัน แอปของคุณจะได้รับPeerHandleของผู้เผยแพร่โฆษณาจาก callback ของ onServiceDiscovered()

หากต้องการส่งข้อความ ให้โทรไปที่ sendMessage() จากนั้นอาจมีการเรียกกลับต่อไปนี้

  • เมื่อแอปเทียบเท่าได้รับข้อความเรียบร้อยแล้ว ระบบจะเรียก onMessageSendSucceeded() การเรียกกลับในแอปการส่ง
  • เมื่อคู่สนทนาได้รับข้อความ ระบบจะเรียกใช้ callback ของ onMessageReceived() ในแอปที่รับ

แม้ว่าจะต้องใช้ PeerHandle เพื่อสื่อสารกับคู่ค้า แต่คุณไม่ควรใช้ PeerHandle เป็นตัวระบุถาวรของคู่ค้า ตัวระบุระดับสูงขึ้นสามารถใช้โดยแอปพลิเคชันที่ฝังอยู่ในบริการสำรวจหรือในข้อความต่อๆ มา คุณฝังตัวระบุไว้ในบริการค้นพบได้ด้วยวิธีการ setMatchFilter() หรือ setServiceSpecificInfo() ของ PublishConfig หรือ SubscribeConfig เมธอด setMatchFilter() จะส่งผลต่อการค้นพบ แต่เมธอด setServiceSpecificInfo() จะไม่ส่งผลต่อการค้นพบ

การฝังตัวระบุในข้อความหมายความว่ามีการแก้ไขอาร์เรย์ไบต์ของข้อความให้รวมตัวระบุ (เช่น เป็นไบต์ 2-3 ตัวแรก)

สร้างการเชื่อมต่อ

Wi-Fi Aware รองรับเครือข่ายไคลเอ็นต์-เซิร์ฟเวอร์ระหว่างอุปกรณ์ Wi-Fi Aware 2 เครื่อง

วิธีตั้งค่าการเชื่อมต่อไคลเอ็นต์กับเซิร์ฟเวอร์

  1. ใช้การค้นพบ Wi-Fi Aware เพื่อเผยแพร่บริการ (บนเซิร์ฟเวอร์) และสมัครใช้บริการ (บนไคลเอ็นต์)

  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 Aware จากผู้สมัครใช้บริการโดยใช้วิธีการเดียวกับที่ผู้เผยแพร่โฆษณาใช้ อย่าระบุพอร์ตเมื่อสร้าง 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()

การระบุช่วงระยะสัญญาณของอุปกรณ์ระยะไกลและการค้นพบที่คำนึงถึงตำแหน่ง

อุปกรณ์ที่พร้อมใช้งานตำแหน่ง RTT ของ Wi-Fi จะวัดระยะทางไปยังอุปกรณ์อื่นๆ ได้โดยตรง และใช้ข้อมูลนี้เพื่อจำกัดการค้นพบบริการ Wi-Fi Aware

Wi-Fi RTT API ช่วยให้สามารถวัดระยะทางไปยังอุปกรณ์ที่เปิดใช้ Wi-Fi Aware ได้โดยตรงโดยใช้ที่อยู่ MAC หรือ PeerHandle

การค้นพบ Wi-Fi Aware สามารถจำกัดให้ค้นพบเฉพาะบริการภายในเขตพื้นที่เสมือนที่เฉพาะเจาะจง เช่น คุณสามารถตั้งค่าเขตพื้นที่เสมือนที่อนุญาตให้ค้นพบอุปกรณ์ที่เผยแพร่บริการ "Aware_File_Share_Service_Name" ที่ไม่อยู่ใกล้กว่า 3 เมตร (ระบุเป็น 3,000 มม.) และไม่เกิน 10 เมตร (ระบุเป็น 10,000 มม.)

หากต้องการเปิดใช้การกำหนดเขตพื้นที่เสมือน ทั้งผู้เผยแพร่และผู้สมัครใช้บริการต้องดำเนินการดังต่อไปนี้

  • ผู้เผยแพร่โฆษณาต้องเปิดใช้การวัดระยะทางในบริการที่เผยแพร่โดยใช้ setRangingEnabled(true)

    หากผู้เผยแพร่โฆษณาไม่ได้เปิดใช้การระบุระยะทาง ระบบจะไม่สนใจข้อจำกัดของเขตพื้นที่เสมือนที่ระบุโดยสมาชิก และจะทำการค้นพบตามปกติโดยไม่สนใจระยะทาง

  • สมาชิกต้องระบุเขตพื้นที่เสมือนโดยใช้ setMinDistanceMm และ setMaxDistanceMm ร่วมกัน

    สำหรับค่าใดค่าหนึ่ง ระยะทางที่ไม่ได้ระบุจะถือว่าไม่มีขีดจำกัด เฉพาะการระบุระยะทางสูงสุดจะถือว่าระยะทางขั้นต่ำคือ 0 การระบุเฉพาะระยะทางต่ำสุดจะถือว่าไม่มีระยะทางสูงสุด

เมื่อพบบริการของบุคคลอื่นภายในเขตพื้นที่เสมือน ระบบจะเรียกใช้การเรียกกลับ onServiceDiscoveredWithinRange ซึ่งระบุระยะทางที่วัดได้ไปยังบุคคลนั้น คุณจะเรียกใช้ RTT API ของ Wi-Fi โดยตรงตามที่จำเป็นในการวัดระยะทางในภายหลังได้