إرسال الرسائل واستلامها على Wear

ترسل الرسائل باستخدام واجهة برمجة التطبيقات MessageClient وإرفاق العناصر التالية بالرسالة:

  • حمولة بيانات عشوائية اختيارية
  • مسار يعرّف إجراء الرسالة بشكل فريد

على عكس عناصر البيانات، لا تحدث أي مزامنة بين التطبيقات المحمولة باليد والتطبيقات القابلة للارتداء. الرسائل هي آلية تواصل أحادية الاتجاه مفيدة لاستدعاءات الإجراءات عن بُعد (RPC)، مثل إرسال رسالة إلى الجهاز القابل للارتداء لبدء نشاط.

يمكن توصيل عدة أجهزة قابلة للارتداء بجهاز المستخدم المحمول. يُعد كل جهاز متصل في الشبكة عقدة.

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

ملاحظة: عند تحديد تفاصيل رسالتك، يجب مراعاة إمكانية وجود عدة عُقد مرتبطة. تأكَّد من تسليم الرسالة إلى الأجهزة أو العُقد المقصودة.

راجع نماذج التطبيقات التالية للحصول على أمثلة على الاستخدام:

إرسال رسالة

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

توضّح لك الأقسام التالية كيفية الإعلان عن عُقد الجهاز التي يمكنها معالجة طلبات الأنشطة، واكتشاف العُقد القادرة على تلبية الحاجة المطلوبة، وإرسال رسائل إلى تلك العُقد.

لبدء نشاط على جهاز محمول من جهاز قابل للارتداء، استخدِم الصف MessageClient لإرسال الطلب. ونظرًا لأنه يمكن توصيل العديد من الأجهزة القابلة للارتداء بالجهاز المحمول باليد، يحتاج التطبيق القابل للارتداء إلى تحديد أن العقدة المتصلة قادرة على بدء النشاط. في التطبيق المحمول باليد، أعلن عن أن العُقدة التي تعمل عليها توفر إمكانات معينة.

للإعلان عن إمكانات تطبيقك المحمول، قم بما يلي:

  1. أنشِئ ملف إعداد XML في دليل res/values/ لمشروعك وحدِّد اسمه wear.xml.
  2. أضِف موردًا باسم android_wear_capabilities إلى wear.xml.
  3. حدِّد الإمكانات التي يوفّرها الجهاز.

ملاحظة: الإمكانات هي سلاسل مخصّصة تحدّدها ويجب أن تكون فريدة داخل تطبيقك.

يوضّح المثال التالي كيفية إضافة ميزة باسم voice_transcription إلى wear.xml:

<resources xmlns:tools="http://schemas.android.com/tools"
           tools:keep="@array/android_wear_capabilities">
    <string-array name="android_wear_capabilities">
        <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);
}

لرصد العُقد القابلة للارتداء عند اتصالها بالجهاز القابل للارتداء، سجِّل مثيل جهاز استماع، خاصةً OnCapabilityChangedListener لكائن CapabilityClient. يوضّح المثال التالي كيفية تسجيل المستمع واسترداد نتيجة تتضمّن عقدًا يمكن الوصول إليها وتحتوي على ميزة 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);
}

بعد اكتشاف العُقد المؤهَّلة، حدِّد مكان إرسال الرسالة. اختَر عقدة قريبة من جهازك القابل للارتداء لتقليل توجيه الرسائل عبر عدة عُقد. وتُعرّف العقدة المجاورة بأنّها عقدة متصلة مباشرةً بالجهاز. لتحديد ما إذا كانت إحدى العُقد قريبة أم لا مثل الاتصال عبر البلوتوث، عليك استدعاء طريقة 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 sendTask: 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) {
        Task<Integer> 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، وحالات استخدام كل منها، يُرجى الاطّلاع على 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 لتوفير المستمع لأحداث الرسائل. بعد ذلك، سجِّل المستمع باستخدام الطريقة addListener. يوضّح المثال التالي كيفية استخدام أداة المستمع للتحقّق من 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);
    }
}

يتطلّب هذا الرمز مزيدًا من تفاصيل التنفيذ. تعرَّف على كيفية تنفيذ نشاط أو خدمة استماع كاملة في قسم الاستماع إلى أحداث طبقة البيانات.