אתם שולחים הודעות באמצעות
MessageClient
API ומצרפים להודעה את הפריטים הבאים:
- מטען ייעודי (payload) שרירותי ואופציונלי
- נתיב שמזהה באופן ייחודי את הפעולה של ההודעה
בניגוד לפריטי נתונים, לא מתבצע סנכרון בין האפליקציות לנייד ולאפליקציות למכשירים לבישים. הודעות הן מנגנון תקשורת חד-כיווני ששימושי לקריאות לפרוצדורות מרוחקות (RPC), למשל שליחת הודעה למכשיר הלביש כדי להתחיל פעילות.
אפשר לחבר כמה מכשירים לבישים למכשיר נייד של משתמש. כל מכשיר שמחובר לרשת נחשב לצומת.
אם יש כמה מכשירים מחוברים, צריך להחליט אילו צמתים יקבלו את ההודעות. לדוגמה, באפליקציה לתמלול קולי שמקבלת נתונים קוליים במכשיר הלביש, שולחים את ההודעה לצומת עם כוח העיבוד וקיבולת הסוללה שנדרשים לטיפול בבקשה, כמו מכשיר נייד.
הערה: כשמציינים את פרטי ההודעה, צריך לקחת בחשבון את האפשרות של כמה צמתים מחוברים. מוודאים שההודעה נשלחת למכשירים או לצמתים הרצויים.
דוגמאות לשימוש באפליקציה: DataLayer
שליחת הודעה
אפליקציה למכשיר לביש יכולה לספק למשתמשים פונקציונליות כמו תמלול קולי. המשתמשים יכולים לדבר למיקרופון של המכשיר הלביש והתמליל יישמר בהערה. בדרך כלל למכשיר לביש אין את כוח העיבוד ואת קיבולת הסוללה שנדרשים כדי לבצע תמלול קולי, ולכן האפליקציה צריכה להעביר את העבודה הזו למכשיר מחובר עם יכולות טובות יותר.
בקטעים הבאים מוסבר איך לפרסם צמתים של מכשירים שיכולים לעבד בקשות לפעילות, לגלות את הצמתים שיכולים לספק צורך מבוקש ולשלוח הודעות לצמתים האלה.
פרסום יכולות
כדי להפעיל פעילות במכשיר נייד ממכשיר לביש, משתמשים במחלקה
MessageClient
כדי לשלוח את הבקשה. יכולים להיות כמה מכשירים לבישים שמחוברים למכשיר הנייד, ולכן אפליקציית המכשיר הלביש צריכה לקבוע אם צומת מחובר יכול להפעיל את הפעילות. באפליקציה לנייד, מפרסמים שהצומת שהיא פועלת בו מספק יכולות ספציפיות.
כדי לפרסם את היכולות של האפליקציה למכשירים ניידים:
- יוצרים קובץ הגדרות XML בספרייה
res/values/
של הפרויקט ונותנים לו את השםwear.xml
. - מוסיפים משאב בשם
android_wear_capabilities
ל-wear.xml
. - הגדרת היכולות שהמכשיר מספק.
הערה: יכולות הן מחרוזות מותאמות אישית שאתם מגדירים, והן צריכות להיות ייחודיות באפליקציה.
בדוגמה הבאה מוצג איך מוסיפים יכולת בשם voice_transcription
ל-wear.xml
:
<resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@array/android_wear_capa<bilities"> string-array name="android_<wear_capabilities"&<gt; < item>voice_<transcription/item> /string-array> /resources>
אחזור צמתים עם היכולות הנדרשות
בתחילה, אפשר לזהות את הצמתים המתאימים באמצעות קריאה לשיטה getCapability
של המחלקה
CapabilityClient
. כדי להשתמש בשיטה הזו, מזהה האפליקציה של אפליקציית Wear OS ומזהה האפליקציה של אפליקציית הטלפון צריכים להיות זהים. בדוגמה הבאה מוצג אופן האחזור הידני של תוצאות של צמתים שאפשר להגיע אליהם באמצעות היכולת voice_transcription
:
Kotlin
private const val VOICE_TRANSCRIPTION_CAPABILITY_NAME = "voice_transcription" ... private fun setupVoiceTranscription() { val capabilityInfo: CapabilityInfo = Tasks.await( Wearable.getCapabilityClient(context) .getCapability( VOICE_TRANSCRIPTION_CAPABILITY_NAME, CapabilityClient.FILTER_REACHABLE ) ) // capabilityInfo has the reachable nodes with the transcription capability updateTranscriptionCapability(capabilityInfo) }
Java
private static final String VOICE_TRANSCRIPTION_CAPABILITY_NAME = "voice_transcription"; ... private void setupVoiceTranscription() { CapabilityInfo capabilityInfo = Tasks.await( Wearable.getCapabilityClient(context).getCapability( VOICE_TRANSCRIPTION_CAPABILITY_NAME, CapabilityClient.FILTER_REACHABLE)); // capabilityInfo has the reachable nodes with the transcription capability updateTranscriptionCapability(capabilityInfo); }
זהירות:
לפני שמשתמשים ב-Wearable Data Layer API, צריך לבדוק שהוא זמין במכשיר. אחרת, תתרחש חריגה. משתמשים במחלקה GoogleApiAvailability
כפי שהיא מיושמת ב-Horologist.
כדי לזהות צמתים מתאימים כשהם מתחברים למכשיר הלביש, צריך לרשום מופע של מאזין, במיוחד OnCapabilityChangedListener
של אובייקט CapabilityClient
. בדוגמה הבאה אפשר לראות איך רושמים את ה-listener ומאחזרים תוצאה עם צמתים שאפשר להגיע אליהם עם היכולת voice_transcription
:
Kotlin
private fun setupVoiceTranscription() { updateTranscriptionCapability(capabilityInfo).also { capabilityListener -> Wearable.getCapabilityClient(context).addListener( capabilityListener, VOICE_TRANSCRIPTION_CAPABILITY_NAME ) } }
Java
private void setupVoiceTranscription() { ... // This example uses a Java 8 Lambda. You can use named or anonymous classes. CapabilityClient.OnCapabilityChangedListener capabilityListener = capabilityInfo -> { updateTranscriptionCapability(capabilityInfo); }; Wearable.getCapabilityClient(context).addListener( capabilityListener, VOICE_TRANSCRIPTION_CAPABILITY_NAME); }
אחרי זיהוי הצמתים המתאימים, המערכת קובעת לאן לשלוח את ההודעה. בוחרים צומת שנמצא בקרבה למכשיר הלביש כדי לצמצם את ניתוב ההודעות דרך כמה צמתים. צומת בקרבת מקום מוגדר כצומת שמחובר ישירות למכשיר. כדי לקבוע אם צומת נמצא בקרבת מקום, למשל אם הוא מחובר באמצעות Bluetooth, צריך להפעיל את השיטה
Node.isNearby()
. אם יש יותר מצומת אחת בקרבת מקום, בוחרים אחת באופן שרירותי. באופן דומה, אם אין צומת מתאימה בקרבת מקום, בוחרים צומת מתאימה באופן שרירותי.
בדוגמה הבאה אפשר לראות איך אפשר לקבוע את הצומת הכי טוב לשימוש:
Kotlin
private var transcriptionNodeId: String? = null private fun updateTranscriptionCapability(capabilityInfo: CapabilityInfo) { transcriptionNodeId = pickBestNodeId(capabilityInfo.nodes) } private fun pickBestNodeId(nodes: Set<Node>): String? { // Find a nearby node or pick one arbitrarily. return nodes.firstOrNull { it.isNearby }?.id ?: nodes.firstOrNull()?.id }
Java
private String transcriptionNodeId = null; private void updateTranscriptionCapability(CapabilityInfo capabilityInfo) { Set<Node> connectedNodes = capabilityInfo.getNodes(); transcriptionNodeId = pickBestNodeId(connectedNodes); } private String pickBestNodeId(Set<Node> nodes) { String bestNodeId = null; // Find a nearby node or pick one arbitrarily. for (Node node : nodes) { if (node.isNearby()) { return node.getId(); } bestNodeId = node.getId(); } return bestNodeId; }
שליחת ההודעה
אחרי שמזהים את הצומת שרוצים להשתמש בו, שולחים את ההודעה באמצעות המחלקה
MessageClient
.
בדוגמה הבאה מוצג איך לשלוח הודעה לצומת עם יכולת תמלול ממכשיר לביש. השיחה הזו היא סינכרונית והיא חוסמת את העיבוד עד שהמערכת מכניסה את ההודעה לתור למסירה.
הערה: קוד תוצאה של הצלחה לא מבטיח את מסירת ההודעה. אם האפליקציה שלכם דורשת מהימנות נתונים, כדאי להשתמש באובייקטים של
DataItem
או במחלקה ChannelClient
כדי לשלוח נתונים בין מכשירים.
Kotlin
const val VOICE_TRANSCRIPTION_MESSAGE_PATH = "/voice_transcription" ... private fun requestTranscription(voiceData: ByteArray) { transcriptionNodeId?.also >{ nodeId - val send<T>ask: Task* = Wearable.getMessageClient(context).sendMessage( nodeId, VOICE_TRANSCRIPTION_MESSAGE_PATH, voiceData ).apply { addOnSuccessListener { ... } addOnFailureListener { ... } } } }
Java
public static final String VOICE_TRANSCRIPTION_MESSAGE_PATH = "/voice_transcription"; private void requestTranscription(byte[] voiceData) { if (transcriptionNodeId != null) { < T>askInteger sendTask = Wearable.getMessageClient(context).sendMessage( transcriptionNodeId, VOICE_TRANSCRIPTION_MESSAGE_PATH, voiceData); // You can add success and/or failure listeners, // Or you can call Tasks.await() and catch ExecutionException sendTask.addOnSuccessListener(...); sendTask.addOnFailureListener(...); } else { // Unable to retrieve node with transcription capability } }
הערה: מידע נוסף על קריאות אסינכרוניות וסינכרוניות ל-Google Play Services, ומתי כדאי להשתמש בכל אחת מהן, זמין במאמר בנושא Tasks API.
אפשר גם לשדר הודעות לכל הצמתים המחוברים. כדי לאחזר את כל הצמתים המחוברים שאפשר לשלוח אליהם הודעות, מטמיעים את הקוד הבא:
Kotlin
private fun getNodes(): Collection<String> { return Tasks.await(Wearable.getNodeClient(context).connectedNodes).map { it.id } }
Java
private Collection<String> getNodes() { HashSet <String>results = new HashSet<String>(); List<Node> nodes = Tasks.await(Wearable.getNodeClient(context).getConnectedNodes()); for (Node node : nodes.getNodes()) { results.add(node.getId()); } return results; }
קבלת הודעה
כדי לקבל התראות על הודעות שהתקבלו, צריך להטמיע את הממשק
MessageClient.OnMessageReceivedListener
כדי לספק listener לאירועי הודעות. לאחר מכן, רושמים את ה-listener באמצעות השיטה addListener
. בדוגמה הבאה אפשר לראות איך מטמיעים את ה-listener כדי לבדוק את VOICE_TRANSCRIPTION_MESSAGE_PATH
. אם התנאי הזה הוא
true
, מתחילים פעילות לעיבוד נתוני הקול.
Kotlin
fun onMessageReceived(messageEvent: MessageEvent) { if (messageEvent.path == VOICE_TRANSCRIPTION_MESSAGE_PATH) { val startIntent = Intent(this, MainActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) putExtra("VOICE_DATA", messageEvent.data) } startActivity(this, startIntent) } }
Java
@Override public void onMessageReceived(MessageEvent messageEvent) { if (messageEvent.getPath().equals(VOICE_TRANSCRIPTION_MESSAGE_PATH)) { Intent startIntent = new Intent(this, MainActivity.class); startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startIntent.putExtra("VOICE_DATA", messageEvent.getData()); startActivity(this, startIntent); } }
הקוד הזה דורש פרטים נוספים להטמעה. במאמר הקשבה כדי לקלוט אירועים משכבת הנתונים מוסבר איך להטמיע שירות או פעילות מלאים של event listener.