wearable device

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

탱탱구리뱅뱅 2024. 6. 30. 16:41
반응형

갤럭시 워치와 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);
        }
    }
}

 

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

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

반응형