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

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

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

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

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

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

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

راجِع تطبيق العيّنة التالي للاطّلاع على أمثلة على الاستخدام: DataLayer

إرسال رسالة

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

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

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

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