Android 17 มาพร้อมฟีเจอร์และ API ใหม่ๆ ที่ยอดเยี่ยมสำหรับนักพัฒนาแอป ส่วนต่อไปนี้จะสรุปฟีเจอร์เหล่านี้เพื่อช่วยให้คุณเริ่มต้นใช้งาน API ที่เกี่ยวข้องได้
ดูรายการ API ใหม่, API ที่แก้ไข และ API ที่นำออกโดยละเอียดได้ที่รายงานความแตกต่างของ API ดูรายละเอียดเกี่ยวกับ API ใหม่ได้ที่เอกสารอ้างอิง Android API ซึ่งจะไฮไลต์ API ใหม่เพื่อให้เห็นได้ชัดเจน
นอกจากนี้ คุณควรตรวจสอบส่วนที่การเปลี่ยนแปลงแพลตฟอร์มอาจส่งผลต่อแอปของคุณด้วย ดูข้อมูลเพิ่มเติมได้ที่หน้าต่อไปนี้
- การเปลี่ยนแปลงลักษณะการทำงานที่ส่งผลต่อแอปเมื่อกำหนดเป้าหมายเป็น Android 17
- การเปลี่ยนแปลงลักษณะการทำงานที่ส่งผลต่อแอปทั้งหมด ไม่ว่าจะเป็น
targetSdkVersionก็ตาม
ฟังก์ชันหลัก
Android 17 เพิ่มฟีเจอร์ใหม่ต่อไปนี้ที่เกี่ยวข้องกับฟังก์ชันการทำงานหลักของ Android
ทริกเกอร์ ProfilingManager ใหม่
Android 17 เพิ่มทริกเกอร์ระบบใหม่หลายรายการลงใน ProfilingManager เพื่อช่วยคุณรวบรวมข้อมูลเชิงลึกเพื่อแก้ไขข้อบกพร่องด้านประสิทธิภาพ
ทริกเกอร์ใหม่มีดังนี้
TRIGGER_TYPE_COLD_START: ทริกเกอร์เกิดขึ้นระหว่างการเปิดแอปแบบ Cold Start โดยจะแสดงทั้งตัวอย่างสแต็กการเรียกใช้และการติดตามของระบบในการตอบกลับTRIGGER_TYPE_OOM: ทริกเกอร์จะเกิดขึ้นเมื่อแอปแสดงOutOfMemoryErrorและให้ฮีปดัมป์ของ Java เป็นการตอบสนองTRIGGER_TYPE_KILL_EXCESSIVE_CPU_USAGE: ทริกเกอร์จะเกิดขึ้นเมื่อแอปถูกปิดเนื่องจากการใช้งาน CPU ที่ผิดปกติและมากเกินไป และจะแสดงตัวอย่างสแต็กการเรียกใช้ในการตอบกลับTRIGGER_TYPE_ANOMALY: ตรวจจับความผิดปกติของประสิทธิภาพของระบบ เช่น การเรียกใช้ Binder มากเกินไปและการใช้งานหน่วยความจำมากเกินไป
หากต้องการทำความเข้าใจวิธีตั้งค่าทริกเกอร์ระบบ โปรดดูเอกสารประกอบเกี่ยวกับการทำโปรไฟล์ตามทริกเกอร์และวิธีเรียกข้อมูลและวิเคราะห์เอกสารประกอบการทำโปรไฟล์
ทริกเกอร์การทำโปรไฟล์สำหรับความผิดปกติของแอป
Android 17 เปิดตัวบริการตรวจจับความผิดปกติในอุปกรณ์ ซึ่งจะตรวจสอบพฤติกรรมที่ใช้ทรัพยากรมากและปัญหาความเข้ากันได้ที่อาจเกิดขึ้น บริการนี้ผสานรวมกับ ProfilingManager เพื่อช่วยให้แอปของคุณได้รับอาร์ติแฟกต์การทำโปรไฟล์ที่ทริกเกอร์โดยเหตุการณ์ที่ระบบตรวจพบ
ใช้ทริกเกอร์ TRIGGER_TYPE_ANOMALY เพื่อตรวจหาปัญหาด้านประสิทธิภาพของระบบ เช่น การเรียก Binder มากเกินไปและการใช้งานหน่วยความจำมากเกินไป เมื่อแอปละเมิดขีดจำกัดหน่วยความจำที่ระบบปฏิบัติการกำหนด ทริกเกอร์ความผิดปกติจะช่วยให้นักพัฒนาแอปได้รับฮีปดัมป์เฉพาะแอปเพื่อช่วยระบุและแก้ไขปัญหาเกี่ยวกับหน่วยความจำ นอกจากนี้ สำหรับสแปม Binder ที่มากเกินไป ทริกเกอร์ความผิดปกติจะแสดงโปรไฟล์แบบสุ่มของสแต็กในธุรกรรม Binder
การเรียกกลับ API นี้จะเกิดขึ้นก่อนการบังคับใช้ที่ระบบกำหนด เช่น ช่วยให้นักพัฒนาแอปเก็บรวบรวมข้อมูลการแก้ไขข้อบกพร่องก่อนที่ระบบจะหยุดแอปเนื่องจากใช้หน่วยความจำเกินขีดจำกัด
val profilingManager =
applicationContext.getSystemService(ProfilingManager::class.java)
val triggers = ArrayList<ProfilingTrigger>()
triggers.add(ProfilingTrigger.Builder(ProfilingTrigger.TRIGGER_TYPE_ANOMALY))
val mainExecutor: Executor = Executors.newSingleThreadExecutor()
val resultCallback = Consumer<ProfilingResult> { profilingResult ->
if (profilingResult.errorCode != ProfilingResult.ERROR_NONE) {
// upload profile result to server for further analysis
setupProfileUploadWorker(profilingResult.resultFilePath)
}
profilingManager.registerForAllProfilingResults(mainExecutor,
resultCallback)
profilingManager.addProfilingTriggers(triggers)
}
JobDebugInfo API
Android 17 เปิดตัว API JobDebugInfo ใหม่เพื่อช่วยนักพัฒนาแอปแก้ไขข้อบกพร่องของงาน JobScheduler เช่น สาเหตุที่งานไม่ทำงาน ระยะเวลาที่งานทำงาน และข้อมูลแบบรวมอื่นๆ
เมธอดแรกของ JobDebugInfo API ที่ขยายคือ getPendingJobReasonStats() ซึ่งจะแสดงผลแผนที่ของเหตุผลที่งานอยู่ในสถานะรอดำเนินการและระยะเวลารอดำเนินการสะสมที่เกี่ยวข้อง เมธอดนี้จะรวมเมธอด getPendingJobReasonsHistory() และ getPendingJobReasons() เพื่อให้ข้อมูลเชิงลึกเกี่ยวกับสาเหตุที่งานที่กำหนดเวลาไว้ไม่ทำงานตามที่คาดไว้ แต่จะลดความซับซ้อนของการดึงข้อมูลโดยทำให้ทั้งระยะเวลาและเหตุผลของงานพร้อมใช้งานในเมธอดเดียว
ตัวอย่างเช่น สำหรับ jobId ที่ระบุ เมธอดอาจแสดงผลเป็น PENDING_JOB_REASON_CONSTRAINT_CHARGING และระยะเวลา 60,000 มิลลิวินาที ซึ่งบ่งชี้ว่างานรอดำเนินการเป็นเวลา 60,000 มิลลิวินาทีเนื่องจากไม่เป็นไปตามข้อจำกัดการชาร์จ
ลด Wake Lock ด้วยการรองรับ Listener สำหรับการปลุกที่อนุญาตขณะไม่มีการใช้งาน
Android 17 เปิดตัวตัวแปรใหม่ของ AlarmManager.setExactAndAllowWhileIdle ที่ยอมรับ OnAlarmListener แทน PendingIntent กลไกใหม่ที่อิงตาม Callback นี้เหมาะอย่างยิ่งสำหรับแอปที่ปัจจุบันอาศัย Wakelock แบบต่อเนื่องเพื่อทำงานเป็นระยะๆ เช่น แอปรับส่งข้อความที่รักษาการเชื่อมต่อซ็อกเก็ต
ความเป็นส่วนตัว
Android 17 มีฟีเจอร์ใหม่ต่อไปนี้เพื่อปรับปรุงความเป็นส่วนตัวของผู้ใช้
การรองรับแพลตฟอร์ม Encrypted Client Hello (ECH)
Android 17 เปิดตัวการรองรับแพลตฟอร์มสำหรับ Encrypted Client Hello (ECH) ซึ่งเป็นการปรับปรุงความเป็นส่วนตัวที่สำคัญสำหรับการสื่อสารผ่านเครือข่าย ECH เป็นส่วนขยายของ TLS 1.3 ที่เข้ารหัสการระบุชื่อเซิร์ฟเวอร์ (SNI) ระหว่างแฮนด์เชค TLS เริ่มต้น การเข้ารหัสนี้ช่วยปกป้องความเป็นส่วนตัวของผู้ใช้ด้วยการทำให้ตัวกลางในเครือข่ายระบุโดเมนที่เฉพาะเจาะจงซึ่งแอปเชื่อมต่อได้ยากขึ้น
ตอนนี้แพลตฟอร์มมี API ที่จำเป็นสำหรับไลบรารีระบบเครือข่ายเพื่อใช้ ECH แล้ว ซึ่งรวมถึงความสามารถใหม่ใน DnsResolver ในการค้นหาระเบียน DNS ของ HTTPS ที่มีการกำหนดค่า ECH และเมธอดใหม่ใน SSLEngines และ SSLSockets ของ Conscrypt เพื่อเปิดใช้ ECH โดยการส่งการกำหนดค่าเหล่านี้เมื่อเชื่อมต่อกับโดเมน นักพัฒนาแอปสามารถกำหนดค่ากำหนด ECH เช่น
การเปิดใช้แบบมีโอกาสหรือการกำหนดให้ใช้ ผ่านองค์ประกอบใหม่
<domainEncryption> ภายในไฟล์การกำหนดค่าความปลอดภัยของเครือข่าย
ซึ่งใช้ได้ทั่วโลกหรือในระดับโดเมน
คาดว่าไลบรารีเครือข่ายยอดนิยม เช่น HttpEngine, WebView และ OkHttp จะผสานรวม API ของแพลตฟอร์มเหล่านี้ในการอัปเดตในอนาคต ซึ่งจะช่วยให้แอปนำ ECH ไปใช้และปรับปรุงความเป็นส่วนตัวของผู้ใช้ได้ง่ายขึ้น
ดูข้อมูลเพิ่มเติมได้ที่เอกสารประกอบการทักทายไคลเอ็นต์ที่เข้ารหัส
เครื่องมือเลือกรายชื่อติดต่อ Android
เครื่องมือเลือกรายชื่อติดต่อ Android เป็นอินเทอร์เฟซที่ได้มาตรฐานและเรียกดูได้สำหรับผู้ใช้ในการแชร์รายชื่อติดต่อกับแอปของคุณ เครื่องมือเลือกนี้พร้อมใช้งานในอุปกรณ์ที่ใช้ Android 17 (API ระดับ 37) ขึ้นไป โดยเป็นทางเลือกที่รักษาความเป็นส่วนตัวแทนสิทธิ์ READ_CONTACTS แบบกว้าง แทนที่จะขอสิทธิ์เข้าถึงสมุดที่อยู่ทั้งหมดของผู้ใช้ แอปของคุณจะระบุฟิลด์ข้อมูลที่ต้องการ เช่น หมายเลขโทรศัพท์หรืออีเมล และผู้ใช้จะเลือกรายชื่อติดต่อที่ต้องการแชร์ ซึ่งจะให้สิทธิ์แอปของคุณเข้าถึงแบบอ่านเฉพาะข้อมูลที่เลือกเท่านั้น เพื่อให้ควบคุมได้อย่างละเอียด พร้อมทั้งมอบประสบการณ์ของผู้ใช้ที่สอดคล้องกันด้วยความสามารถในการค้นหา การสลับโปรไฟล์ Search และการเลือกหลายรายการในตัว โดยไม่ต้องสร้างหรือดูแลรักษา UI
ดูข้อมูลเพิ่มเติมได้ที่เอกสารประกอบเกี่ยวกับเครื่องมือเลือกรายชื่อติดต่อ
ความปลอดภัย
Android 17 เพิ่มฟีเจอร์ใหม่ต่อไปนี้เพื่อปรับปรุงความปลอดภัยของอุปกรณ์และแอป
โหมดการปกป้องขั้นสูงของ Android (AAPM)
โหมดการปกป้องขั้นสูงของ Android มอบฟีเจอร์ด้านความปลอดภัยชุดใหม่ที่ทรงพลังให้แก่ผู้ใช้ Android ซึ่งถือเป็นก้าวสำคัญในการปกป้องผู้ใช้ โดยเฉพาะผู้ที่มีความเสี่ยงสูงจากการโจมตีที่ซับซ้อน AAPM ออกแบบมาให้เป็นฟีเจอร์ที่เลือกใช้ได้ โดยจะเปิดใช้งานด้วยการตั้งค่าเดียวที่ผู้ใช้เปิดได้ทุกเมื่อ เพื่อใช้ชุดการป้องกันความปลอดภัยที่กำหนดไว้
การกำหนดค่าหลักเหล่านี้รวมถึงการบล็อกการติดตั้งแอปจากแหล่งที่มาที่ไม่รู้จัก
(การโหลดจากแหล่งที่ไม่รู้จัก) การจำกัดการส่งสัญญาณข้อมูลผ่าน USB และการกำหนดให้สแกนด้วย Google Play Protect
ซึ่งจะช่วยลดพื้นที่ผิวการโจมตีของอุปกรณ์ได้อย่างมาก
นักพัฒนาแอปสามารถผสานรวมกับฟีเจอร์นี้ได้โดยใช้ API AdvancedProtectionManager เพื่อตรวจหาสถานะของโหมด ซึ่งจะช่วยให้แอปพลิเคชันใช้ท่าทีด้านความปลอดภัยที่เข้มงวดขึ้นโดยอัตโนมัติ หรือจำกัดฟังก์ชันการทำงานที่มีความเสี่ยงสูงเมื่อผู้ใช้เลือกใช้
การรับรอง APK ด้วย PQC
ตอนนี้ Android รองรับ APK Signature Scheme แบบไฮบริดเพื่อเตรียมความพร้อมสำหรับอนาคตในการลงนามข้อมูลประจำตัวของแอปเพื่อป้องกันภัยคุกคามที่อาจเกิดขึ้นจากการโจมตีที่ใช้คอมพิวเตอร์ควอนตัม ฟีเจอร์นี้เปิดตัวรูปแบบลายเซ็น APK ใหม่ ซึ่งช่วยให้คุณจับคู่คีย์การรับรองแบบคลาสสิก (เช่น RSA หรือ EC) กับอัลกอริทึมวิทยาการเข้ารหัสหลังยุคควอนตัม (PQC) ใหม่ (ML-DSA) ได้
แนวทางแบบไฮบริดนี้ช่วยให้แอปของคุณปลอดภัยจากการโจมตีด้วยควอนตัมในอนาคต ขณะเดียวกันก็ยังคงเข้ากันได้แบบย้อนหลังอย่างสมบูรณ์กับ Android เวอร์ชันเก่าและอุปกรณ์ที่ใช้การยืนยันลายเซ็นแบบคลาสสิก
ผลกระทบต่อนักพัฒนาแอป
- แอปที่ใช้ Play App Signing: หากใช้ Play App Signing คุณสามารถรอให้ Google Play มีตัวเลือกในการอัปเกรดลายเซ็นแบบไฮบริดโดยใช้คีย์ PQC ที่ Google Play สร้างขึ้น เพื่อให้มั่นใจว่าแอปได้รับการปกป้องโดยไม่ต้องจัดการคีย์ด้วยตนเอง
- แอปที่ใช้คีย์ที่จัดการด้วยตนเอง: นักพัฒนาแอปที่จัดการคีย์ Signing ของตนเองสามารถใช้เครื่องมือสร้าง Android ที่อัปเดตแล้ว (เช่น apksigner) เพื่อหมุนเวียนไปใช้ข้อมูลประจำตัวแบบไฮบริด ซึ่งรวมคีย์ PQC เข้ากับคีย์แบบคลาสสิกใหม่ (คุณต้องสร้างคีย์แบบคลาสสิกใหม่ โดยจะใช้คีย์เดิมซ้ำไม่ได้)
การเชื่อมต่อ
Android 17 เพิ่มฟีเจอร์ต่อไปนี้เพื่อปรับปรุงการเชื่อมต่อของอุปกรณ์และแอป
เครือข่ายดาวเทียมที่มีข้อจำกัด
ใช้การเพิ่มประสิทธิภาพเพื่อให้แอปทำงานได้อย่างมีประสิทธิภาพผ่านเครือข่ายดาวเทียมที่มีแบนด์วิดท์ต่ำ
ประสบการณ์ของผู้ใช้และ UI ของระบบ
Android 17 มีการเปลี่ยนแปลงต่อไปนี้เพื่อปรับปรุงประสบการณ์ของผู้ใช้
สตรีมเสียงผู้ช่วยโดยเฉพาะ
Android 17 เปิดตัวสตรีมเสียงผู้ช่วยโดยเฉพาะสำหรับแอป Assistant เพื่อเล่นด้วย USAGE_ASSISTANT การเปลี่ยนแปลงนี้จะแยกเสียงของ Assistant ออกจากสตรีมสื่อมาตรฐาน ทำให้ผู้ใช้ควบคุมระดับเสียงทั้ง 2 แบบแยกกันได้ ซึ่งจะช่วยให้สามารถดำเนินการต่างๆ ได้ เช่น การปิดเสียงการเล่นสื่อขณะที่ยังคงได้ยินเสียงคำตอบของ Assistant และในทางกลับกัน
แอปผู้ช่วยที่มีสิทธิ์เข้าถึงโหมดเสียง MODE_ASSISTANT_CONVERSATION ใหม่จะช่วยปรับปรุงความสอดคล้องของการควบคุมระดับเสียงได้มากขึ้น แอปผู้ช่วยสามารถใช้โหมดนี้เพื่อบอกใบ้ระบบเกี่ยวกับเซสชัน Assistant ที่ใช้งานอยู่ เพื่อให้มั่นใจว่าสตรีม Assistant จะควบคุมได้นอกการเล่น USAGE_ASSISTANT ที่ใช้งานอยู่หรือด้วยอุปกรณ์ต่อพ่วงบลูทูธที่เชื่อมต่อ
Handoff
Handoff เป็นฟีเจอร์และ API ใหม่ที่กำลังจะเปิดตัวใน Android 17 ซึ่งนักพัฒนาแอปสามารถผสานรวมเพื่อมอบความต่อเนื่องในการใช้งานข้ามอุปกรณ์ให้แก่ผู้ใช้ได้ ซึ่งช่วยให้ผู้ใช้เริ่มกิจกรรมของแอปในอุปกรณ์ Android เครื่องหนึ่งและเปลี่ยนไปใช้กิจกรรมดังกล่าวในอุปกรณ์ Android อีกเครื่องได้ Handoff จะทำงานในเบื้องหลังของอุปกรณ์ของผู้ใช้ และแสดงกิจกรรมที่พร้อมใช้งานจากอุปกรณ์อื่นๆ ที่อยู่ใกล้เคียงของผู้ใช้ผ่านจุดแรกเข้าต่างๆ เช่น Launcher และแถบงานในอุปกรณ์ที่รับข้อมูล
แอปสามารถกำหนดให้ Handoff เปิดแอป Android แบบเนทีฟเดียวกันได้ หากติดตั้งและพร้อมใช้งานในอุปกรณ์ที่รับ ในขั้นตอนแบบแอปต่อแอปนี้ ระบบจะทำ Deep Link ผู้ใช้ไปยังกิจกรรมที่กำหนด หรือจะเสนอการส่งต่อจากแอปไปยังเว็บเป็นตัวเลือกสำรองหรือติดตั้งใช้งานโดยตรงด้วยการส่งต่อ URL ก็ได้
การรองรับ Handoff จะใช้ตามกิจกรรม หากต้องการเปิดใช้ Handoff ให้เรียกใช้เมธอด setHandoffEnabled() สำหรับกิจกรรม อาจต้องส่งข้อมูลเพิ่มเติมไปพร้อมกับการส่งต่อเพื่อให้กิจกรรมที่สร้างขึ้นใหม่ในอุปกรณ์ที่รับสามารถกู้คืนสถานะที่เหมาะสมได้ ใช้ Callback onHandoffActivityDataRequested() เพื่อแสดงผลออบเจ็กต์ HandoffActivityData ซึ่งมีรายละเอียดที่ระบุวิธีที่ Handoff ควรจัดการและสร้างกิจกรรมใหม่ในอุปกรณ์ที่รับ
ข้อมูลอัปเดตแบบเรียลไทม์ - API สีเชิงความหมาย
ใน Android 17 Live Update จะเปิดตัว Semantic Coloring API เพื่อรองรับสีที่มีความหมายสากล
คลาสต่อไปนี้รองรับการใช้สีตามความหมาย
NotificationNotification.MetricNotification.ProgressStyle.PointNotification.ProgressStyle.Segment
เกมระบายสี
- สีเขียว: เกี่ยวข้องกับความปลอดภัย ควรใช้สีนี้ในกรณีที่ต้องการให้ผู้อื่นทราบว่าคุณอยู่ในสถานการณ์ที่ปลอดภัย
- สีส้ม: สำหรับระบุข้อควรระวังและทำเครื่องหมายอันตรายทางกายภาพ ควรใช้สีนี้ในสถานการณ์ที่ผู้ใช้ต้องให้ความสนใจเพื่อตั้งค่าการปกป้องที่ดีขึ้น
- สีแดง: โดยทั่วไปหมายถึงอันตราย ให้หยุด ควรแสดงในกรณีที่ต้องการความสนใจจากผู้ใช้อย่างเร่งด่วน
- สีน้ำเงิน: สีกลางสำหรับเนื้อหาที่เป็นข้อมูลและควรโดดเด่นกว่าเนื้อหาอื่นๆ
ตัวอย่างต่อไปนี้แสดงวิธีใช้รูปแบบเชิงความหมายกับข้อความในการแจ้งเตือน
val ssb = SpannableStringBuilder()
.append("Colors: ")
.append("NONE", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_UNSPECIFIED), 0)
.append(", ")
.append("INFO", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_INFO), 0)
.append(", ")
.append("SAFE", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_SAFE), 0)
.append(", ")
.append("CAUTION", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_CAUTION), 0)
.append(", ")
.append("DANGER", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_DANGER), 0)
Notification.Builder(context, channelId)
.setSmallIcon(R.drawable.ic_icon)
.setContentTitle("Hello World!")
.setContentText(ssb)
.setOngoing(true)
.setRequestPromotedOngoing(true)
UWB Downlink-TDoA API สำหรับ Android 17
การกำหนดระยะ Downlink Time Difference of Arrival (DL-TDoA) ช่วยให้อุปกรณ์ระบุตำแหน่งของตนเองที่สัมพันธ์กับ Anchor หลายรายการได้โดยการวัดเวลาที่สัญญาณมาถึงที่สัมพันธ์กันข้อมูลโค้ดต่อไปนี้แสดงวิธีเริ่มต้นเครื่องมือจัดการการวัดระยะ, ยืนยันความสามารถของอุปกรณ์ และเริ่มเซสชัน DL-TDoA
Kotlin
class RangingApp {
fun initDlTdoa(context: Context) {
// Initialize the Ranging Manager
val rangingManager = context.getSystemService(RangingManager::class.java)
// Register for device capabilities
val capabilitiesCallback = object : RangingManager.RangingCapabilitiesCallback {
override fun onRangingCapabilities(capabilities: RangingCapabilities) {
// Make sure Dl-TDoA is supported before starting the session
if (capabilities.uwbCapabilities != null && capabilities.uwbCapabilities!!.isDlTdoaSupported) {
startDlTDoASession(context)
}
}
}
rangingManager.registerCapabilitiesCallback(Executors.newSingleThreadExecutor(), capabilitiesCallback)
}
fun startDlTDoASession(context: Context) {
// Initialize the Ranging Manager
val rangingManager = context.getSystemService(RangingManager::class.java)
// Create session and configure parameters
val executor = Executors.newSingleThreadExecutor()
val rangingSession = rangingManager.createRangingSession(executor, RangingSessionCallback())
val rangingRoundIndexes = byteArrayOf(0)
val config: ByteArray = byteArrayOf() // OOB config data
val params = DlTdoaRangingParams.createFromFiraConfigPacket(config, rangingRoundIndexes)
val rangingDevice = RangingDevice.Builder().build()
val rawTagDevice = RawRangingDevice.Builder()
.setRangingDevice(rangingDevice)
.setDlTdoaRangingParams(params)
.build()
val dtTagConfig = RawDtTagRangingConfig.Builder(rawTagDevice).build()
val preference = RangingPreference.Builder(DEVICE_ROLE_DT_TAG, dtTagConfig)
.setSessionConfig(SessionConfig.Builder().build())
.build()
// Start the ranging session
rangingSession.start(preference)
}
}
private class RangingSessionCallback : RangingSession.Callback {
override fun onDlTdoaResults(peer: RangingDevice, measurement: DlTdoaMeasurement) {
// Process measurement results here
}
}
Java
public class RangingApp {
public void initDlTdoa(Context context) {
// Initialize the Ranging Manager
RangingManager rangingManager = context.getSystemService(RangingManager.class);
// Register for device capabilities
RangingManager.CapabilitiesCallback capabilitiesCallback = new RangingManager.RangingCapabilitiesCallback() {
@Override
public void onRangingCapabilities(RangingCapabilities capabilities) {
// Make sure Dl-TDoA is supported before starting the session
if (capabilities.getUwbCapabilities() != null && capabilities.getUwbCapabilities().isDlTdoaSupported()) {
startDlTDoASession(context);
}
}
};
rangingManager.registerCapabilitiesCallback(Executors.newSingleThreadExecutor(), capabilitiesCallback);
}
public void startDlTDoASession(Context context) {
RangingManager rangingManager = context.getSystemService(RangingManager.class);
// Create session and configure parameters
Executor executor = Executors.newSingleThreadExecutor();
RangingSession rangingSession = rangingManager.createRangingSession(executor, new RangingSessionCallback());
byte[] rangingRoundIndexes = new byte[] {0};
byte[] config = new byte[0]; // OOB config data
DlTdoaRangingParams params = DlTdoaRangingParams.createFromFiraConfigPacket(config, rangingRoundIndexes);
RangingDevice rangingDevice = new RangingDevice.Builder().build();
RawRangingDevice rawTagDevice = new RawRangingDevice.Builder()
.setRangingDevice(rangingDevice)
.setDlTdoaRangingParams(params)
.build();
RawDtTagRangingConfig dtTagConfig = new RawDtTagRangingConfig.Builder(rawTagDevice).build();
RangingPreference preference = new RangingPreference.Builder(DEVICE_ROLE_DT_TAG, dtTagConfig)
.setSessionConfig(new SessionConfig.Builder().build())
.build();
// Start the ranging session
rangingSession.start(preference);
}
private static class RangingSessionCallback implements RangingSession.Callback {
@Override
public void onDlTdoaResults(RangingDevice peer, DlTdoaMeasurement measurement) {
// Process measurement results here
}
}
}
การกำหนดค่า Out-of-Band (OOB)
ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างข้อมูลการกำหนดค่า DL-TDoA OOB สำหรับ Wi-Fi และ BLE
Java
// Wifi Configuration
byte[] wifiConfig = {
(byte) 0xDD, (byte) 0x2D, (byte) 0x5A, (byte) 0x18, (byte) 0xFF, // Header
(byte) 0x5F, (byte) 0x19, // FiRa Sub-Element
(byte) 0x02, (byte) 0x00, // Profile ID
(byte) 0x06, (byte) 0x02, (byte) 0x20, (byte) 0x08, // MAC Address
(byte) 0x14, (byte) 0x01, (byte) 0x0C, // Preamble Index
(byte) 0x27, (byte) 0x02, (byte) 0x08, (byte) 0x07, // Vendor ID
(byte) 0x28, (byte) 0x06, (byte) 0xCA, (byte) 0xC8, (byte) 0xA6, (byte) 0xF7, (byte) 0x6F, (byte) 0x08, // Static STS IV
(byte) 0x08, (byte) 0x02, (byte) 0x60, (byte) 0x09, // Slot Duration
(byte) 0x1B, (byte) 0x01, (byte) 0x0A, // Slots per RR
(byte) 0x09, (byte) 0x04, (byte) 0xE8, (byte) 0x03, (byte) 0x00, (byte) 0x00, // Duration
(byte) 0x9F, (byte) 0x04, (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01 // Session ID
};
// BLE Configuration
byte[] bleConfig = {
(byte) 0x2D, (byte) 0x16, (byte) 0xF4, (byte) 0xFF, // Header
(byte) 0x5F, (byte) 0x19, // FiRa Sub-Element
(byte) 0x02, (byte) 0x00, // Profile ID
(byte) 0x06, (byte) 0x02, (byte) 0x20, (byte) 0x08, // MAC Address
(byte) 0x14, (byte) 0x01, (byte) 0x0C, // Preamble Index
(byte) 0x27, (byte) 0x02, (byte) 0x08, (byte) 0x07, // Vendor ID
(byte) 0x28, (byte) 0x06, (byte) 0xCA, (byte) 0xC8, (byte) 0xA6, (byte) 0xF7, (byte) 0x6F, (byte) 0x08, // Static STS IV
(byte) 0x08, (byte) 0x02, (byte) 0x60, (byte) 0x09, // Slot Duration
(byte) 0x1B, (byte) 0x01, (byte) 0x0A, // Slots per RR
(byte) 0x09, (byte) 0x04, (byte) 0xE8, (byte) 0x03, (byte) 0x00, (byte) 0x00, // Duration
(byte) 0x9F, (byte) 0x04, (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01 // Session ID
};
หากใช้การกำหนดค่า OOB ไม่ได้เนื่องจากไม่มี หรือหากต้องการเปลี่ยนค่าเริ่มต้นที่ไม่ได้อยู่ในการกำหนดค่า OOB คุณสามารถสร้างพารามิเตอร์ด้วย DlTdoaRangingParams.Builder ดังที่แสดงในข้อมูลโค้ดต่อไปนี้ คุณใช้พารามิเตอร์เหล่านี้แทน DlTdoaRangingParams.createFromFiraConfigPacket() ได้
Kotlin
val dlTdoaParams = DlTdoaRangingParams.Builder(1)
.setComplexChannel(UwbComplexChannel.Builder()
.setChannel(9).setPreambleIndex(10).build())
.setDeviceAddress(deviceAddress)
.setSessionKeyInfo(byteArrayOf(0x01, 0x02, 0x03, 0x04))
.setRangingIntervalMillis(240)
.setSlotDuration(UwbRangingParams.DURATION_2_MS)
.setSlotsPerRangingRound(20)
.setRangingRoundIndexes(byteArrayOf(0x01, 0x05))
.build()
Java
DlTdoaRangingParams dlTdoaParams = new DlTdoaRangingParams.Builder(1)
.setComplexChannel(new UwbComplexChannel.Builder()
.setChannel(9).setPreambleIndex(10).build())
.setDeviceAddress(deviceAddress)
.setSessionKeyInfo(new byte[]{0x01, 0x02, 0x03, 0x04})
.setRangingIntervalMillis(240)
.setSlotDuration(UwbRangingParams.DURATION_2_MS)
.setSlotsPerRangingRound(20)
.setRangingRoundIndexes(new byte[]{0x01, 0x05})
.build();