2014年1月28日火曜日



GDKでは、以前お伝えしたCardの仕組みを使わずにAndroidと同様にActivityを使ってアプリを構築することができます。



注意点としては以下があります。



  • 640 × 360 の解像度

  • スワイプダウンが戻るボタンに該当する

  • Androidのようなタッチ操作はできない

しかしActivityだけではアプリが timeline 上に表示されない為、ユーザーがアプリを起動する手段がありません。そこで、アプリ起動用Serviceを用意してonStartCommand()のタイミングで任意のアクティビティを起動してやる必要があります。

なんだかとても面倒に感じますが、とても簡単。

まずサービスクラスを用意します。

単純にアクティビティを起動するだけのサービスクラスに必要なコードはたったこれだけ。

public class HelloService extends Service {
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Intent aIntent = new Intent();
        aIntent.setClassName("com.example.helloactivity","com.example.helloactivity.MainActivity");
        aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
        startActivity(aIntent);
        return START_STICKY;
    }
}


あとは timeline からサービスを呼ぶようにマニフェストファイルを設定するだけ。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloactivity"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="15" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
         android:icon="@drawable/ic_launcher"
            android:name="com.example.helloactivity.MainActivity"
            android:label="@string/app_name" >
        </activity>
        <service
            android:name="com.example.helloactivity.HelloService"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
            </intent-filter>
            <meta-data
                android:name="com.google.android.glass.VoiceTrigger"
                android:resource="@xml/voice_trigger_start" />
        </service>
    </application>
</manifest>


この intent-filter と meta-data が重要で、これを記述することによってサービスが timeline 上に表示されるようになります。

            <intent-filter>
                <action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
            </intent-filter>
            <meta-data
                android:name="com.google.android.glass.VoiceTrigger"
                android:resource="@xml/voice_trigger_start" />


これだけで、Androidと同様のActivityを使ったアプリをGlassで実現することができます。

しかし、AndroidアプリをGlassに簡単に移植できる、とは考えないで下さい

現時点で Activity は Glass にはコストが高く、非常に動作が重くなり、本体の発熱も凄いです。

現時点では、Glass に Activity を使うのは良い選択肢ではないと考えます。

それを示すように、Activity を使って描画を行っているサンプルは Google から提供されていません。

そもそもソースコードも公開されてませんし、Glass は Android と似て非なるもの なのです。




GDKでActivityを使ってみる



GDKでは、以前お伝えしたCardの仕組みを使わずにAndroidと同様にActivityを使ってアプリを構築することができます。



注意点としては以下があります。



  • 640 × 360 の解像度

  • スワイプダウンが戻るボタンに該当する

  • Androidのようなタッチ操作はできない

しかしActivityだけではアプリが timeline 上に表示されない為、ユーザーがアプリを起動する手段がありません。そこで、アプリ起動用Serviceを用意してonStartCommand()のタイミングで任意のアクティビティを起動してやる必要があります。

なんだかとても面倒に感じますが、とても簡単。

まずサービスクラスを用意します。

単純にアクティビティを起動するだけのサービスクラスに必要なコードはたったこれだけ。

public class HelloService extends Service {
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Intent aIntent = new Intent();
        aIntent.setClassName("com.example.helloactivity","com.example.helloactivity.MainActivity");
        aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
        startActivity(aIntent);
        return START_STICKY;
    }
}


あとは timeline からサービスを呼ぶようにマニフェストファイルを設定するだけ。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloactivity"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="15" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
         android:icon="@drawable/ic_launcher"
            android:name="com.example.helloactivity.MainActivity"
            android:label="@string/app_name" >
        </activity>
        <service
            android:name="com.example.helloactivity.HelloService"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
            </intent-filter>
            <meta-data
                android:name="com.google.android.glass.VoiceTrigger"
                android:resource="@xml/voice_trigger_start" />
        </service>
    </application>
</manifest>


この intent-filter と meta-data が重要で、これを記述することによってサービスが timeline 上に表示されるようになります。

            <intent-filter>
                <action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
            </intent-filter>
            <meta-data
                android:name="com.google.android.glass.VoiceTrigger"
                android:resource="@xml/voice_trigger_start" />


これだけで、Androidと同様のActivityを使ったアプリをGlassで実現することができます。

しかし、AndroidアプリをGlassに簡単に移植できる、とは考えないで下さい

現時点で Activity は Glass にはコストが高く、非常に動作が重くなり、本体の発熱も凄いです。

現時点では、Glass に Activity を使うのは良い選択肢ではないと考えます。

それを示すように、Activity を使って描画を行っているサンプルは Google から提供されていません。

そもそもソースコードも公開されてませんし、Glass は Android と似て非なるもの なのです。









本ブログ「屋内測位をやってみました」で、始めた屋内測位ですが、あれからいろいろやってみて、だいぶまともに動くようになってきました。今回はある会議室にビーコンをだいたい3m四方に12個配置しました。使用したビーコンは、Estimote社のものを使っています。このビーコン出力が弱いため、精度を出すには3mという短い間隔で置くしかありませんでした。使用した測位アルゴリズムも、トリラテレーション(Trilateration)ではなく、近辺のビーコン位置にRSSI値をもとにした加重平均をとる方法を採用しました。

では、実際の実験の様子をご覧ください。

iBeaconで屋内測位成功のヒントをつかんだ!






本ブログ「屋内測位をやってみました」で、始めた屋内測位ですが、あれからいろいろやってみて、だいぶまともに動くようになってきました。今回はある会議室にビーコンをだいたい3m四方に12個配置しました。使用したビーコンは、Estimote社のものを使っています。このビーコン出力が弱いため、精度を出すには3mという短い間隔で置くしかありませんでした。使用した測位アルゴリズムも、トリラテレーション(Trilateration)ではなく、近辺のビーコン位置にRSSI値をもとにした加重平均をとる方法を採用しました。

では、実際の実験の様子をご覧ください。

2014年1月22日水曜日

2013年12月に締め切られた、Bluetooth SIG Breakthrough Awardsの決勝進出者が2014年1月6日にCES(ラスベガス)で発表されました。

https://www.bluetooth.org/ja-jp/news-events/bluetooth-breakthrough-awards

選考は、4つのカテゴリー(製品/アプリケーション/試作品/学生のアイデア)に分かれています。CESでの発表は、あくまで決勝進出者です。優勝者は、2月23日にバルセロナで開かれるMWC(=Mobile World Congress)で発表されます。個人的に気に入っているのが、試作品部門の「H2O-Pal」ですね。シンプルな発想がいいです。ぜひ勝ち残ってほしいです。次回ブログで各作品について詳しく見ていきたいです。


以下は、Bluetooth SIGのサイトから引用です。読み難かったので表にしてみました。


製品部門
製品名 製作者 説明

InfoMotion Sports Technologies 94Fifty® Smart Sensor Basketball は、バスケットボールコートで自信を培い、多才な能力を持ち、成功するためには不可欠な鍵となる技能の頻度と質の両方を測定および診断する業界初の Bluetooth Smart フィットネス製品です。

Nonin Medical Inc Nonin Model 3230 は、血液酸素、脈拍数、およびその他のパルス信号特性を測定し、患者、個人介護人、ならびに医療専門家を支援するための情報を提供する世界初の臨床 Bluetooth Smart 指パルス酸素濃度計です。

Swirl Networks Swirl は、店内ショッピング体験を変容し、小売店売上を増やすために、Bluetooth Smart を通じて携帯機器の力を活用する小売業者を支援します。

Anki Anki Drive は、自宅のリビングルームの床で楽しむレーシングゲームです。しかしリモコンやスロットカーとは違って、Anki Drive カーは他では可能でない速度と正確さの水準を極めるためにロボット工学と人工知能 (AI) で高機能化されています。車体は iOS 機器からのコマンドを全て Bluetooth Smart を使って絶えず送受信しています。

Leica-Geosystems AG Leica DISTO™ D810 touch は、タッチスクリーン搭載で画像で測定を行うことができる最初のレーザー距離計です。高機能性は、通信するために Bluetooth Smart を使うスマートフリーアプリ “Leica DISTO™ sketch” で完成します。


アプリ部門
アプリ名 製作者 説明

Polar Electro Oyその Bluetooth Smart 技術により、大型のアリーナでさえカバーできる素晴らしい送信域とユーザーフレンドリーなアプリ設計である Polar Team は、屋内スポーツチームにとって比類のないソリューションです: チーム全体のパフォーマンス、激しさ、ならびに心拍数を別々の基地局なしでリアルタイムに追跡できる唯一のソリューション – 必要なものは複数のセンサーと 1 台の iPad です。

Automatic LabsAutomatic は、自動車のデータポート (米国で 1996 年以降発売された全ての自動車に搭載) に差し込む小型のハードウェアアクセサリーを通じて、車載コンピュータと iPhone を接続するアプリです。運転しているときはいつでも、たとえ電話機があなたのポケット内からずっと離れない場合でさえ、Bluetooth Smart Ready 機器を利用して自動車と電話機は接続します。

MobiliMobilis は、センサー、ボタン、カメラ、スマートウォッチ、アクチュエータのような異なる 50 台以上の Bluetooth® 機器、Bluetooth Smart® 機器ならびに内部機器と接続するクライアントを支援し、単一または複数センサー/ユーザープラットフォームとして設計されます。

試作品部門
作品名製作者説明

SkulptAim™ は、身体組成を測定し、個別の筋肉を分析するための革新的な機器です。あらゆる測定結果は Bluetooth Smart を通じて個人用オンラインダッシュボードに自動的に同期します。

Out of Galaxy, LLCH2O-Pal は水分摂取量を監視して、必要に応じて水を飲むようにユーザーに促します。

BeeWiBeeWi Smart Plug は、スマートフォンによって制御できるプラグです。電気装置のスイッチを簡単にオン/オフでき、アプリからプログラムできます。

BionymBionym のプレミア製品である Nymi は、ECG (心電図) を使って装着者の身元を確認するリストバンドです。一度確認されると、Nymi は近くにある Bluetooth Smart を使う機器やシステムと装着者の身元をやり取りできます。

学生アイデア部門
作品名製作者説明
ピアノペダルCatherin Keithlineタブレット上のシートミュージックを次のページにする小型の携帯用足踏みペダル。
Arduino ベースの Bluetooth 上腕義手Shiva Nathan切断手術を受けた患者の腕に取り付けることができる低コストの人工装具、脳による制御インターフェース (BCI) 上腕義手。
SpectrumBetty Quinn患者ならびに医者に不安障害に対するより良い洞察を与えるために脈拍および発汗を追跡する装着機器。
クールな冷蔵庫Temeka Gongs食物がまだ食用に適するかを確認するために、貯蔵容器の蓋にパチンと留めて食物から放出された化学物質を監視するセンサー機器。
自転車スーパービジョンSavannah Cofer自転車運転者が周囲 360 度の状況把握を可能にするアプセサリーソリューション。

[コラム] BluetoothSIG - Breakthrough Awards の決勝進出作品を吟味する(1)

2013年12月に締め切られた、Bluetooth SIG Breakthrough Awardsの決勝進出者が2014年1月6日にCES(ラスベガス)で発表されました。

https://www.bluetooth.org/ja-jp/news-events/bluetooth-breakthrough-awards

選考は、4つのカテゴリー(製品/アプリケーション/試作品/学生のアイデア)に分かれています。CESでの発表は、あくまで決勝進出者です。優勝者は、2月23日にバルセロナで開かれるMWC(=Mobile World Congress)で発表されます。個人的に気に入っているのが、試作品部門の「H2O-Pal」ですね。シンプルな発想がいいです。ぜひ勝ち残ってほしいです。次回ブログで各作品について詳しく見ていきたいです。


以下は、Bluetooth SIGのサイトから引用です。読み難かったので表にしてみました。


製品部門
製品名 製作者 説明

InfoMotion Sports Technologies 94Fifty® Smart Sensor Basketball は、バスケットボールコートで自信を培い、多才な能力を持ち、成功するためには不可欠な鍵となる技能の頻度と質の両方を測定および診断する業界初の Bluetooth Smart フィットネス製品です。

Nonin Medical Inc Nonin Model 3230 は、血液酸素、脈拍数、およびその他のパルス信号特性を測定し、患者、個人介護人、ならびに医療専門家を支援するための情報を提供する世界初の臨床 Bluetooth Smart 指パルス酸素濃度計です。

Swirl Networks Swirl は、店内ショッピング体験を変容し、小売店売上を増やすために、Bluetooth Smart を通じて携帯機器の力を活用する小売業者を支援します。

Anki Anki Drive は、自宅のリビングルームの床で楽しむレーシングゲームです。しかしリモコンやスロットカーとは違って、Anki Drive カーは他では可能でない速度と正確さの水準を極めるためにロボット工学と人工知能 (AI) で高機能化されています。車体は iOS 機器からのコマンドを全て Bluetooth Smart を使って絶えず送受信しています。

Leica-Geosystems AG Leica DISTO™ D810 touch は、タッチスクリーン搭載で画像で測定を行うことができる最初のレーザー距離計です。高機能性は、通信するために Bluetooth Smart を使うスマートフリーアプリ “Leica DISTO™ sketch” で完成します。


アプリ部門
アプリ名 製作者 説明

Polar Electro Oyその Bluetooth Smart 技術により、大型のアリーナでさえカバーできる素晴らしい送信域とユーザーフレンドリーなアプリ設計である Polar Team は、屋内スポーツチームにとって比類のないソリューションです: チーム全体のパフォーマンス、激しさ、ならびに心拍数を別々の基地局なしでリアルタイムに追跡できる唯一のソリューション – 必要なものは複数のセンサーと 1 台の iPad です。

Automatic LabsAutomatic は、自動車のデータポート (米国で 1996 年以降発売された全ての自動車に搭載) に差し込む小型のハードウェアアクセサリーを通じて、車載コンピュータと iPhone を接続するアプリです。運転しているときはいつでも、たとえ電話機があなたのポケット内からずっと離れない場合でさえ、Bluetooth Smart Ready 機器を利用して自動車と電話機は接続します。

MobiliMobilis は、センサー、ボタン、カメラ、スマートウォッチ、アクチュエータのような異なる 50 台以上の Bluetooth® 機器、Bluetooth Smart® 機器ならびに内部機器と接続するクライアントを支援し、単一または複数センサー/ユーザープラットフォームとして設計されます。

試作品部門
作品名製作者説明

SkulptAim™ は、身体組成を測定し、個別の筋肉を分析するための革新的な機器です。あらゆる測定結果は Bluetooth Smart を通じて個人用オンラインダッシュボードに自動的に同期します。

Out of Galaxy, LLCH2O-Pal は水分摂取量を監視して、必要に応じて水を飲むようにユーザーに促します。

BeeWiBeeWi Smart Plug は、スマートフォンによって制御できるプラグです。電気装置のスイッチを簡単にオン/オフでき、アプリからプログラムできます。

BionymBionym のプレミア製品である Nymi は、ECG (心電図) を使って装着者の身元を確認するリストバンドです。一度確認されると、Nymi は近くにある Bluetooth Smart を使う機器やシステムと装着者の身元をやり取りできます。

学生アイデア部門
作品名製作者説明
ピアノペダルCatherin Keithlineタブレット上のシートミュージックを次のページにする小型の携帯用足踏みペダル。
Arduino ベースの Bluetooth 上腕義手Shiva Nathan切断手術を受けた患者の腕に取り付けることができる低コストの人工装具、脳による制御インターフェース (BCI) 上腕義手。
SpectrumBetty Quinn患者ならびに医者に不安障害に対するより良い洞察を与えるために脈拍および発汗を追跡する装着機器。
クールな冷蔵庫Temeka Gongs食物がまだ食用に適するかを確認するために、貯蔵容器の蓋にパチンと留めて食物から放出された化学物質を監視するセンサー機器。
自転車スーパービジョンSavannah Cofer自転車運転者が周囲 360 度の状況把握を可能にするアプセサリーソリューション。

2014年1月15日水曜日



Google からGlass Development Kit(以後GDK)が発表されてしばらく経ちました。

合わせて開発者用Glassの販売も行われ、今後市場投入に向けての動きが活発になることが予想されます。

しかしこの開発者用Glass、2014年1月時点で日本からは購入することができません。

USAでも開発者向けの招待メールでしか購入ができないようになっています。

弊社は現地支社がある為、いくつか購入することができました。

Glassを使った開発ノウハウが徐々に溜まってきたので、GDKでHelloWorldを書く方法をお伝えします。



さて、まず一言。

HelloWorld を書くのにこんなに苦労したのは久しぶりでした

完成されたSDKであれば普通、HelloWorldというのはプロジェクトを新規作成すると自動的に生成されるスケルトンプロジェクトに、ちょちょいと追記するだけで簡単に作れるものなのですが、現在のGDK(Rev.2)にはスケルトンコードを出力する機能がありません

従って今回は、GDKの中に含まれるサンプルコードをリファクタリングしながらHelloWorldを作ります。

Google Glassの開発環境


Glassの開発環境は基本的にAndroidと同じで、IDEはEclipseを使うのが最も簡単でしょう。

Android SDK Managerから Android 4.0.3 > GDK を選択して開発環境をインストールします。

f:id:bs-android:20140110095919p:image:w640

HelloWorldを作ってみる


それではGDKに含まれるサンプルコードをリファクタリングしながらHelloWorldを作ってみます。

新規プロジェクト > Android Sample Project > GDK > Timer を選択します。最後の画面でプロジェクト名をHelloWorldに変えておきます。

f:id:bs-android:20140110095920p:image:w360

f:id:bs-android:20140110095921p:image:w360

f:id:bs-android:20140110095922p:image:w360

このサンプルはその名の通りタイマーアプリで、設定した時間をカウントダウンすることができます。

まず、アプリがどのような動作をするか確認します。

遷移図を作りました。

f:id:bs-android:20140110095924j:image:w640

Glassはタップによる文字入力ができませんので入力項目は全て選択式になります。従って、シンプルなアプリですが画面数はとても多くなる傾向にあります。

Timerサンプルを解析してみる


次はTimerサンプルのコードを見て行きます。

まずはManifestから。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.android.glass.sample.timer"
    android:versionCode="2"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="15" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_timer"
        android:label="@string/app_name" >

        <activity
            android:name="com.google.android.glass.sample.timer.MenuActivity"
            android:label="@string/app_name"
            android:theme="@style/MenuTheme"
            android:enabled="true" >
        </activity>

        <activity
            android:name="com.google.android.glass.sample.timer.SetTimerActivity"
            android:label="@string/app_name"
            android:enabled="true" >
        </activity>

        <activity
            android:name="com.google.android.glass.sample.timer.SelectValueActivity"
            android:label="@string/app_name"
            android:enabled="true" >
        </activity>

        <service
            android:name="com.google.android.glass.sample.timer.TimerService"
            android:icon="@drawable/ic_timer"
            android:label="@string/app_name"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
            </intent-filter>
            <meta-data
                android:name="com.google.android.glass.VoiceTrigger"
                android:resource="@xml/voice_trigger_start" />
        </service>

    </application>

</manifest>


Activity が三つにServiceが一つ宣言されています。

こんなに小さなアプリでActivityが三つもあるのは何故か?

Glassでは基本的にActivityはコンテンツを描画する目的では無くメニューを表示する目的で使われます。従って、メニュー(設定項目や選択項目)が増えるとActivityがどんどん増えていく傾向があります。

Service内のmeta-dataは音声認識によるアプリ起動をサポートします。

次はソースコードを見て行きます。



  • MenuActivity.java

  • SelectValueActivity.java

  • SelectValueScrollAdapter.java

  • SetTimerActivity.java

  • SetTimerScrollAdapter.java

  • Timer.java

  • TimerDrawer.java

  • TimerService.java

  • TimerView.java

この中で最低限必要なクラスは以下です。



  • MenuActivity.java

  • TimerDrawer.java

  • TimerService.java

一つのGlassアプリには必ず一つのサービスが必要です。

サービスである為、アプリを終了する為のメニューが必要となるでしょう。必然的にメニューを表示するActivityも一つは必要となります。

さっき、Activityはメニューを表示する為に使うと説明しました。では、肝心のコンテンツはどのように描画するか?

GlassではCardというAndroidには無い仕組みが有ります。

Cardとは


Androidでは一つのActivityで一画面を表現しますが、Glassでは一つのCardで一つの画面を表現することができます。

CardにはStatic CardLive Cardの二種類があり、画面の更新頻度に応じて使い分けるとDocには書かれています。

TimerサンプルはLive Cardを利用している為、今回はLive Cardを使うことにします。

Live Cardは以下のような仕組みになっています。

http://developers.google.com/glass/images/diagrams/live-card-service.png

Glassではアプリ一覧が並ぶUIの事をTimelineと呼びます。

Timeline からアプリのサービスが起動し、サービスでLive Cardを生成しコンテンツの描画を行います。

HelloWorldを作ってみた


Timerサンプルを元に作成したHelloWorldのプロジェクト一式はこちら




重要なのはTimerServiceのonStartCommand()で、それ以外はAndroidと全く同じです。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (mLiveCard == null) {
        //LiveCardを生成したい
        mLiveCard = mTimelineManager.createLiveCard(LIVE_CARD_TAG);

        //レンダリング用Drawerを追加したい
        mLiveCard.setDirectRenderingEnabled(true).getSurfaceHolder().addCallback(mTimerDrawer);
        
        //Menu用Activityの生成と追加をしたい
        Intent menuIntent = new Intent(this, MenuActivity.class);
        menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        mLiveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent, 0));

        //LiveCardを表示したい
        mLiveCard.publish(PublishMode.REVEAL);
    } else {
        // TODO(alainv): Jump to the LiveCard when API is available.
    }

    return START_STICKY;
}


尚、Cardを使わずAndroidと同様にActivityのみでアプリを構築する方法もあります。

しかしこの場合、そのままではTimelineからアプリを起動することができない為、アプリを起動する為だけのGlassアプリを用意する必要があります。これに関してはまた別の機会に書きます。

Glassの開発難易度


残念ながら現時点ではGlass用のシミュレータはありません。実機が無いとアプリのテストができない為、早急なシミュレータ環境の提供を期待するばかりです。

コードを書く事だけを見れば、Cardの概念さえ理解すれば後はAndroidとほとんど同じである為、Androidアプリ開発経験者はスムーズに開発を行うことができるでしょう。

しかし、実際にGlassを身につけるとよくわかるのですが、この最低限のアプリケーションでも、起動すると本体が非常に熱くなり、継続した装着が困難になります。

Glassで実用的なアプリケーションを構築する為には高度な省エネのスキルが要求されることでしょう。

しかし、Glassはソースコードが公開されていません。その為、基本的に Java 層で省エネを実現する必要があります。

実験的なアプリケーションはAndroidの延長線上で作れるものの、現時点のGlassの性能で実用的なアプリケーションをFixする為には非常に高度な開発スキルが求められると考えます。

Java で省エネって、アメ車に低燃費を求めるようなもんですよね




GDKでHelloWorldを作ってみる



Google からGlass Development Kit(以後GDK)が発表されてしばらく経ちました。

合わせて開発者用Glassの販売も行われ、今後市場投入に向けての動きが活発になることが予想されます。

しかしこの開発者用Glass、2014年1月時点で日本からは購入することができません。

USAでも開発者向けの招待メールでしか購入ができないようになっています。

弊社は現地支社がある為、いくつか購入することができました。

Glassを使った開発ノウハウが徐々に溜まってきたので、GDKでHelloWorldを書く方法をお伝えします。



さて、まず一言。

HelloWorld を書くのにこんなに苦労したのは久しぶりでした

完成されたSDKであれば普通、HelloWorldというのはプロジェクトを新規作成すると自動的に生成されるスケルトンプロジェクトに、ちょちょいと追記するだけで簡単に作れるものなのですが、現在のGDK(Rev.2)にはスケルトンコードを出力する機能がありません

従って今回は、GDKの中に含まれるサンプルコードをリファクタリングしながらHelloWorldを作ります。

Google Glassの開発環境


Glassの開発環境は基本的にAndroidと同じで、IDEはEclipseを使うのが最も簡単でしょう。

Android SDK Managerから Android 4.0.3 > GDK を選択して開発環境をインストールします。

f:id:bs-android:20140110095919p:image:w640

HelloWorldを作ってみる


それではGDKに含まれるサンプルコードをリファクタリングしながらHelloWorldを作ってみます。

新規プロジェクト > Android Sample Project > GDK > Timer を選択します。最後の画面でプロジェクト名をHelloWorldに変えておきます。

f:id:bs-android:20140110095920p:image:w360

f:id:bs-android:20140110095921p:image:w360

f:id:bs-android:20140110095922p:image:w360

このサンプルはその名の通りタイマーアプリで、設定した時間をカウントダウンすることができます。

まず、アプリがどのような動作をするか確認します。

遷移図を作りました。

f:id:bs-android:20140110095924j:image:w640

Glassはタップによる文字入力ができませんので入力項目は全て選択式になります。従って、シンプルなアプリですが画面数はとても多くなる傾向にあります。

Timerサンプルを解析してみる


次はTimerサンプルのコードを見て行きます。

まずはManifestから。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.android.glass.sample.timer"
    android:versionCode="2"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="15" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_timer"
        android:label="@string/app_name" >

        <activity
            android:name="com.google.android.glass.sample.timer.MenuActivity"
            android:label="@string/app_name"
            android:theme="@style/MenuTheme"
            android:enabled="true" >
        </activity>

        <activity
            android:name="com.google.android.glass.sample.timer.SetTimerActivity"
            android:label="@string/app_name"
            android:enabled="true" >
        </activity>

        <activity
            android:name="com.google.android.glass.sample.timer.SelectValueActivity"
            android:label="@string/app_name"
            android:enabled="true" >
        </activity>

        <service
            android:name="com.google.android.glass.sample.timer.TimerService"
            android:icon="@drawable/ic_timer"
            android:label="@string/app_name"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
            </intent-filter>
            <meta-data
                android:name="com.google.android.glass.VoiceTrigger"
                android:resource="@xml/voice_trigger_start" />
        </service>

    </application>

</manifest>


Activity が三つにServiceが一つ宣言されています。

こんなに小さなアプリでActivityが三つもあるのは何故か?

Glassでは基本的にActivityはコンテンツを描画する目的では無くメニューを表示する目的で使われます。従って、メニュー(設定項目や選択項目)が増えるとActivityがどんどん増えていく傾向があります。

Service内のmeta-dataは音声認識によるアプリ起動をサポートします。

次はソースコードを見て行きます。



  • MenuActivity.java

  • SelectValueActivity.java

  • SelectValueScrollAdapter.java

  • SetTimerActivity.java

  • SetTimerScrollAdapter.java

  • Timer.java

  • TimerDrawer.java

  • TimerService.java

  • TimerView.java

この中で最低限必要なクラスは以下です。



  • MenuActivity.java

  • TimerDrawer.java

  • TimerService.java

一つのGlassアプリには必ず一つのサービスが必要です。

サービスである為、アプリを終了する為のメニューが必要となるでしょう。必然的にメニューを表示するActivityも一つは必要となります。

さっき、Activityはメニューを表示する為に使うと説明しました。では、肝心のコンテンツはどのように描画するか?

GlassではCardというAndroidには無い仕組みが有ります。

Cardとは


Androidでは一つのActivityで一画面を表現しますが、Glassでは一つのCardで一つの画面を表現することができます。

CardにはStatic CardLive Cardの二種類があり、画面の更新頻度に応じて使い分けるとDocには書かれています。

TimerサンプルはLive Cardを利用している為、今回はLive Cardを使うことにします。

Live Cardは以下のような仕組みになっています。

http://developers.google.com/glass/images/diagrams/live-card-service.png

Glassではアプリ一覧が並ぶUIの事をTimelineと呼びます。

Timeline からアプリのサービスが起動し、サービスでLive Cardを生成しコンテンツの描画を行います。

HelloWorldを作ってみた


Timerサンプルを元に作成したHelloWorldのプロジェクト一式はこちら




重要なのはTimerServiceのonStartCommand()で、それ以外はAndroidと全く同じです。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (mLiveCard == null) {
        //LiveCardを生成したい
        mLiveCard = mTimelineManager.createLiveCard(LIVE_CARD_TAG);

        //レンダリング用Drawerを追加したい
        mLiveCard.setDirectRenderingEnabled(true).getSurfaceHolder().addCallback(mTimerDrawer);
        
        //Menu用Activityの生成と追加をしたい
        Intent menuIntent = new Intent(this, MenuActivity.class);
        menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        mLiveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent, 0));

        //LiveCardを表示したい
        mLiveCard.publish(PublishMode.REVEAL);
    } else {
        // TODO(alainv): Jump to the LiveCard when API is available.
    }

    return START_STICKY;
}


尚、Cardを使わずAndroidと同様にActivityのみでアプリを構築する方法もあります。

しかしこの場合、そのままではTimelineからアプリを起動することができない為、アプリを起動する為だけのGlassアプリを用意する必要があります。これに関してはまた別の機会に書きます。

Glassの開発難易度


残念ながら現時点ではGlass用のシミュレータはありません。実機が無いとアプリのテストができない為、早急なシミュレータ環境の提供を期待するばかりです。

コードを書く事だけを見れば、Cardの概念さえ理解すれば後はAndroidとほとんど同じである為、Androidアプリ開発経験者はスムーズに開発を行うことができるでしょう。

しかし、実際にGlassを身につけるとよくわかるのですが、この最低限のアプリケーションでも、起動すると本体が非常に熱くなり、継続した装着が困難になります。

Glassで実用的なアプリケーションを構築する為には高度な省エネのスキルが要求されることでしょう。

しかし、Glassはソースコードが公開されていません。その為、基本的に Java 層で省エネを実現する必要があります。

実験的なアプリケーションはAndroidの延長線上で作れるものの、現時点のGlassの性能で実用的なアプリケーションをFixする為には非常に高度な開発スキルが求められると考えます。

Java で省エネって、アメ車に低燃費を求めるようなもんですよね




Related Posts Plugin for WordPress, Blogger...