เมื่อเรียกใช้ Data Layer API คุณจะได้รับสถานะของการเรียกใช้เมื่อการเรียกใช้เสร็จสมบูรณ์ นอกจากนี้ คุณยังฟังเหตุการณ์ข้อมูลที่เกิดจากการเปลี่ยนแปลงข้อมูลที่แอปของคุณทำได้ทุกที่ในเครือข่าย Wear OS by Google
ดูตัวอย่างการทำงานกับ Data Layer API อย่างมีประสิทธิภาพได้ที่แอป Android DataLayer Sample
รอสถานะของการเรียกใช้ Data Layer
การเรียกใช้ Data Layer API เช่น การเรียกใช้โดยใช้เมธอด putDataItem ของคลาส
DataClient บางครั้งจะแสดงผลออบเจ็กต์ Task<ResultType> ทันทีที่สร้างออบเจ็กต์ Task ระบบจะจัดคิวการดำเนินการในเบื้องหลัง
หากคุณไม่ดำเนินการใดๆ เพิ่มเติมหลังจากนี้ การดำเนินการจะเสร็จสมบูรณ์โดยไม่มีการแจ้งเตือนในที่สุด
อย่างไรก็ตาม โดยปกติแล้วคุณมักต้องการทำบางอย่างกับผลลัพธ์หลังจากที่การดำเนินการเสร็จสมบูรณ์ ดังนั้นออบเจ็กต์ Task จะช่วยให้คุณรอสถานะผลลัพธ์ได้ ไม่ว่าจะเป็นแบบอะซิงโครนัสหรือซิงโครนัส
การเรียกแบบอะซิงโครนัส
หากโค้ดทำงานในเทรด UI หลัก อย่าทำการเรียกที่บล็อกไปยัง
Data Layer API และใช้โครูทีนเพื่อเรียก putDataItem:
private suspend fun Context.sendDataAsync(count: Int) { try { val putDataReq: PutDataRequest = PutDataMapRequest.create("/count").run { dataMap.putInt("count_key", count) asPutDataRequest() } val dataItem = Wearable.getDataClient(this).putDataItem(putDataReq).await() handleDataItem(dataItem) } catch (e: Exception) { handleDataItemError(e) } finally { handleTaskComplete() } } private fun handleDataItem(dataItem: DataItem) { } private fun handleDataItemError(exception: Exception) { } private fun handleTaskComplete() { }
ดูความเป็นไปได้อื่นๆ ได้ที่ Task API ซึ่งรวมถึงการเชื่อมโยงการดำเนินการ ของงานต่างๆ
การโทรแบบซิงโครนัส
หากโค้ดทำงานในเธรดตัวแฮนเดิลแยกต่างหากในบริการเบื้องหลัง
เช่น ใน WearableListenerService ให้ใช้ runBlocking เพื่อทำการเรียกที่บล็อกไปยัง putDataItem
หมายเหตุ: อย่าเรียกใช้ฟังก์ชันนี้ในขณะที่อยู่ในเทรดหลัก
private fun Context.sendDataSync(count: Int) { // Create a data item with the path and data to be sent val putDataReq: PutDataRequest = PutDataMapRequest.create("/count").run { dataMap.putInt("count_key", count) asPutDataRequest() } // Create a task to send the data to the data layer val task: Task<DataItem> = Wearable.getDataClient(this).putDataItem(putDataReq) try { Tasks.await(task).apply { // Add your logic here } } catch (e: ExecutionException) { // TODO: Handle exception } catch (e: InterruptedException) { // TODO: Handle exception Thread.currentThread().interrupt() } }
รอรับเหตุการณ์ชั้นข้อมูล
เนื่องจากชั้นข้อมูลจะซิงค์และส่งข้อมูลในอุปกรณ์แบบพกพาและอุปกรณ์ที่สวมใส่ได้ คุณจึงมักจะต้องรอฟังเหตุการณ์สำคัญ เช่น การสร้างรายการข้อมูลและการรับข้อความ
หากต้องการรอรับเหตุการณ์ชั้นข้อมูล คุณมี 2 ตัวเลือก ดังนี้
- สร้างบริการที่ขยาย
WearableListenerService - สร้างกิจกรรมหรือคลาสที่ใช้
DataClient.OnDataChangedListenerอินเทอร์เฟซ
ทั้ง 2 ตัวเลือกนี้จะลบล้างวิธีการเรียกกลับของเหตุการณ์ข้อมูลสําหรับ เหตุการณ์ที่คุณสนใจจัดการ
หมายเหตุ: โปรดพิจารณาการใช้แบตเตอรี่ของแอปเมื่อเลือกการติดตั้งใช้งาน Listener
WearableListenerService จะลงทะเบียนในไฟล์ Manifest ของแอป
และสามารถเปิดแอปได้หากยังไม่ได้เรียกใช้ หากคุณต้องการฟังเหตุการณ์เฉพาะเมื่อแอปทำงานอยู่แล้ว ซึ่งมักเป็นกรณีของแอปพลิเคชันแบบอินเทอร์แอกทีฟ ให้ไม่ต้องใช้ WearableListenerService แต่ให้ลงทะเบียน Listener ที่ใช้งานจริงแทน เช่น ใช้วิธี addListener ของคลาส
DataClient ซึ่งจะช่วยลดภาระงานในระบบและลดการใช้แบตเตอรี่ได้
ใช้ WearableListenerService
โดยปกติแล้ว คุณจะสร้างอินสแตนซ์ของ WearableListenerService ในทั้งแอปที่ใช้กับอุปกรณ์สวมใส่และแอปที่ใช้กับอุปกรณ์ถือ อย่างไรก็ตาม หากไม่สนใจเหตุการณ์ข้อมูลในแอปใดแอปหนึ่ง คุณก็ไม่จำเป็นต้องติดตั้งใช้งานบริการในแอปนั้น
เช่น คุณอาจมีแอปแบบพกพาที่ตั้งค่าและรับออบเจ็กต์รายการข้อมูล และแอปบนอุปกรณ์ที่สวมใส่ได้ซึ่งรอรับการอัปเดตเหล่านี้เพื่ออัปเดต UI แอปบนอุปกรณ์ที่สวมใส่ได้ จะไม่เคยอัปเดตรายการข้อมูลใดๆ ดังนั้นแอปบนอุปกรณ์พกพาจึงไม่ฟัง เหตุการณ์ข้อมูลใดๆ จากแอปบนอุปกรณ์ที่สวมใส่ได้
เหตุการณ์บางอย่างที่คุณสามารถฟังได้โดยใช้ WearableListenerService มีดังนี้
onDataChanged(): เมื่อใดก็ตามที่มีการสร้าง ลบ หรือ เปลี่ยนแปลงออบเจ็กต์รายการข้อมูล ระบบจะทริกเกอร์การเรียกกลับนี้ในโหนดที่เชื่อมต่อทั้งหมดonMessageReceived(): ข้อความที่ส่งจากโหนดจะทริกเกอร์ การเรียกกลับนี้ในโหนดเป้าหมายonCapabilityChanged(): เมื่อความสามารถที่อินสแตนซ์ของแอปโฆษณาพร้อมใช้งานในเครือข่าย เหตุการณ์ดังกล่าวจะทริกเกอร์การเรียกกลับนี้ หากต้องการค้นหาโหนดที่อยู่ใกล้เคียง คุณสามารถค้นหาเมธอดisNearby()ของโหนดที่ระบุไว้ในการเรียกกลับ
นอกจากนี้ คุณยังฟังเหตุการณ์จาก ChannelClient.ChannelCallback ได้ด้วย เช่น onChannelOpened()
เหตุการณ์ก่อนหน้าทั้งหมดจะดำเนินการในเธรดเบื้องหลัง ไม่ใช่ในเธรดหลัก
หากต้องการสร้าง WearableListenerService ให้ทำตามขั้นตอนต่อไปนี้
- สร้างคลาสที่ขยาย
WearableListenerService - ฟังเหตุการณ์ที่คุณสนใจ เช่น
onDataChanged() - ประกาศตัวกรอง Intent ในไฟล์ Manifest ของ Android เพื่อแจ้งให้ระบบทราบเกี่ยวกับ
WearableListenerServiceการประกาศนี้ช่วยให้ระบบเชื่อมโยงบริการของคุณได้ตามต้องการ
ตัวอย่างต่อไปนี้แสดงวิธีใช้ WearableListenerService
class DataLayerListenerService : WearableListenerService() { override fun onDataChanged(dataEvents: DataEventBuffer) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "onDataChanged: $dataEvents") } // Loop through the events and send a message // to the node that created the data item. dataEvents .map { it.dataItem.uri } .forEach { uri -> // Get the node ID from the host value of the URI. val nodeId: String = uri.host!! // Set the data of the message to be the bytes of the URI. val payload: ByteArray = uri.toString().toByteArray() // Send the RPC. Wearable.getMessageClient(this) .sendMessage( nodeId, DATA_ITEM_RECEIVED_PATH, payload ) } } }
ส่วนต่อไปนี้จะอธิบายวิธีใช้ตัวกรอง Intent กับ Listener นี้
ใช้ตัวกรองกับ WearableListenerService
ตัวกรอง Intent สำหรับWearableListenerService ตัวอย่างที่แสดงในส่วนก่อนหน้า
อาจมีลักษณะดังนี้
<service android:name=".snippets.datalayer.DataLayerListenerService" android:exported="true" tools:ignore="ExportedService" > <intent-filter> <action android:name="com.google.android.gms.wearable.DATA_CHANGED" /> <data android:scheme="wear" android:host="*" android:path="/start-activity" /> </intent-filter> </service>
DATA_CHANGED ตัวกรองการดำเนินการจะบอกระบบว่าแอปของคุณสนใจเหตุการณ์ใน Data
Layer
ในตัวอย่างนี้ นาฬิกาจะรอรับ/start-activityรายการข้อมูล และโทรศัพท์จะรอรับข้อความ /data-item-received (DATA_ITEM_RECEIVED_PATH) ตอบกลับ
ระบบจะใช้กฎการจับคู่ตัวกรอง Android มาตรฐาน คุณระบุบริการหลายรายการ
ต่อไฟล์ Manifest, ตัวกรอง Intent หลายรายการต่อบริการ, การดำเนินการหลายรายการต่อตัวกรอง
และกลุ่มข้อมูลหลายรายการต่อตัวกรองได้ ตัวกรองสามารถจับคู่กับโฮสต์ไวลด์การ์ดหรือโฮสต์ที่เฉพาะเจาะจง หากต้องการจับคู่ในโฮสต์ไวลด์การ์ด ให้ใช้ host="*" หากต้องการจับคู่ในโฮสต์ที่เฉพาะเจาะจง ให้ระบุ host=<node_id>
นอกจากนี้ คุณยังจับคู่เส้นทางที่ตรงกันทุกประการหรือค่าต่อท้ายของเส้นทางได้ด้วย โดยคุณต้องระบุ สัญลักษณ์แทนหรือโฮสต์ที่เฉพาะเจาะจง มิฉะนั้น ระบบจะไม่สนใจเส้นทางที่คุณระบุ
ดูข้อมูลเพิ่มเติมเกี่ยวกับประเภทตัวกรองที่ Wear OS รองรับได้ที่เอกสารอ้างอิง API
สำหรับ WearableListenerService
ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวกรองข้อมูลและกฎการจับคู่ได้ในเอกสารอ้างอิง API
สำหรับองค์ประกอบ Manifest ของ <data>
เมื่อจับคู่ตัวกรอง Intent โปรดคำนึงถึงกฎสำคัญ 2 ข้อต่อไปนี้
- หากไม่ได้ระบุสคีมาสำหรับตัวกรอง Intent ระบบจะเพิกเฉยต่อแอตทริบิวต์ URI อื่นๆ ทั้งหมด
- หากไม่ได้ระบุโฮสต์สำหรับตัวกรอง ระบบจะไม่สนใจแอตทริบิวต์เส้นทางทั้งหมด
ใช้ผู้ฟังสด
หากแอปสนใจเฉพาะเหตุการณ์ชั้นข้อมูลเมื่อผู้ใช้โต้ตอบกับแอป คุณอาจไม่จำเป็นต้องมีบริการที่ทำงานเป็นเวลานานเพื่อจัดการการเปลี่ยนแปลงข้อมูลทุกครั้ง ใน กรณีดังกล่าว คุณสามารถรอฟังเหตุการณ์ในกิจกรรมได้โดยการใช้ อินเทอร์เฟซต่อไปนี้อย่างน้อย 1 รายการ
DataClient.OnDataChangedListenerMessageClient.OnMessageReceivedListenerCapabilityClient.OnCapabilityChangedListenerChannelClient.ChannelCallback
หากต้องการสร้างกิจกรรมที่รอรับเหตุการณ์ข้อมูล ให้ทำตามขั้นตอนต่อไปนี้
- ใช้ส่วนติดต่อที่จำเป็น
- ในเมธอด
onCreate()หรือonResume()ให้เรียกใช้Wearable.getDataClient(this).addListener(),MessageClient.addListener(),CapabilityClient.addListener()หรือChannelClient.registerChannelCallback()เพื่อแจ้งบริการ Google Play ว่ากิจกรรมของคุณสนใจเหตุการณ์ใน Data Layer - ใน
onStop()หรือonPause()ให้ยกเลิกการลงทะเบียน Listener ด้วยDataClient.removeListener(),MessageClient.removeListener(),CapabilityClient.removeListener()หรือChannelClient.unregisterChannelCallback() - หากกิจกรรมต้องการรับเฉพาะเหตุการณ์ที่มีคำนำหน้าเส้นทางที่เฉพาะเจาะจง ให้เพิ่ม Listener ที่มีตัวกรองคำนำหน้าเพื่อรับเฉพาะข้อมูล ที่เกี่ยวข้องกับสถานะแอปพลิเคชันปัจจุบัน
- ใช้
onDataChanged(),onMessageReceived(),onCapabilityChanged()หรือเมธอดจากChannelClient.ChannelCallbackขึ้นอยู่กับ อินเทอร์เฟซที่คุณใช้ โดยจะเรียกใช้เมธอดเหล่านี้ในเทรดหลัก หรือคุณจะระบุLooperที่กำหนดเองโดยใช้WearableOptionsก็ได้
ตัวอย่างการใช้งาน DataClient.OnDataChangedListener
class MainActivity : Activity(), DataClient.OnDataChangedListener { public override fun onResume() { super.onResume() Wearable.getDataClient(this).addListener(this) } override fun onPause() { super.onPause() Wearable.getDataClient(this).removeListener(this) } override fun onDataChanged(dataEvents: DataEventBuffer) { dataEvents.forEach { event -> if (event.type == DataEvent.TYPE_DELETED) { Log.d(TAG, "DataItem deleted: " + event.dataItem.uri) } else if (event.type == DataEvent.TYPE_CHANGED) { Log.d(TAG, "DataItem changed: " + event.dataItem.uri) } } } }
ข้อควรระวัง: ก่อนใช้ Wearable Data Layer API ให้ตรวจสอบว่า API พร้อมใช้งานในอุปกรณ์
หรือไม่ มิฉะนั้นจะเกิดข้อยกเว้น ใช้คลาส
GoogleApiAvailability ตามที่ใช้ใน Horologist
ใช้ตัวกรองกับผู้ฟังแบบเรียลไทม์
ดังที่กล่าวไว้ก่อนหน้านี้ คุณสามารถระบุตัวกรอง Intent สำหรับออบเจ็กต์ WearableListenerService ที่อิงตามไฟล์ Manifest ได้เช่นเดียวกับที่ใช้ตัวกรอง Intent เมื่อลงทะเบียน Listener แบบสดผ่าน Wearable API กฎเดียวกันนี้
มีผลกับทั้งผู้ฟังที่ใช้ API และผู้ฟังที่ใช้ไฟล์ Manifest
รูปแบบที่ใช้กันทั่วไปคือการลงทะเบียน Listener ด้วยเส้นทางหรือคำนำหน้าเส้นทางที่เฉพาะเจาะจง
ในเมธอด onResume() ของกิจกรรม แล้วนำ Listener ออกใน
เมธอด onPause() ของกิจกรรม การใช้ Listener ในลักษณะนี้
จะช่วยให้แอปรับเหตุการณ์ได้อย่างเลือกสรรมากขึ้น ซึ่งจะช่วยปรับปรุงการออกแบบและ
ประสิทธิภาพ