오늘은 저번에 알아본 data layer에서 message 을 구현해 보도록 하겠습니다.
일단 전 google 에서 제공한 가이드 문서 토대로 라이브러리를 다운 받았습니다.
//wear
implementation 'com.google.android.gms:play-services-wearable:18.0.0'
//Gson
implementation 'com.google.code.gson:gson:2.10.1'
//await()`
implementation 'com.google.guava:guava:32.0.1-jre'
implementation "androidx.concurrent:concurrent-futures-ktx:1.1.0"
위에서 부터 보면
자 그럼 한번 봅시다.
File -> New -> New Moudle 을 선택해 wear Project을 만들어 줍니다.
그후 wear 에서 activity_main 와 MainActivity을 만들어주고 Mainfest에 선언을 해줍니다.
블로그를 쓰기전 제가 코드를 구현 하면서 Data layer message가 작동을 안해
잠시 삽질한 적이 있습니다.
그 이유가 Build gradle 에 applicationId 가 문제 였습니다.
defaultConfig {
applicationId "com.example.wearproject_mobile" -> 요거 때문
minSdk 30
targetSdk 33
versionCode 1
versionName "1.0.0_mobile"
wearAppUnbundled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
여러분이 제 글을 따라오면서 wear 에도 이름을 정해줬을텐데요
그때 wear 의 applicationId 을 확인해 주시길 바랍니다.
wear도 applicationId 가 똑같아야 data layer 가 작동됩니다.
자 그럼 계속 준비를 해보겠습니다.
난 실물로 돌릴건데 라고 하시는 분들
안드로이드 스튜디오 우측 상단에 보면 app 밖에 없어서 당활 하실 겁니다.
그럼 당황하지 마시고 app 을 누르시면 edit configuration 을 누르면
이런 창이 보이실 겁니다
그럼 우측 상단에 + 을 눌러 추가를 눌러주시고 이름은 마음대로 하시고 Module은 wear Project을 추가해주시면 되겠습니다.
여기서 한번 정의 하고 가겠습니다.
입니다.
그럼 wear 에 함수를 구현해 보겠습니다.
val messageClient by lazy { Wearable.getMessageClient(this) }
val capabilityClient by lazy { Wearable.getCapabilityClient(this) }
private fun sendMessage(){
val data = TestObject("MessageFromWear")
val gson = Gson()
val dataJson = gson.toJson(data)
val sendData = dataJson.toByteArray(Charsets.UTF_8)
CoroutineScope(Dispatchers.Default).launch {
try{
val nodes = capabilityClient.getCapability(Define.MOBILE_CAPABILITY , CapabilityClient.FILTER_REACHABLE).await().nodes
if(nodes.size == 0){
Log.d("tag" , "The node Size is 0")
}
nodes.map {node ->
async {
Log.d("tag", "data send $data")
messageClient.sendMessage(node.id ,Define.MESSAGE_URL , sendData )
}
}.awaitAll()
}catch (e : Exception){
Log.d("tag" , "Error to send Data_wear")
}
}
}
위에서 부터 messageclient 란 data layer 의 message을 보내는주는 라이브러리 입니다.
capabilityClient 은 wear에 연결된 node 갯수를 return 해줍니다.
val data = TestObject("MessageFromWear")
val gson = Gson()
val dataJson = gson.toJson(data)
val sendData = dataJson.toByteArray(Charsets.UTF_8)
해당 코드는 data는 string object 로 만들어 주고 그것을 json으로 만들어 bytearray로 만들어줍니다.
CoroutineScope(Dispatchers.Default).launch {
try{
val nodes = capabilityClient.getCapability(Define.MOBILE_CAPABILITY(이게 mobile) , CapabilityClient.FILTER_REACHABLE).await().nodes
if(nodes.size == 0){
Log.d("tag" , "The node Size is 0")
}
nodes.map {node ->
async {
Log.d("tag", "data send $data")
messageClient.sendMessage(node.id ,Define.MESSAGE_URL , sendData )
}
}.awaitAll()
}catch (e : Exception){
Log.d("tag" , "Error to send Data_wear")
}
}
그후 비동기로 보내기 위해 코루틴을 선언하며 nodes 갯수를 체크 했습니다.
node 사이즈를 봐서 0일시 연결된 핸드폰이 없다고 판단합니다.
아닐시 node을 통해 messageClient을 사용해 연결된 모바일에 메세지를 보내줍니다.
mobile 에 res / values 에 wear.xml 을 선언해 줍니다.
<resources xmlns:tools="http://schemas.android.com/tools">
<string-array name="android_wear_capabilities" translatable="false">
<!-- declaring the provided capabilities -->
<item>mobile</item> -> 요건 상관 없음
</string-array>
</resources>
mobile을 다른것으로 바꿔도 상관 없습니다. 위에 칸으로 보면
val nodes = capabilityClient.getCapability(Define.MOBILE_CAPABILITY , CapabilityClient.FILTER_REACHABLE).await().nodes
Define.MOBILE_CAPABILITY -> mobile 입니다.
다른것으로 바꿔도 상관 없습니다
define은 제가 만든 함수 이니까요 static
자 그럼 dataLayerLstener을 구현 해 보겠습니다.
class DataLayerListenerService : WearableListenerService() , DataClient.OnDataChangedListener {
override fun onMessageReceived(messageEvent: MessageEvent) {
Timber.d("The Message is come from Wear")
}
}
저희는 메세지만 받기 때문에 override onMessageReceived 만 가졌습니다.
Mobile 에 Menifest 쪽으로 가보겠습니다.
<service android:name=".DataLayerListenerService"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data
android:host="*"
android:pathPrefix="/message"
android:scheme="wear" />
</intent-filter>
</service>
android:scheme="wear" 은 지켜주시고
android:pathPrefix="/message" 은 마음대로 하셔도 상관 없습니다.
messageClient.sendMessage(node.id ,Define.MESSAGE_URL , sendData )
wear 쪽에 messageClient 코드 입니다.
그럼 오늘도 읽어주셔사 감사합니다
-피드백와 비판은 언제나 환영입니다-