Android Wearable Data Layer

안드로이드 앱이 Wear기기를 지원하기 위해서는 두가지방식이 있다. 첫번째는 Notification을 이용해서 메세지를 보여주거나 간단한 액션으로 명령을 내려 처리하는 방법. 두번째는 Wear기기에 직접 앱을 올려 동작시키는 방법이 있다. 두번째 방법은 전혀다른 두개의 기기에 동시에 데이터를 동기화를 해야하는데, Google Play Service 5.0에 포함된 Wearable Message API를 사용하면된다.

Wearable Message API로 한쪽에서 메세지를 전송하고 다른 한쪽에서는 WearableListenerSevice를 통해 메시지를 수신하면 된다. 실제로 블루투스를 통해서 메시지를 주고 받는것은 Google Play Service에서 담달하기 때문에  우리는 단순히 API를 통해서 snedMessage, onMessageReceived로 메시지를 송/수신할 수 있다.

그럼 간단한 예제를 통해 메세지를 주고받은 예제를 구현해보자.

Android Studio에서 간단하게 Phone용과 Wear용으로 하나의 프로젝트로 만들수 있다. (프로젝트 생성 부분은 생략.)

Phone에서 메세지 전송

GoogleApiClient 초기화

public class Handheld extends Activity implements
  GoogleApiClient.ConnectionCallbacks,
  GoogleApiClient.OnConnectionFailedListener {

  GoogleApiClient googleClient;

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

  // Build a new GoogleApiClient
  googleClient = new GoogleApiClient.Builder(this)
    .addApi(Wearable.API)
    .addConnectionCallbacks(this)
    .addOnConnectionFailedListener(this)
    .build();
  }
      // Data layer and lifecycle implementation (Step 2)
      ...
}

콜백 메소드 추가및 라이프 사이클에 따른 연결 설정

// Connect to the data layer when the Activity starts
@Override
protected void onStart() {
      super.onStart();
  googleClient.connect();
}

// Send a message when the data layer connection is successful.
@Override
public void onConnected(Bundle connectionHint) {
      sendDataLayerMessage();
}

// Disconnect from the data layer when the Activity stops
@Override
protected void onStop() {
  if (null != googleClient && googleClient.isConnected()) {
    googleClient.disconnect();
    }
    super.onStop();
}

메시지 전송

private void sendDataLayerMessage() {
  new Thread(new Runnable() {
    @Override
    public void run() {
      // Get the connected nodes and wait for results
      NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleClient).await();
      for (Node node : nodes.getNodes()) {
        // Send a message and wait for result
        SendMessageResult result =
          Wearable.MessageApi.sendMessage(googleClient, node.getId(),
          MESSAGE_RECEIVED_PATH, MESSAGE.getBytes()).await();
          if (result.getStatus().isSuccess()) {
            Log.v("myTag", "Message sent to : " + node.getDisplayName());
          }
          else {
            // Log an error
            Log.v("myTag", "MESSAGE ERROR: failed to send Message");
          }
       }
    }
  }).start();
}

Wear에서 메시지 수신

메시지 수신은 WearableListenerService를 통해 수신을 받을 수 있다. Service를 통해 받은 메시지를 Activity화면에 보여 주기 위해서 Broadcast로 처리한다.

WearableListenerService와 Wear기기를 사용하기위해 다음과 같이 Android Manifest에 추가한다.

<uses-feature android:name="android.hardware.type.watch" />

<application
  ...
  <service android:name=".ListenerService">
    <intent-filter>
      <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
    </intent-filter>
  </service>
</application>

WearableListenerService 구현

public class ListenerService extends WearableListenerService {

  @Override
  public void onMessageReceived(MessageEvent messageEvent) {

    if (messageEvent.getPath().equals(MESSAGE_RECEIVED_PATH)) {
      final String message = new String(messageEvent.getData());
      Log.v("myTag", "Message path received on watch is: " + messageEvent.getPath());
      Log.v("myTag", "Message received on watch is: " + message);

      // Broadcast message to wearable activity for display
      Intent messageIntent = new Intent();
      messageIntent.setAction("message-forwarded-from-data-layer");
      messageIntent.putExtra("message", message);
      LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent);
    
    }
    else {
      super.onMessageReceived(messageEvent);
    }
  }
}

Activity에서 Broadcast Receiver를 등록.

@Override
protected void onCreate(Bundle savedInstanceState) {
  // Basic UI code, generated by New Project wizard.
          ...

  // Register a local broadcast receiver, defined is Step 3.
  IntentFilter messageFilter = new IntentFilter("message-forwarded-from-data-layer");
  MessageReceiver messageReceiver= new MessageReceiver();
  LocalBroadcastManager.getInstance(this).registerReceiver(messageReceiver, messageFilter);
}

전송받은 메세지를 UI처리

 public class MessageReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
      String message = intent.getStringExtra("message");
              // Display message in UI
      mTextView.setText(message);
    }
  }
}

이제 Phone과 Wear기기가 연결 된 상태에서 Phone용으로 만든 앱을 실행 하면 Wear기기에 전달받은 메시지가 출력된다.