简体   繁体   English

从可穿戴设备发送消息到手机,然后立即回复

[英]Send message from wearable to phone and then immediately reply

I've been battling with the Android Wear Message API all day today and have finally accepted I need some help with this. 我今天一整天都在与Android Wear Message API作斗争,并且终于接受了我需要一些帮助。

My app is very straightforward. 我的应用程序非常简单。 The Mobile portion consists of a MainActivity (which does nothing but display "Hello world" and a Service which extends WearableListenerService . The Wear portion is just a MainActivity with a single Button, and implements MessageApi.MessageListener . Mobile部分包含一个MainActivity(除了显示“Hello world”和一个扩展WearableListenerService的Service。)Wear部分只是一个带有单个Button的MainActivity,并实现了MessageApi.MessageListener

The idea is simple: press the Button on the Wear device which sends a message to the Mobile. 这个想法很简单:按下Wear设备上的按钮,该按钮向Mobile发送消息。 When the Mobile receives the message, it displays a Toast with the sender's message path (eg /mobile ). 当移动设备收到消息时,它会显示带有发件人消息路径的Toast(例如/ mobile )。 Immediately after doing this, the Mobile should send a message back to the Wear device using my reply() method. 执行此操作后,Mobile应立即使用我的reply()方法将消息发送 Wear设备。 All I want to do then is Log this message. 我想做的就是记录这条消息。

I can achieve the first part perfectly fine. 我可以完美地完成第一部分。 When the Button is pressed, the Mobile pops up a Toast saying "/mobile". 当按下按钮时,手机会弹出一个叫“/ mobile”的Toast。 The reply, however, seems to just get lost in the aether; 然而,答案似乎只是在以太中迷失了; no errors, but no message either. 没有错误,但也没有消息。

Can someone please help me understand what I'm doing wrong? 有人可以帮我理解我做错了什么吗? I have pasted my files below. 我在下面粘贴了我的文件。

This is the tutorial I am following. 是我关注的教程。 Cheers! 干杯!

Wear: MainActivity.java 穿:MainActivity.java

package org.thecosmicfrog.toastdroidmessageapitutorial;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.wearable.view.WatchViewStub;
import android.util.Log;
import android.view.View;

import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.MessageApi;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;

import java.util.List;
import java.util.concurrent.TimeUnit;

public class MainActivity extends Activity implements MessageApi.MessageListener {

    private final String LOG_TAG = MainActivity.class.getSimpleName();

    private static final long CONNECTION_TIME_OUT_MS = 100;
    private static final String MOBILE_PATH = "/mobile";

    private GoogleApiClient googleApiClient;
    private String nodeId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initGoogleApiClient();

        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override
            public void onLayoutInflated(WatchViewStub stub) {
                initWidgets();
            }
        });
    }

    private void initGoogleApiClient() {
        googleApiClient = getGoogleApiClient(this);
        retrieveDeviceNode();
    }

    private GoogleApiClient getGoogleApiClient(Context context) {
        return new GoogleApiClient.Builder(context)
                .addApi(Wearable.API)
                .build();
    }

    private void retrieveDeviceNode() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (googleApiClient != null && !(googleApiClient.isConnected() || googleApiClient.isConnecting()))
                    googleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);

                NodeApi.GetConnectedNodesResult result =
                        Wearable.NodeApi.getConnectedNodes(googleApiClient).await();

                List<Node> nodes = result.getNodes();

                if (nodes.size() > 0)
                    nodeId = nodes.get(0).getId();

                Log.v(LOG_TAG, "Node ID of phone: " + nodeId);

                googleApiClient.disconnect();
            }
        }).start();
    }

    private void initWidgets() {
        findViewById(R.id.button_toast).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendToast();
            }
        });
    }

    private void sendToast() {
        if (nodeId != null) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    if (googleApiClient != null && !(googleApiClient.isConnected() || googleApiClient.isConnecting()))
                        googleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);

                    Wearable.MessageApi.sendMessage(googleApiClient, nodeId, MOBILE_PATH, null).await();
                    googleApiClient.disconnect();
                }
            }).start();
        }
    }

    @Override
    public void onMessageReceived(MessageEvent messageEvent) {
        Log.v(LOG_TAG, "In onMessageReceived()");

        if (messageEvent.getPath().equals("/wear")) {
            Log.v(LOG_TAG, "Success!");
        }
    }
}

Mobile: ListenerService.java Mobile:ListenerService.java

package org.thecosmicfrog.toastdroidmessageapitutorial;

import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;

import java.util.concurrent.TimeUnit;

public class ListenerService extends WearableListenerService {

    private final String LOG_TAG = ListenerService.class.getSimpleName();

    private static GoogleApiClient googleApiClient;

    private static final long CONNECTION_TIME_OUT_MS = 100;
    private static final String WEAR_PATH = "/wear";
    private String nodeId;

    @Override
    public void onMessageReceived(MessageEvent messageEvent) {
        if (messageEvent.getPath().equals("/mobile")) {
            nodeId = messageEvent.getSourceNodeId();
            Log.v(LOG_TAG, "Node ID of watch: " + nodeId);
            showToast(messageEvent.getPath());

            reply(WEAR_PATH);
        }
    }

    private void showToast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }

    private void reply(final String path) {
        googleApiClient = new GoogleApiClient.Builder(getApplicationContext())
                .addApi(Wearable.API)
                .build();

        Log.v(LOG_TAG, "In reply()");
        Log.v(LOG_TAG, "Path: " + path);

        if (googleApiClient != null && !(googleApiClient.isConnected() || googleApiClient.isConnecting()))
            googleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);

        Wearable.MessageApi.sendMessage(googleApiClient, nodeId, path, null).await();
        googleApiClient.disconnect();
    }
}

The Mobile MainActivity is pretty trivial so I've left it out for clarity. Mobile MainActivity非常简单,所以为了清晰起见,我把它留了下来。

You never call MessageApi.addListener() in your Wear activity so your MessageListener is never registered to receive messages. 您永远不会在Wear活动中调用MessageApi.addListener() ,因此永远不会注册MessageListener来接收消息。 You should also call MessageApi.removeListener() when your activity is being destroyed. 您的活动被销毁时也应该调用MessageApi.removeListener()

Note: both methods require a connected GoogleApiClient . 注意:这两种方法都需要连接的GoogleApiClient It may make logic easier if you leave a GoogleApiClient open throughout the duration of your activity rather than try connecting/ removeListener() /disconnect in your onDestroy() . 如果您在整个活动期间打开GoogleApiClient而不是在onDestroy()尝试连接/ removeListener() / disconnect,则可能会使逻辑更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM