AndroidWearのWatchFaceを作ってみた


先日、LG G Watch を入手したので早速WatchFaceを作りました。
初めは実機のWatchFace設定の一覧に自作のWatchFaceが表示されず少し戸惑ったので備忘録をまとめておきます。

##完成したもの(手抜き)
![2014-12-09 22.25.42.png](https://qiita-image-store.s3.amazonaws.com/0/55941/29cb8da4-7d3c-df4e-717b-25ffcb80b25c.png "WatchFace")
画像は[@yaplus](https://twitter.com/yaplus)氏作のアイコンを使用しました

##マニフェスト
```AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="squidgirlwatchface.mizofumi.net.squidgirlwatchface" >

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.DeviceDefault" >
        <activity
            android:name=".WatchFaceActivity"
            android:allowEmbedded="true"
            android:theme="@android:style/Theme.DeviceDefault"
            android:label="イカ娘" >
            <meta-data
                android:name="com.google.android.clockwork.home.preview"
                android:resource="@drawable/squidicon" />

            <intent-filter>
                <category android:name="com.google.android.clockwork.home.category.HOME_BACKGROUND" />
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>
    </application>

</manifest>

```
重要な点としては、activityの設定で次のパラメータを設定します。

	android:allowEmbedded="true"
	android:theme="@android:style/Theme.DeviceDefault"
	android:label="WatchFaceの名前"

そしてmeta-dataには次のパラメータを設定します。

	android:name="com.google.android.clockwork.home.preview"
	android:resource="@drawable/squidicon"
android:resourceで指定された画像はWatchFace設定時のプレビュー画像として使用されます。
	

intent-filterは次のように設定します。

	<intent-filter>
		<category
			android:name="com.google.android.clockwork.home.category.HOME_BACKGROUND" />
		<action android:name="android.intent.action.MAIN" />
	</intent-filter>
	


##レイアウト
```
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/squidicon"
    android:id="@+id/background">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:id="@+id/time"
        android:textColor="#ff008bff"
        android:textSize="40dp"
        android:text="12:00"
        android:textStyle="bold"
        android:layout_below="@+id/date"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="-12dp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="2014/02/02 (TUE)"
        android:id="@+id/date"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="3dp"
        android:textColor="#ff005aa6" />
</RelativeLayout>
```

##ソースコード

```WatchFaceActivity.java
package squidgirlwatchface.mizofumi.net.squidgirlwatchface;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.support.wearable.view.WatchViewStub;
import android.text.format.DateFormat;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class WatchFaceActivity extends Activity {
    private final static IntentFilter INTENT_FILTER;
    private TextView date;
    private TextView time;
    private RelativeLayout background;

    static {
        INTENT_FILTER = new IntentFilter();
        INTENT_FILTER.addAction(Intent.ACTION_TIME_TICK);
        INTENT_FILTER.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        INTENT_FILTER.addAction(Intent.ACTION_TIME_CHANGED);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity2_watch_face);
        time = (TextView) findViewById(R.id.time);
        date = (TextView) findViewById(R.id.date);
        background = (RelativeLayout)findViewById(R.id.background);
        clockChange();
        registerReceiver(timeReceiver, INTENT_FILTER);
    }

    @Override
    protected void onPause() {
        super.onPause();
        background.setBackgroundResource(R.drawable.squidiconsleep);
        time.setTextColor(Color.parseColor("#ffffffff"));
        date.setTextColor(Color.parseColor("#ffffffff"));
    }

    @Override
    protected void onResume() {
        super.onResume();
        background.setBackgroundResource(R.drawable.squidicon);
        time.setTextColor(Color.parseColor("#ff008bff"));
        date.setTextColor(Color.parseColor("#ff005aa6"));
    }

    private void clockChange() {
        this.date.setText(DateFormat.format("yyyy/MM/dd (E)", Calendar.getInstance()));
        this.time.setText(DateFormat.format("kk:mm", Calendar.getInstance()));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(timeReceiver);
    }

    private BroadcastReceiver timeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            clockChange();
        }
    };
}

```

###スリープの時とアクティブな時の切り替え
* onPause()

	onPause()が呼ばれるのは、AndroidWear本体の画面が暗くなる時で、標準のWatchFaceだと画像等が非表示になり文字のみ表示される時と同じです。
  
	上記のコードでは画像の明るさを下げたものに差し替える動作をしています。
	(nullでも突っ込んで非表示にしても大丈夫です)
  
* onResume()

	onResume()が呼ばれるのは、onPause()時から復帰する時です。
	上記のコードでは、文字色と画像を変更する動作をするようにしています。
	

----
以上で簡単なWatchFaceを作ることが出来ました。

~~しかし、"OK Google"の表示位置等を変更する方法はまだ分かっていないため左上に表示されてしまいます。分かる方が居ましたら教えて頂けると助かります。~~

AndroidWearはSmartWatch等と違って従来のAndroidのレイアウトを設定するようにWearでもそのままレイアウトを設定できとても開発が簡単だと感じました。


#追記
端末に「OK Google」と話しかけて、音声入力画面にさせるのを3回程繰り返すとWatchFace上に表示される"OK Google"が勝手に表示されなくなりました。