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기기에 전달받은 메시지가 출력된다.




Google Android Wear 개발환경 설정


구글 I/O 2014를 발표를 기점으로 기존의 Wear Preview에서 정식으로 발표되었다. LG  G Watch와 삼성 Gear Live도 함께 출시되었다. 이로 인해 Wear Device를 처음으로 발을 내딧게 되었다. 기존의 Wear Preview 버전은 Eclipse를 지원하였으나, 이번 정식 버전에는 Eclipse에서는 지원하지 않고, Android Studio에서만 확인 가능하다.

구글은 Wear은 API 20 버전으로 Android 4.4W라는 네임을 가진다. Preview 버전에 비해 개발툴에서 많은 지원이 이루어졌으며, 구글 플레이서비스 5.0과 Anroid Wear 앱과 Google Search앱들도 대거 업데이트되어 이를 기반으로 Wear이 작동된다.

기존의 Preview버전을 사용한 개발자라면 모두 제거하고 정식버전을 설치 해야한다.

 

Wear 에뮬레이터와 폰간의 연결하기.

1] 아직 Wear관련 해서 앱들이 정식 출시 되지 않았기때문에 Testing을 등록 해서 구글 플레이 서비스 5.0과 Adnroid Wear, Google Search 앱을 내려받아야 한다.

1) Android Play Service 5.0
2) Android Wear Compaion
3) Google Search

2] AVD 에서 Waer용 애물레이터를 만든다.

3] 1번에서 설치한 Android Wear을 실행 후에 Notification Access 설정에서 Android Waer을 선택한다. Android Wear은 Android Notification을 이용하기때문에 액세스할 수 있는 권한을 주는 것이다. 안드로이드 폰에서 문자가 오거나 음악을 들을때 Notofication이 뜨는것을 볼 수 있는데 이것이 그래도 Wear에도 표시된다.

4] 에뮬레이터와 폰간의 연결을 위해 다음과 같이 adb명령을 내린다.

$ adb -d forward tcp:5601 tcp:5601