Android Nで導入される「浅いDoze」について

今年はGoogle I/Oに合わせるのではなく、3月にAndroid N Previewが公開されました。また、4月13日(米国時間)にPreview 2へのアップデートも公開されました。

以前、「DroidKaigi 2016:「 Andoridの省電力について考える」に対する補足」にて、DroidKaigi 2016での省電力関連の発表資料の紹介とその補足をいたしましたが、その時点で最新だったAndroid 6.0系よりもさらにDozeが強化されています。

Googleが公開しているドキュメントによると、Dozeに段階が設けられました。Android 6.0で導入されたDoze(深いDoze)とは別に、端末が静止1していなくてもバッテリ駆動かつスクリーンオフの状態が一定時間続くと、制限の緩いDoze(浅いDoze)に入ります。2

「浅いDoze」では、アプリのネットワーク通信不可となり、ジョブ(詳しくはJobSchedulerを参照)と同期がメンテナンスウィンドウもしくはDozeの解除まで遅延されます。

では、実際にどのくらいの時間経つと「浅いDoze」に入るのでしょうか。Preview時点ではソースコードがまだ開示されていませんので、実際の挙動から調査をしました。

Nexus 5XにAndroid N Preview 2を入れた状態では、以下のような挙動を確認しています。

バッテリー駆動かつスクリーンオフから「浅いDoze」に入るまでの時間

5分

メンテナンスウィンドウ間の時間

5分(1回目)、10分(2回目)、15分(3回目)……と、Linear Incremental Backoffで時間が増加(上限値は未確認)


  1. Nexus 5Xの場合、端末の静止確認にはSignificant Motion Sensorを使用しているようです。このセンサでは同じ場所で端末を振り回しても静止したままとみなされ、歩行や車などで移動することで動いたとみなされます。 

  2. 「深いDoze」条件が満たされた時点で「浅いDoze」の挙動から「深いDoze」の挙動に切り替わります。 

「AndroidシステムのWebView」を更新しよう

AndroidシステムのWebViewとは

Android 5.0から最新のWebViewはGoogle Playで更新されるようになりました。これにより「AndroidシステムのWebView」というアプリを更新することで、Chrome(Chromium)をベースとした、バグが修正されたWebViewを利用することができます。バグが修正されるということは、更新しておくとセキュリティ面でも安心です。

WebViewを利用しているアプリは多いので、セキュリティ問題が含まれたままの古いWebViewを利用していると、なんらかの攻撃を受けるリスクはかなり高くなります。

また、そのようなマイナスを減らすというだけではなく、更新することで新しいWeb技術を利用できるというプラスもあります。

ということで、Android 5.0以上の端末において「AndroidシステムのWebView」は是非とも更新すべきアプリの一つです。

2016年2月9日版までのWebViewのクラッシュ問題

(いつからかまでは特定できていませんが)2016年2月9日のバージョン48.0.2564.106までの「AndroidシステムのWebView」にはかなり重大なバグが潜んでいました。

このリンク先のissueがそれを示したものなのですが、簡単にまとめると「WebViewを利用したアプリがランダムに落ちる」というものです。

OpenGL関連のネイティブライブラリ内でクラッシュするようで、アプリ側で例外をキャッチして回復処理を行うということもできません。またランダムというのもくせものでした。弊社での確認でもそうだったのですが、この問題はAndroid 6.0および6.0.1上でのみ発生しているようでした。

ただ、一応アプリ開発する上での回避方法はありまして、以下のようにすることで回避できていました。

WebView webView; // この変数にWebViewインスタンスをセット
....
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)

これがどういうことをやっているかというと、「指定したWebViewの描画にハードウェア支援(GPUによる描画支援)を使用しない」という設定です。つまり回避のためにこの設定を行うと、WebViewの表示が遅くなりメモリ使用量も増えるというデメリットがあります。

Android 6.0以降が搭載された端末は非常に限られていたことや、パフォーマンス問題を引き起こすことを嫌うことなどから、回避策を入れていないアプリも多いと考えられます。

アップデートによる改善

Alex Mineer氏によると、49.0.2623.63がベータ版としてリリースされ、問題なければ正式にリリースされるとのことです。

issueのコメントによると、49.0.2623.55には問題のworkaround(回避策)が入っていますので、正式にリリース予定のバージョンでは問題は改善している見込みです。

弊社でWebViewのテスター登録を行ってベータ版をインストールしてみたところ、以前は落ちることがあったものが安定することを確認しました。

2016年春以降、Android 6.0端末急増の見込み

日本国内でも大手キャリアのAndroid端末に対するAndroid 6.0へのアップデートが始まります。たとえば、 NTTドコモによるAndoid 6.0へのアップデートのお知らせが出ています。

旧機種へのアップデートが行われるということは、今年の春夏モデル端末にはAndroid 6.0が搭載されてくるでしょう。

特にアップデートによってAndroid 6.0になるものについては、古いWebViewが搭載されたままとなっている可能性が高いでしょう。試験にかかる時間などを考えると、2月下旬に公開されたものを組み込んだ状態でアップデートがリリースされるとは考えにくいためです。

アプリ開発者はどうするべきか?

  • 6.0以降の端末である
  • 端末内の「AndroidシステムのWebView」のバージョンが古い
  • アプリ内でWebViewを利用している

上記の3つがAND条件で成立する場合、ユーザを「AndroidシステムのWebView」の更新に誘導してもよいかもしれません。

ユーザはどうするべきか?

AndroidシステムのWebView」を更新しましょう。アプリがクラッシュするのを少しでも減らせるのはよいことです。

DroidKaigi 2016:「 Andoridの省電力について考える」に対する補足

弊社代表の中西がDroidKaigi 2016にて「Androidの省電力について考える」というタイトルでセッションを担当いたしました。

以下にその際に用いた資料を示します。

また、上記の資料では説明しきれなかったDozeの細かい話について少しだけ補足をします。

Android 6.0 Dozeの状態遷移

Dozeに入るまでの状態の変化については、同イベントでのSmartium株式会社の江川さんによるセッション資料の以下のページが参考になります。

あくまでも簡略的な図であり、正確な状態遷移について知りたい方はコードを追いかけてみてください。

資料には状態を遷移する時間が記されていますが、その情報はDeviceIdleControllerクラスのupdateConstants()メソッドの定義を見るとよいでしょう。状態遷移についてはstepIdleStateLocked()を確認するとわかります。

stepIdleStateLocked()を見ると、状態はACTIVE -> INACTIVE -> IDLE_PENDING -> SENSING -> LOCATINGというように段階を追って遷移していくことが示されています。
LOCATING後すぐにIDLE_MAINTENANCEに遷移し、一定時間後にIDLEへと遷移し、IDLEからもまた時間が経つとIDLE_MAINTENANCEへと遷移するというようなコードとなっています。

Doze突入の判定と継続の条件

DozeServiceクラスを読むことで、どういう条件でDozeに入るのか、またDozeが継続されるのかがわかります。

資料に簡単に記載しましたが、DozeServiceはAPI Level 17で導入されたDaydreamという機能をベースに実現されています。言いかえると「DozeServiceはDreamServceを継承したサービス」です。

Daydreamはスクリーンセーバーを実現する機能であり、画面がOFFになるタイミングで働き始めます。そのタイミングから各種の条件が成立するかの監視を開始し、成立すると先に挙げた状態遷移が行われるというわけです。

資料にも簡単に記載しましたが、面白いところとしてはコードの中でpulseと表現されている事象(たとえば端末が動かされる)が発生することがIDLE状態から抜けるトリガとなるのですが、近接センサ(proximity sensor)で端末が何かの物体と近接している場合には抜け出すトリガは捨てるという処理があります。コードを細かく見ていきコメントなども確認するとわかるのですが、これは端末がポケットやかばんに入っている場合にはDozeで省電力モードのままとするための処理です。

Dozeはディープスリープか?

ディープスリープは端末として最低限の電力消費まで機能を落としている状態であるとするなら、弊社で調べた限りではDoze自体がディープスリープとは言えないのではないかと考えております。

いわゆるACPU(アプリが動作するプロセッサ)は動作しシステムとしてはネットワーク通信もしている状態です。除外設定されたアプリは普通に動いています。そうでなければ高優先度のGCMを受け取って即時に対象のアプリに渡すということもできません。

Dozeによる省電力に対して非協力的なアプリが多いと、省電力効果は限定的になるだろうと考えられます。

そのため、Androidの将来バージョンにおいて更なる強制的な制限が行われることを避けるためにも、アプリ開発者ができるだけ省電力に対して協力的になることは非常に大事なことだと考えております。

Android M (6.0)でのActivity#shouldShowRequestPermissionRationaleの使いどころを探る

注意:本記事については、弊社でもどうするのがベストプラクティスなのか掴みかねております。その点を留意してお読みください。

Andorid M (6.0)のPreview 2から、ActivityクラスにshouldShowRequestPermissionRationaleというメソッドが追加されています。rationaleとは「理論的根拠」とかそんな感じの意味があるので、このメソッドは「パーミッション要求の根拠を表示すべきかどうか」を判定するためのものであることが名前からわかります。

実際、Previewのドキュメントでもそういう風に使うように記載されています。

しかし、このメソッドの挙動が少し不思議です。

  1. まだ一度も要求していないパーミッションを渡した場合、falseが返る
  2. 要求したパーミッションが拒絶されたことがあり、かつ今後表示しないチェックがつけられていない場合、trueが返る
  3. 要求したパーミッションが、今後表示しないというチェックを入れて拒絶された場合、falseが返る

上記のような挙動になります。

ここで不思議なのは1番目です。初回のパーミッション要求の前にも、そのパーミッションをどういう根拠で求めるのかはユーザに提示した方が良いのではないかと思われますが、このAPIに従った場合、表示しないというパスに流れます。

また、PreviewのAPI Overviewに示されたコードも不思議です。

if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (shouldShowRequestPermissionRationale(
            Manifest.permission.READ_CONTACTS)) {
        // Explain to the user why we need to read the contacts
    }

    requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
            MY_PERMISSIONS_REQUEST_READ_CONTACTS);

    // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
    // app-defined int constant

    return;
}

このコードを参考にして実装すると、shouldShowRequestPermissionRationale()の結果がtrueであったときに説明を表示します。たとえばダイアログで表示するなどが考えられますが、その場合はダイアログ表示している間にrequestPermissions()がすでに呼び出され、外部アプリ(PackageInstallerアプリ)による権限確認ダイアログの表示に遷移してしまうことでしょう。

以上から、このサンプルコードをベースに書くのはベストプラクティスでは無いだろうと考えています。

ということで、現時点ではどうするのが良いのかについてはまだ模索中です。二つの問題点とうまく折り合いをつけたベストプラクティスがGoogleから提示されることを期待しています。

Android M (6.0)の新セキュリティモデルの注意点

TechBooster様の「Androidビルディングデザイン」に、弊社代表中西がAndroid Mの新しいセキュリティモデル(パーミッションモデル)の記事を寄稿しました。2015年8月25日現在、紙の書籍は完売しておりますが電子書籍版はまだ頒布されています。

電子版では、Android M Developer Preview 3、SDKバージョン23、Support Libraryバージョン23についても反映した内容に更新されていますが、その中では触れていない気をつけないといけない項目について、ここに記載します。

targetSdkVersionを23以上に上げたアプリは22以下に戻せない

Android Studioでデバッグ実行で試すとわかるのですが、targetSdkVersionを23にしたアプリをインストールし、それを22以下に変更して再度インストールしようとすると、以下の様な警告が表示されます。

Failure [INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE]

書いてあるとおり、パーミッションモデルのダウングレードを求めるようなアプリのインストールが許可されていません。この時、Android Studioは以下のようなダイアログも表示します。

スクリーンショット 2015-08-25 10.36.08

ここに書いてあるのは、今インストールされているアプリをアンインストールして、それからインストールするかと聞いてきています。つまり、インストール済みのアプリの保存しているデータや設定などを維持して、targetSdkVersionを22以下に落としたアプリのインストール(アップデート)を行うことはできません。

これ、おそらくはGoogle Play Storeでも対策がなされるのではないでしょうか。

一度targetSdkVersionを23以上に上げて新しいセキュリティモデルの対象となったアプリは、targetSdkVersionを上げたことによって発生したバグがあっても、22以下に戻したアプリをアップロードすることはできなくするのではないかと。

既存アプリを運用されている場合、targetSdkVersionを23に変更するのは慎重に行うようにしましょう。

targetSdkVersion 22以下のアプリを23にした場合、パーミッションが許可状態になる

これはユーザにとっての罠ですが、Android M端末にtargetSdkVersionが22以下のアプリをインストールし、それがバージョンアップでtargetSdkVersionが23になったとしても、パーミッションが許可状態になります(Context#checkSelfPermissionがtrueを返します)。

新規にtargetSdkVersionが23のアプリをインストールした場合、最初はContext#checkSelfPermissionはfalseとなりますので、そこからActivity#requestPermissionsによって権限を取得していくという流れになります。

しかし、前述の場合は、targetSdkVersionが22のアプリをインストールした時点で、権限利用を許可したという状態が端末に記録され、それはtargetSdkVersionを23以上に上げた場合にも維持されます。

この挙動は、iOSなどで新しいOSバージョンで権限チェックが強化された場合の挙動とは異なります。iOSでは、たとえばマイク利用にユーザによる権限確認が必要となった場合、アプリの新規インストールとアップデートのいずれであってもダイアログで確認するという挙動になります。

この挙動のまま正式版となるかはわかりませんが、ユーザは気をつけておくとよいでしょう。

Mac OSX Yosemite(10.10)でAndroid Studio起動に利用するJDKの変更

Android Studioは、利用するJDKを環境変数STUDIO_JDKに設定することで切り替えることができます。このことはAndroid Tools Project Site内のMac OSX JDK Selectionで説明されています。

ただし、上記の方法では、Android Studioをいちいちコマンドラインから立ち上げないといけないため面倒です。そのため、ランチャー向けにSTUDIO_JDKの環境変数を設定しておく方が便利です。

Marvericks(10.9)では、/etc/launchd.conf に環境変数を記述しておくと、ランチャー向けにその環境変数が設定されました。しかし、Yosemiteからは/etc/launchd.confの設定は無視されます。

Yosemite以降では、/Library/LaunchAgents以下にplistファイルを作成し、その中で環境変数を設定する必要があります。適当なファイル名で以下の様なplistファイルを作成してください(たとえば com.example.android.studio.plist)。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>com.example.android.studio.plist</string>
    <key>ProgramArguments</key>
    <array>
      <string>/bin/launchctl</string>
      <string>setenv</string>
      <string>STUDIO_JDK</string>
      <string>/Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
  </dict>
</plist>

「com.example.android.studio.plist」は、将来的にもAndroid Studioなどが公式に作成するファイルと重ならないようにつけているだけで、ご自身の好みで名前は適当に変えてください(たとえば自分の持っているドメイン名をリバースドメインで使用するなど)。

使用するJDKのバージョンなどについても、ご自身が使用したいものを指定してください。必ずインストールされているJDKを指定してください。ここでは、執筆時点でのJava8最新のJDKを指定しています。

ファイルを作成したらOSを再起動すれば設定が反映されます。ランチャーからのAndroid Studio起動時に、STUDIO_JDKに設定したJDKが使用されるようになります。

OS再起動したくない場合、以下のようにすると追加したファイルの設定が追加反映されます。

% sudo launchctl load /Library/LaunchAgents/com.example.android.studio.plist

Android 5.0でのセキュリティ機能追加 (RestrictionsManager)

これまでに弊社blogにて、Android 4.3からの隠し機能AppOpsでユーザによるパーミッション制御ができるようになっていたということを書いておりました。

Android 5.0でもAppOpsの仕組みは一部で生き残っていますが、あまり拡張されませんでした。別の機能としてRestrictionsManager というものが追加されているようです。

API Referenceから引用します。

Apps can also send permission requests to a local or remote device administrator to override default app-specific restrictions or any other operation that needs explicit authorization from the administrator.

もしかしてpermission機構とは別の仕組みで権限管理が!と期待しましたが、直交する概念だったようです。ただし、Universal Data Controls というAndroid 5.0から導入される仕組みとどう関係するかは要確認です。

サンプルアプリがgithub上で公開されていますが、アプリごとに定義したrestrictionを管理する仕組みでしょうか。具体的な使用方法がまだイメージ出来ていません。

より正確な情報は調査の上で追加していく予定ですが、まずは一報だけ。

Android Wear向けにアプリを作ってみた (2014/07/01 訂正)

(2014/07/01 アプリのインストール手順とapkファイルを更新しました。)

Android Wear端末での音声入力と、Wear端末とコンパニオン端末の相互通信のプログラミング方法の調査ついでにちょっとしたアプリを作ってみました。

コンパニオン端末(スマートフォン)用アプリをダウンロードして、コンパニオン端末に adb install などでインストールしてください。

このアプリのassetsにwear用アプリのapkも含まれており、コンパニオン端末にアプリをインストールすると、wear端末にはassets内に含まれたapkファイルがインストールされるようです。wear端末へのアプリインストール完了には少し時間がかかるので少々お待ちください。

なお、コンパニオン端末にアプリをインストールしたタイミングだけwear端末にアプリがインストールされるのか、新規のwear端末に自動的にコンパニオン端末上のアプリが持っているwearアプリがインストールされるのかといったタイミングについてはまだ調査しておりません。

device-2014-06-29-231622

両端末へのアプリインストールが成功していれば、コンパニオン端末アプリのボタンを押すとWear端末側のアプリが起動します。

device-2014-06-29-231444

Wear端末の音声入力ボタンを押してください。

device-2014-06-29-231454

音声入力画面が起動するので、「バンザイ」と音声に入力してみてください。

device-2014-06-29-231648

すると、コンパニオン端末上のドロイドくん(Android Robot)がバンザイします。3秒ほどすると元のポーズに戻ります。

実は他に一つポーズを隠しで入れてあります。Wearが腕時計型であることとWearアプリに出ている言葉から類推すると隠しコマンドを見つけやすいかもしれません。

ソースはもうちょっと整理したら公開するかもしれません。

Enjoy Android Wear!

Android Wear: アプリプロジェクトの新規作成から実機起動まで

追記 (2014/06/27 11:38 PST)

Android 0.8.1 が公開され、そちらで新規作成したプロジェクトにはバグが含まれないことを確認しました。

ただし、Android 0.8.1での新規プロジェクト作成で作られるMyActivityクラスは、Wearアプリ用に用意されたInsetActivityクラスではなく、普通にActivityクラスを親クラスとして参照するようです。

(Android SDK Managerでの、Android Support RepositoryとGoogle Repositoryのrevisionが古い問題は未解決です。)

アプリビルド環境について

Android Wearアプリのビルドには、Android Studio 0.8.0 が必要です。ただし、単純にそれをインストールしてただけではビルドが通りません。

回避策は見つかっているので、前回の記事を参照してください。

Android Studio 0.8.0が生成するプロジェクトの問題

Android Studio 0.8.0 では、Wearアプリのプロジェクトを新規作成できますが、前述の環境設定が終わっていてもビルドに成功しません。

作成されるプロジェクトの初期状態のMyActivityが誤っているようです。新規作成ウィザードが完了すると、以下のようなMyActivityクラスが生成されます。

public class MyActivity  extends WatchActivity {

    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override
            public void onLayoutInflated(WatchViewStub stub) {
                mTextView = (TextView) stub.findViewById(R.id.text);
                Log.d(TAG, "TextView: " + mTextView.getText() + " view=" + mTextView);
            }
        });
    }
}

上記には以下の問題があります。

  • 親クラスとして指定しているWatchActivityというクラスが存在しない
  • TAGが定義されていない (おそらく WatchActivityに定義されている前提)

Wear用のサポートライブラリに含まれるJavaDocから、android.support.wearable.activity.InsetActivity がWearアプリの基本的なベースActivityクラスだとわかりますので、WatchActivity を InsetActivityに置き換えます。

そして、InsetActivityでabstractで定義されている onReadyForContent()をオーバーライドして実装します。

TAGが定義されてないのでLog.d()も取り払いましょう。

public class MyActivity  extends InsetActivity {

    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override
            public void onLayoutInflated(WatchViewStub stub) {
                mTextView = (TextView) stub.findViewById(R.id.text);
            }
        });
    }

    @Override
    public void onReadyForContent() {
    }
}

以上で、Wearアプリのビルドが通るようになります。

しかし、これを実際にWearにインストールして実行すると IllegalStateExceptionが発生して落ちます。

エラーメッセージによると、setContentView()以降はonReadyForContent()で実行しないといけないようです。ということで、以下のように修正します。

public class MyActivity  extends InsetActivity {

    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onReadyForContent() {
        setContentView(R.layout.activity_my);
        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override
            public void onLayoutInflated(WatchViewStub stub) {
                mTextView = (TextView) stub.findViewById(R.id.text);
            }
        });
    }
}

これでアプリの実行が成功するようになります。

Let’s enjoy Android Wear app development!

Android Studio 0.8.0 で Wear プロジェクトのビルド失敗について

問題

新規作成したWearプロジェクトのビルド時に、依存ライブラリが見つからないというエラーが出て失敗します。

見つからないのは以下の2ライブラリです。

  • com.google.android.gms:play-services-wearable:+
  • com.google.android.support:wearable:+

原因

Wear プロジェクトの依存ライブラリがまだ配布されていません (PST 2014年6月26日 18時現在)

Android SDK Manager でSDKを最新に更新し、Android 4.4W のコンポーネントを全部インストールし、サポートライブラリとGogoleのレポジトリも最新に更新した状態でも、sdk/extras 以下に必要なライブラリファイルが配信されていないために発生しています。

解決策

待ちましょう。Android SDK Managerで配信されるコンポーネントが更新されないと解決しないため。

Google I/O 2014でGoogleの人にこの件は伝達し、さらにadt-devというAndroid開発環境に関するGoogle Groupsにも報告を送りました。

adt-dev への報告はモデレータさんがOKしないと出ないと思われるので、念のため issue tracker にも以下で登録しました。

Can’t build Android Wear application project generated by Android Studio 0.8.0

(緩和策について追記: 2014/06/27 00:16 PST)
緩和策は見つかっています。以下のURLからダウンロードしたファイルを所定のディレクトリに置くことです。

https://dl-ssl.google.com/android/repository/google_m2repository_r09.zip

(上記の説明だけで対応出来る人にしか緩和策の実行はおすすめしません。)

これは上記のissueへのコメントに示されたxmlファイルから推察されたURLであり、実際にそのファイルは存在するようです。

ただし、これは正式な方法ではありません。もしかすると同じファイル名で差し替えのファイルが提供され、その後に公式にAndroid SDK Managerからダウンロードが提供されるかもしれません。その場合、SDK Managerからダウンロードできるファイルが改善版であるにも関わらず、同じリビジョンであるためにダウンロードが行われないということが起こる可能性もあります。

リスクを勘案し、元に戻せるようにするなどの対策をした上で使用することをおすすめします。

おまけ: Android Wearについて

Google I/O 2014にて参加者に先行して端末が配布されました。

実際に半日使用してみたところ、スマートフォンを取り出して確認するという行動がかなり減り、いろいろと快適になった感じがします。

ハングアウト(Google+のチャット機能)やTwitterへの返信を、日本語の音声入力で腕時計から簡単に返すというようなことも出来て非常に便利です。

Wearにインストールするアプリ次第でさらにいろいろなことも出来るので、今後が楽しみです。