웨어러블 - 모바일 디바이스 간 데이터 전송

cluelin·2021년 11월 26일
0

WearOS

목록 보기
2/3

모바일(수신측) - 웨어러블(발신측) 의 데이터 송수신을 해보자.

모바일은 여러개의 웨어러블과 연결될수 있기때문에 상대방의 nodeId를 알아내는 과정이필요하자.

먼저 모바일에 voice_transcription기능을 추가하기위해

모바일의 res/values/ 디렉터리에 wear.xml 파일을 만들어서 아래와 같이 선언.

<resources xmlns:tools="http://schemas.android.com/tools"
               tools:keep="@array/android_wear_capabilities">
        <string-array name="android_wear_capabilities">
            <item>voice_transcription</item>
        </string-array>
    </resources>

웨어러블에서 아래와 같은 코드를 통해

voice_transcription 기능이 있는 최선의 node를 검색

 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)
    }
  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
    }

구해진 nodeId를 가지고 메세지를 전송한다.

    const val VOICE_TRANSCRIPTION_MESSAGE_PATH = "/voice_transcription"
    ...
    private fun requestTranscription(voiceData: ByteArray) {
        transcriptionNodeId?.also { nodeId ->
            val sendTask: Task<*> = Wearable.getMessageClient(context).sendMessage(
                    nodeId,
                    VOICE_TRANSCRIPTION_MESSAGE_PATH,
                    voiceData
            ).apply {
                addOnSuccessListener { ... }
                addOnFailureListener { ... }
            }
        }
    }

여기까지로 웨어러블(발신) -> 모바일(수신)으로 데이터 전송이 실행된다.

이제 수신부를 구현해보자.

수신부를 구현하는방법은 두가지가있는데

  1. WearableListenerService 서비스를 구현

  2. DataClient.OnDataChangedListener 인터페이스를 구현

Service를 구현하는 방법은 시스템 리소스를 더 차지하지만 Service를 통해 앱을 실행시킬수있다.

Service를 통해 구현하기위해서는 Manifest에 다음과 같이 intent filter를 선언해 주어야합니다.

   <service android:name=".DataLayerListenerService">
      <intent-filter>
          <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
          <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
          <data android:scheme="wear" android:host="*"
                   android:path="/start-activity" />
      </intent-filter>
    </service>

다음 아래와 같이 service를 구현해주면됩니다.

    class DataLayerListenerService : WearableListenerService() {

        override fun onDataChanged(dataEvents: DataEventBuffer) {
            ...
        }
        
        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)
            }
        }
    }

참조
https://github.com/android/wear-os-samples/tree/main/DataLayer
https://developer.android.com/training/wearables/data-layer/events

0개의 댓글