user3583884
user3583884

Reputation: 103

Message from Wearable to Phone

I'm making an app to wear that simply send a message to the phone to show a Toast, and for now all is working, but i have a problem, it only sends messages when user interacts with the Wearable and I want that my app send a message automatically.

The problem is that if i call the method sendToast() in the onCreate method the Boolean variable nodeId inside the method sendToast() is null, but if I do click to the button once everithing is created it works perfectly.

I suspect that if I call sendToast directly the Thread is not finished and in that precisly moment i don't have the node, but I don't know how to solve it.

I also tryed some tricks like those, but all failed so far:

Call the method sendToast() inside the method setupWidgets().

Simulate the click creating an instance of the button and using the method .callOnClick() or performClick() but since i'm using WatchViewStub(to work with round and squear wearables) i can't acces to it, it give me NullPointerException

Call a timer before calling the method to delay the execution.

Nothing works so far, anyone can help me?

Thank you so much!!

Here is my code:

public class Main extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        initApi();
        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {

            @Override
            public void onLayoutInflated(WatchViewStub stub) {
                setupWidgets();
            }
        });
    }

    private void initApi() {
        client = getGoogleApiClient(this);
        retrieveDeviceNode();
    }

    private void setupWidgets() {
        clickButton = (Button) findViewById(R.id.btn_toast);
        clickButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sendToast();
            }
        });
    }

    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() {
                client.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
                NodeApi.GetConnectedNodesResult result =
                        Wearable.NodeApi.getConnectedNodes(client).await();
                List<Node> nodes = result.getNodes();
                if (nodes.size() > 0) {
                    nodeId = nodes.get(0).getId();
                }
                client.disconnect();
            }
        }).start();
    }

    private void sendToast() {
        if (nodeId != null) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    client.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
                    Wearable.MessageApi.sendMessage(client, nodeId, GET_CONTACTS, null);
                    client.disconnect();
                }
            }).start();
        }
    }
}

Upvotes: 0

Views: 113

Answers (1)

gruszczy
gruszczy

Reputation: 42188

If you want to send a message from onCreate, you actually want to do this (this is not a compiling example, but should give you an idea):

NodeApi.getConnectedNodes(client).setResultCallback(new ResultCallback<..>(List<Node> nodes) {
    String nodeId = nodes.get(0).getId();
    Wearable.MessageApi.sendMessage(client, nodeId, GET_CONTACTS, null);
}, TIMEOUT);

So, basically instead of waiting on separate thread, add a callback and when it returns, send the message. This way you should be able to immediately schedule a message directly from onCreate.

Upvotes: 1

Related Questions