본문 바로가기

wearable device

Google Mobile Service를 활용한 갤럭시 워치 Wear os 와 모바일 기기 간의 통신 방법

반응형

갤럭시 워치와 Wear os 간에 직접적으로 통신하는 방법에 대한 블로그 글이 많이 없어 글을 작성하려고 한다.

갤럭시 스마트폰과 갤럭시 워치로 구현을 하였다.

 

시작하기 전에 가장 주의할 점은 두 프로젝트의 이름이 동일해야 한다는 것이다.

 

모바일 기기와 워치 기기의 패키지 명이 아래의 예시와 같이 동일해야한다.

package com.example.wearcommunication;

 

먼저 웨어러블 기기와 wearos의 build.gradle 파일에 다음 종속성을 추가한다.

implementation 'com.google.android.gms:play-services-wearable:18.0.0'
implementation 'com.google.android.gms:play-services-base:18.0.0'

 

이후 워치의 AndroidManifest.xml 파일에 다음 내용을 추가한다.

<service
    android:name=".MessageService"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
        <data android:scheme="wear" android:host="*" android:pathPrefix="/start-app" />
    </intent-filter>
</service>

 

모바일 기기의 코드는 다음과 같다.

 

package com.example.wearcommunication;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;

import com.google.android.gms.wearable.MessageClient;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.Wearable;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private Button launchButton;
    private MessageClient messageClient;
    private String nodeId;

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

        launchButton = findViewById(R.id.launch_button);
        messageClient = Wearable.getMessageClient(this);

        // 노드 ID 가져오기
        getNodeId();

        launchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessageToWearable();
            }
        });
    }

    private void sendMessageToWearable() {
        if (nodeId != null) {
            // JSON 데이터 생성
            JSONObject jsonObject = new JSONObject();
            try {
                jsonObject.put("action", "launch_app");
            } catch (JSONException e) {
                e.printStackTrace();
                Log.e(TAG, "Failed to create JSON message", e);
                return;
            }

            String message = jsonObject.toString();
            // 메시지 전송
            messageClient.sendMessage(nodeId, "/start-app", message.getBytes())
                    .addOnSuccessListener(aVoid -> Log.d(TAG, "Message sent successfully"))
                    .addOnFailureListener(e -> Log.e(TAG, "Message failed to send", e));
        } else {
            Log.e(TAG, "Node ID is null. Message not sent.");
        }
    }

    private void getNodeId() {
        Wearable.getNodeClient(this).getConnectedNodes()
                .addOnCompleteListener(task -> {
                    if (task.isSuccessful() && task.getResult() != null && !task.getResult().isEmpty()) {
                        nodeId = task.getResult().get(0).getId();
                        Log.d(TAG, "Node ID: " + nodeId);
                    } else {
                        Log.e(TAG, "Failed to get Node ID");
                    }
                });
    }
}

워치만이 연결된 상태였기에, getNodeId에서 첫번째 기기의 id를 불러오고, 해당 노드의 아이디로 sendMessageToWearable() 함수에서 메시지를 전송한다.

 

워치에서는 MessageService.java 파일에 해당 코드를 사용하여, 모바일 기기로부터 메시지를 받기 코드이다.

package com.example.wearcommunication;

import android.content.Intent;
import android.util.Log;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.WearableListenerService;

import org.json.JSONException;
import org.json.JSONObject;

public class MessageService extends WearableListenerService {

    private static final String TAG = "MessageService";
    private static final String START_APP_PATH = "/start-app";

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "MessageService started");
    }

    @Override
    public void onMessageReceived(MessageEvent messageEvent) {
        Log.d(TAG, "onMessageReceived: " + messageEvent.getPath());
        Log.d(TAG, "Message content: " + new String(messageEvent.getData()));

        if (messageEvent.getPath().startsWith(START_APP_PATH)) {
            String message = new String(messageEvent.getData());
            Log.d(TAG, "Message received: " + message);

            try {
                JSONObject jsonObject = new JSONObject(message);
                String action = jsonObject.getString("action");

                if ("launch_app".equals(action)) {
                    Log.d(TAG, "Launching the target app...");
                    // 원하는 앱 실행
                    Intent intent = getPackageManager().getLaunchIntentForPackage("com.example.wearcommunication");
                    if (intent != null) {
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                        Log.d(TAG, "Target app launched successfully");
                    } else {
                        Log.e(TAG, "Target app not found");
                    }
                } else {
                    Log.d(TAG, "Unexpected action received");
                }
            } catch (JSONException e) {
                Log.e(TAG, "Failed to parse JSON message", e);
            }
        } else {
            Log.d(TAG, "Unexpected path received: " + messageEvent.getPath());
            super.onMessageReceived(messageEvent);
        }
    }
}

 

패키지 이름만 동일하게 한다면 크게 어렵지 않으나 패키지 이름을 다르게 해서 이틀 넘게 걸렸다.

이 글 읽으시는 분은 동일한 실수를 안하길 바라며..글 마무리!

반응형