2014年3月20日木曜日



f:id:bs-android:20140319172604p:image

早くも発売が待ち遠しいAndroid Wearの端末ですが、端末を買ってから環境を整えていたら開発者として楽しめません。

エミュレータを使って開発ができるので環境構築手順を紹介します。

Android Wear Developer Preview 開発環境構築



f:id:bs-android:20140319172604p:image

早くも発売が待ち遠しいAndroid Wearの端末ですが、端末を買ってから環境を整えていたら開発者として楽しめません。

エミュレータを使って開発ができるので環境構築手順を紹介します。



f:id:bs-android:20140319135838j:image

2週間近く前にGoogleのSundar Pichai氏がSXSWのイベントでAndroidのウェアラブル機器のSDKをリリースするという話をしていたのですが、宣言通りに開発者向けプレビュー版のSDKが本日公開されました。

公式ブログでのAndroid Wear発表

Android Wear開発者向けサイト

Android Wearとは


Android WearとはAndroid搭載スマートフォンと連携して動作するウェアラブルデバイスのことを指すようです。

現段階では腕時計だけが対象のようですが、今後他のウェアラブル機器にも広げていくとのこと。

音声でのテキスト入力、タッチパネルでの操作が可能なようです。

詳細なハードウェア仕様はまだ公開されていません。




恐らく6/25-6/26にサンフランシスコで開催されるGoogle I/O 2014でデバイスがお目見えすることになると思います。




モトローラが夏にAndroid Wear端末Moto 360を発売すると発表しているので恐らくこのモデルがGoogle I/O参加者に配布されることになるのではないかと予想しています。

まずは利用シーンの紹介動画。


D

開発者向け動画


D

下の画像は動画から抜き出したものですが、Google Nowで使える機能がほとんど使えるようです。天気予報、経路検索、音声入力でHangoutでテキストチャットもできている模様。


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

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

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

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

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

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

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

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


UIの動作イメージはこんな感じです。

画面が小さいので基本操作はスワイプ。音声入力にも対応しています。

「Ok google」と話しかけると、そこからアプリとインターネットへの道が開きます。


f:id:bs-android:20140319153819g:image




f:id:bs-android:20140319153820g:image




f:id:bs-android:20140319154729g:image


まずは概要だけお届けしましたが、開発者視点の記事を随時更新していきますのでお楽しみに。







ちなみにシンクロニシティなのかどうかわかりませんが、偶然にも(?)2日ほど前にTizen陣営からもTizen Software Developer Kit for Wearablesというスマートウォッチ向けのSDKがリリースされています。




[コラム] ウェアラブル機器開発の本命、Android Wear登場



f:id:bs-android:20140319135838j:image

2週間近く前にGoogleのSundar Pichai氏がSXSWのイベントでAndroidのウェアラブル機器のSDKをリリースするという話をしていたのですが、宣言通りに開発者向けプレビュー版のSDKが本日公開されました。

公式ブログでのAndroid Wear発表

Android Wear開発者向けサイト

Android Wearとは


Android WearとはAndroid搭載スマートフォンと連携して動作するウェアラブルデバイスのことを指すようです。

現段階では腕時計だけが対象のようですが、今後他のウェアラブル機器にも広げていくとのこと。

音声でのテキスト入力、タッチパネルでの操作が可能なようです。

詳細なハードウェア仕様はまだ公開されていません。




恐らく6/25-6/26にサンフランシスコで開催されるGoogle I/O 2014でデバイスがお目見えすることになると思います。




モトローラが夏にAndroid Wear端末Moto 360を発売すると発表しているので恐らくこのモデルがGoogle I/O参加者に配布されることになるのではないかと予想しています。

まずは利用シーンの紹介動画。


D

開発者向け動画


D

下の画像は動画から抜き出したものですが、Google Nowで使える機能がほとんど使えるようです。天気予報、経路検索、音声入力でHangoutでテキストチャットもできている模様。


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

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

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

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

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

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

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

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


UIの動作イメージはこんな感じです。

画面が小さいので基本操作はスワイプ。音声入力にも対応しています。

「Ok google」と話しかけると、そこからアプリとインターネットへの道が開きます。


f:id:bs-android:20140319153819g:image




f:id:bs-android:20140319153820g:image




f:id:bs-android:20140319154729g:image


まずは概要だけお届けしましたが、開発者視点の記事を随時更新していきますのでお楽しみに。







ちなみにシンクロニシティなのかどうかわかりませんが、偶然にも(?)2日ほど前にTizen陣営からもTizen Software Developer Kit for Wearablesというスマートウォッチ向けのSDKがリリースされています。




2014年2月20日木曜日



Glassを身につけている人の視線(カメラプレビュー)をリアルタイムに共有できたらとても便利と思いませんか?

更にお互いに何かのアクションをやりとりできたらどんなに素敵でしょう。さまざまな仕事やエンターテイメントに応用できるはずです。

ということで、Glass の視線をiPadで共有し、ついでに、iPadからGlassに対して指示を送るサンプルを作ってみました。「ここを見て!」という指示が飛ぶようにします。



アプリの流れは以下のようになります。


GoogleGlassの視線(カメラプレビュー)をiPad でリアルタイムに共有して、かつ、指示を送ってみる その一



Glassを身につけている人の視線(カメラプレビュー)をリアルタイムに共有できたらとても便利と思いませんか?

更にお互いに何かのアクションをやりとりできたらどんなに素敵でしょう。さまざまな仕事やエンターテイメントに応用できるはずです。

ということで、Glass の視線をiPadで共有し、ついでに、iPadからGlassに対して指示を送るサンプルを作ってみました。「ここを見て!」という指示が飛ぶようにします。



アプリの流れは以下のようになります。


2014年2月14日金曜日



以前GDKでActivityを多様することは本体の発熱量が高くなるに少し触れましたが、今回はその発熱対策として放熱板の取り付けを行ってみました。

元々Google Glassには既存で放熱板が取り付けられています。

しかしコストの高いアプリを作成し、動作を続けるとタップやスワイプなどを行う右側部分(装着時)のフレームの発熱が非常に高くなることがわかりました。


f:id:bs-android:20140213193033j:image:w360



※ピンク:既存の耐熱板。Glassフレームを囲うように装着してある。

 赤 :発熱が最も高い部分。今回はここに自作の耐熱板を装着する。




少し温かくなる程度であれば問題ないのですが、カメラ機能を使い続けるようなコストの高いアプリを動作させ続けると、Glassをかけ続けることも辛いほどの発熱量となります。

そこで既存の放熱板だけでは不足な発熱の対策としてオリジナルの放熱板を取り付けることを試みました。




用意したもの




  • 熱伝導性シリコン

  • 熱伝導性接着剤

  • コイン

  • プラスチックの線

  • ハサミ

  • ペンチ

f:id:bs-android:20140213193034j:image:w360







手順


1)シリコンを発熱対策を行いたいフレームのサイズに合わせてカットし、熱伝導性の接着剤を使い重ね合わせます。

f:id:bs-android:20140213193035j:image:w360




2)更に放熱度をあげるため、重ねたシリコンの間にコインを挟みます。

f:id:bs-android:20140213193036j:image:w360




3)2)で作成したものをGlassの放熱を行いたい部分に装着します。

このとき、放熱板とGlassに隙間ができると放熱効果が下がるため、しっかり密着させることが重要。

f:id:bs-android:20140213193037j:image:w360







装着イメージ


f:id:bs-android:20140213193038j:image:w360

放熱板を装着したことによる違和感は特に気にならず。







成果


オリジナルの放熱板を取り付けることにより、以前に感じていた発熱を抑えることができました。

またカメラビューを使い続けるようなアプリをGlassで動作させ続けた際の動作時間を以前の約倍近くまで延ばすことができました。







今回苦労した点


Glassに放熱板の密着度を意識しながら取り付けたことぐらいです。

ですが、これが重要です!!!!




今回の放熱板の取り付けにより発熱対策は行いましたが、より多様な機能を搭載したアプリを開発するには設計段階からの省エネ対策が必要となります。




[Tips] Google Glassの発熱対策



以前GDKでActivityを多様することは本体の発熱量が高くなるに少し触れましたが、今回はその発熱対策として放熱板の取り付けを行ってみました。

元々Google Glassには既存で放熱板が取り付けられています。

しかしコストの高いアプリを作成し、動作を続けるとタップやスワイプなどを行う右側部分(装着時)のフレームの発熱が非常に高くなることがわかりました。


f:id:bs-android:20140213193033j:image:w360



※ピンク:既存の耐熱板。Glassフレームを囲うように装着してある。

 赤 :発熱が最も高い部分。今回はここに自作の耐熱板を装着する。




少し温かくなる程度であれば問題ないのですが、カメラ機能を使い続けるようなコストの高いアプリを動作させ続けると、Glassをかけ続けることも辛いほどの発熱量となります。

そこで既存の放熱板だけでは不足な発熱の対策としてオリジナルの放熱板を取り付けることを試みました。




用意したもの




  • 熱伝導性シリコン

  • 熱伝導性接着剤

  • コイン

  • プラスチックの線

  • ハサミ

  • ペンチ

f:id:bs-android:20140213193034j:image:w360







手順


1)シリコンを発熱対策を行いたいフレームのサイズに合わせてカットし、熱伝導性の接着剤を使い重ね合わせます。

f:id:bs-android:20140213193035j:image:w360




2)更に放熱度をあげるため、重ねたシリコンの間にコインを挟みます。

f:id:bs-android:20140213193036j:image:w360




3)2)で作成したものをGlassの放熱を行いたい部分に装着します。

このとき、放熱板とGlassに隙間ができると放熱効果が下がるため、しっかり密着させることが重要。

f:id:bs-android:20140213193037j:image:w360







装着イメージ


f:id:bs-android:20140213193038j:image:w360

放熱板を装着したことによる違和感は特に気にならず。







成果


オリジナルの放熱板を取り付けることにより、以前に感じていた発熱を抑えることができました。

またカメラビューを使い続けるようなアプリをGlassで動作させ続けた際の動作時間を以前の約倍近くまで延ばすことができました。







今回苦労した点


Glassに放熱板の密着度を意識しながら取り付けたことぐらいです。

ですが、これが重要です!!!!




今回の放熱板の取り付けにより発熱対策は行いましたが、より多様な機能を搭載したアプリを開発するには設計段階からの省エネ対策が必要となります。




2014年2月13日木曜日


2014年2月の日本アンドロイドの会定例会に参加してきました。

https://www.android-group.jp/event/event28.html

iBeaconとはどんなもので、アンドロイドで実現する場合に注意すべきことは何かなどを、この方面で活躍されている方を招いて勉強するという内容でした。

まず、今度の2/15、16に会津でBLEハッカソンを企画されている、Aka Beacon で有名なGClue の佐々木陽氏が、iBeacon とは、UUID、Major、Minor でビーコンを区別し、Immediate/Near/Far/Unknown などの近さが取得できるものですよ、ということを自作したデバイスを使ってデモを行いながら、非常に軽やかに説明されました。

また、iOSのバックグラウンド処理についても触れて、アプリがバックグラウンドにいてもRegion IN/OUTのイベントを受信でき、15秒間は動作可能ということも述べられていました。結局、もっとバックグラウンド動作を伸ばす方法はあるみたいですが…。

アンドロイドは、各アプリがビーコンを監視する部分を独自でもつため、ビーコンを利用するアプリが立ち上がるほど、電力消費が大きくなるとのこと。対して、iOSは、フレームワーク部分がビーコンの監視を行ってくれているので、ビーコンを使うアプリがたくさんいても省電力になっているとのこと。だから、アンドロイドでもビーコンを扱うサービスを作り、省電力な設計を行う必要があるとおっしゃっていました。

あとは、エコシステム、Appcessoryを中心とする最近のビジネス状況について、BLEデバイスのモジュール化のベンチャーが増えていることなどを説明してくれました。

続いて、Applixで研究開発をされている日向さんがビーコンの電波特性について、非常にわかりやすく解説してくれました。屋内測位をやっていると、電波特性というものに敏感になるもので、なんでこんなに状況によって電波強度がかわるのか深く知りたくなってきます。日向さんの調べたところによると、床や壁などに当たって跳ね返ってくる反射波との干渉により、場所によって電波の強弱が変わってしまうということです。また、電波強度と距離の関係式も、2、3mくらいまでなら大体合っているが、距離が遠くなるに連れて、実際の値とのずれが大きくなってくるとのこと。屋内測位をやったときもFarのビーコンは無視すると非常にうまく行きましたから、納得です。日向さんの考えでは、RSSIからもとめる距離の精度も対数をとった値なら実用に耐えられるのでは、とのこと。

あとのお二人は、iBeaconを使った事例でした。

元頓知ドットさんのおでかけスクラップサービス"tab"は、失敗事例などいくつか紹介しており、非常に参考になりました。

残念ながら、帰阪するため参加できたのはここまででした。

iBeaconでブームとなったBLEの流れですが、アンドロイドでちゃんとしたサービスが展開されるのはまだまだ先なのかなという印象を受けました。

[コラム] 日本アンドロイドの会2月定例会に参加してきました。


2014年2月の日本アンドロイドの会定例会に参加してきました。

https://www.android-group.jp/event/event28.html

iBeaconとはどんなもので、アンドロイドで実現する場合に注意すべきことは何かなどを、この方面で活躍されている方を招いて勉強するという内容でした。

まず、今度の2/15、16に会津でBLEハッカソンを企画されている、Aka Beacon で有名なGClue の佐々木陽氏が、iBeacon とは、UUID、Major、Minor でビーコンを区別し、Immediate/Near/Far/Unknown などの近さが取得できるものですよ、ということを自作したデバイスを使ってデモを行いながら、非常に軽やかに説明されました。

また、iOSのバックグラウンド処理についても触れて、アプリがバックグラウンドにいてもRegion IN/OUTのイベントを受信でき、15秒間は動作可能ということも述べられていました。結局、もっとバックグラウンド動作を伸ばす方法はあるみたいですが…。

アンドロイドは、各アプリがビーコンを監視する部分を独自でもつため、ビーコンを利用するアプリが立ち上がるほど、電力消費が大きくなるとのこと。対して、iOSは、フレームワーク部分がビーコンの監視を行ってくれているので、ビーコンを使うアプリがたくさんいても省電力になっているとのこと。だから、アンドロイドでもビーコンを扱うサービスを作り、省電力な設計を行う必要があるとおっしゃっていました。

あとは、エコシステム、Appcessoryを中心とする最近のビジネス状況について、BLEデバイスのモジュール化のベンチャーが増えていることなどを説明してくれました。

続いて、Applixで研究開発をされている日向さんがビーコンの電波特性について、非常にわかりやすく解説してくれました。屋内測位をやっていると、電波特性というものに敏感になるもので、なんでこんなに状況によって電波強度がかわるのか深く知りたくなってきます。日向さんの調べたところによると、床や壁などに当たって跳ね返ってくる反射波との干渉により、場所によって電波の強弱が変わってしまうということです。また、電波強度と距離の関係式も、2、3mくらいまでなら大体合っているが、距離が遠くなるに連れて、実際の値とのずれが大きくなってくるとのこと。屋内測位をやったときもFarのビーコンは無視すると非常にうまく行きましたから、納得です。日向さんの考えでは、RSSIからもとめる距離の精度も対数をとった値なら実用に耐えられるのでは、とのこと。

あとのお二人は、iBeaconを使った事例でした。

元頓知ドットさんのおでかけスクラップサービス"tab"は、失敗事例などいくつか紹介しており、非常に参考になりました。

残念ながら、帰阪するため参加できたのはここまででした。

iBeaconでブームとなったBLEの流れですが、アンドロイドでちゃんとしたサービスが展開されるのはまだまだ先なのかなという印象を受けました。

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月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 CardとLive 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 CardとLive 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 で省エネって、アメ車に低燃費を求めるようなもんですよね




2013年12月21日土曜日




今回は、あまり余所のブログでは取り上げられていない領域識別子(identifier)に注目してみた。

CLBeaconRegionオブジェクトの生成時に指定するidentifier(日本語で言うと、識別子)は、領域の識別子である。これはそのアプリケーション内で自由に決められるものである。

CLBeaconRegionオブジェクトの初期化処理(initWith...)には、次の種類がある。

  • - (id)initWithProximityUUID:(NSUUID *)proximityUUID identifier:(NSString *)identifier;
  • - (id)initWithProximityUUID:(NSUUID *)proximityUUID major:(CLBeaconMajorValue)major identifier:(NSString *)identifier;
  • - (id)initWithProximityUUID:(NSUUID *)proximityUUID major:(CLBeaconMajorValue)major minor:(CLBeaconMinorValue)minor identifier:(NSString *)identifier;

したがって、識別子をつけられる対象は、次のような組み合わせだけである。

組み合わせ

  • proximityUUID
  • proximityUUID、Major
  • proximityUUID、Major、Minor


ここからわかること、および、実際に動かしてわかったことがある:

1. 同じUUIDを持つデバイスが複数あるときに、3階層のグルーピングが可能である

2. 異なる組み合わせには、同じ識別子を付けられない
(実際、同じ識別子で異なるUUIDのCLBeaconRegionオブジェクトを作ろうとすると、後から作ったオブジェクトで上書きされてしまう)

3. 同じ組み合わせに対して、異なる識別子が付けられる

2つ目はあまり意識されていないところだと思うが、重要である。例えば、いろんなメーカーから購入したiBeaconデバイスを寄せ集めて、ひとつの領域を監視したいとする。しかし、そのようなiBeaconデバイスの中には、UUIDが予め決められていて、購入者が変更できないものもあるかもしれない。そうなると、これらのデバイスすべてを、同じ領域を表すためには使えないことになる。(たいていのiBeaconは、購入後もアプリケーションからUUIDが変更できるようになっている。)

この識別子、使い方によっては非常におもしろいことができる。ひとつのiBeaconに近づいたとか離れたとかといった使い方は基本中の基本で、本質的な使い方は、文字通り、領域にはいったかどうかである。例えば、同じUUID、MajorをもつiBeaconが、下図のように輪っかになっている場合は、そのUUIDとMajorの組に対して付けた識別子は、その赤い輪っかの領域を表す領域識別子として使用することができる。

3つ目の性質に着目すれば、同じビーコンでも異なる領域として使用可能なので、次図のように同じビーコンの配置に対して、いくつもの異なる領域が考えられる。(ただし、この場合、異なるビーコンには同じ識別子が使えないので、識別子自体をURLのようなドメイン構造にする工夫が必要となる。図では、aグループ、bグループ、cグループとしている。どのビーコンも2つの領域に属している。)

    


これは、iBeaconを社会インフラとして考えた場合、非常に柔軟に扱えることを意味している。たとえば、ある区域にiBeaconを均等に配置しておき、適切な識別子を与えただけで、あるルートを表す領域が取得でき、iBeaconの電波を拾って道案内を行うなど、低コストなナビゲーションシステムが実現できる。

例えば、次の図のように大阪駅構内にiBeaconを配置しておく、御堂筋北口から中央きっぷ売り場への道順を表す領域(赤枠)や、御堂筋南口から高速バスターミナルまでの道順を表す領域(青枠)など、おなじiBeaconインフラに対して、ことなる領域を定義することが可能となる。




領域の識別子をうまく使うことが、柔軟で低コストなiBeaconサービスを提供するための必須条件であることは間違いないだろう。


[Tips] iBeaconの領域識別子とは?




今回は、あまり余所のブログでは取り上げられていない領域識別子(identifier)に注目してみた。

CLBeaconRegionオブジェクトの生成時に指定するidentifier(日本語で言うと、識別子)は、領域の識別子である。これはそのアプリケーション内で自由に決められるものである。

CLBeaconRegionオブジェクトの初期化処理(initWith...)には、次の種類がある。

  • - (id)initWithProximityUUID:(NSUUID *)proximityUUID identifier:(NSString *)identifier;
  • - (id)initWithProximityUUID:(NSUUID *)proximityUUID major:(CLBeaconMajorValue)major identifier:(NSString *)identifier;
  • - (id)initWithProximityUUID:(NSUUID *)proximityUUID major:(CLBeaconMajorValue)major minor:(CLBeaconMinorValue)minor identifier:(NSString *)identifier;

したがって、識別子をつけられる対象は、次のような組み合わせだけである。

組み合わせ

  • proximityUUID
  • proximityUUID、Major
  • proximityUUID、Major、Minor


ここからわかること、および、実際に動かしてわかったことがある:

1. 同じUUIDを持つデバイスが複数あるときに、3階層のグルーピングが可能である

2. 異なる組み合わせには、同じ識別子を付けられない
(実際、同じ識別子で異なるUUIDのCLBeaconRegionオブジェクトを作ろうとすると、後から作ったオブジェクトで上書きされてしまう)

3. 同じ組み合わせに対して、異なる識別子が付けられる

2つ目はあまり意識されていないところだと思うが、重要である。例えば、いろんなメーカーから購入したiBeaconデバイスを寄せ集めて、ひとつの領域を監視したいとする。しかし、そのようなiBeaconデバイスの中には、UUIDが予め決められていて、購入者が変更できないものもあるかもしれない。そうなると、これらのデバイスすべてを、同じ領域を表すためには使えないことになる。(たいていのiBeaconは、購入後もアプリケーションからUUIDが変更できるようになっている。)

この識別子、使い方によっては非常におもしろいことができる。ひとつのiBeaconに近づいたとか離れたとかといった使い方は基本中の基本で、本質的な使い方は、文字通り、領域にはいったかどうかである。例えば、同じUUID、MajorをもつiBeaconが、下図のように輪っかになっている場合は、そのUUIDとMajorの組に対して付けた識別子は、その赤い輪っかの領域を表す領域識別子として使用することができる。

3つ目の性質に着目すれば、同じビーコンでも異なる領域として使用可能なので、次図のように同じビーコンの配置に対して、いくつもの異なる領域が考えられる。(ただし、この場合、異なるビーコンには同じ識別子が使えないので、識別子自体をURLのようなドメイン構造にする工夫が必要となる。図では、aグループ、bグループ、cグループとしている。どのビーコンも2つの領域に属している。)

    


これは、iBeaconを社会インフラとして考えた場合、非常に柔軟に扱えることを意味している。たとえば、ある区域にiBeaconを均等に配置しておき、適切な識別子を与えただけで、あるルートを表す領域が取得でき、iBeaconの電波を拾って道案内を行うなど、低コストなナビゲーションシステムが実現できる。

例えば、次の図のように大阪駅構内にiBeaconを配置しておく、御堂筋北口から中央きっぷ売り場への道順を表す領域(赤枠)や、御堂筋南口から高速バスターミナルまでの道順を表す領域(青枠)など、おなじiBeaconインフラに対して、ことなる領域を定義することが可能となる。




領域の識別子をうまく使うことが、柔軟で低コストなiBeaconサービスを提供するための必須条件であることは間違いないだろう。


2013年12月19日木曜日


ビーコンって何を考えてるんでしょうね?聞いてみたいと思いませんか?

と、唐突に書き始めてしまいました。開発のやりすぎで頭がおかしくなったのでしょうか? いえ、そうではなくて、今回は、ビーコンの近さに応じて、再生する音の大きさを変えてみようというお話です。でも、それはまるで、ビーコンが「近づいたよ〜」「遠のいたよ〜」と言っているように聞こえるので、結構、たのしいのです。(実際には、電波が強くなったよ〜、ですが。。。)

では、さっそく作って行きます。

1.ボタンを押したら、曲を再生する、というところまでを作ります。xcodeのプロジェクト(BeaconVoiceという名前にしました)を作成し、AVFoundation.frameworkを追加します。また、"sounds"というフォルダを作成し、そこに用意したMP3ファイルをおきます(図参照)。


画面はこんな感じ(図参照)。

しょぼいですね〜。音量と電波受信強度のラベルだけはつけときました。

ソースコードは、こんな感じです。(STARTボタンを押すと、曲が再生されて、もう一度押すと、停止する、という動きにしてます。)

ViewController.m


はい、では、次行きましょう。

2.CoreLocation.frameworkをセットして、ビーコンを受信できるようにします。この辺りは、このブログで何回か紹介してますので、コードだけ載っけます。

ViewController.hのプロパティ

ViewController.mのViewDidLoadの中

ViewController.mの中のLocationManagerのデリゲート処理

はい、できました!

では、実行の様子をお聴きください...。


ああ、残念です。音声がお伝えできない。

音量は、0.0〜1.0までの値です。RSSIの値は、-90〜-58にしています。つまり、この画像では、最大値になっています。iPhoneもビーコンもスクリーンショットを撮った開発環境のPCに接続しているので無理ないですね。では、ちょっとビーコンを遠くへ離してみます。

か、かすかに音が聞こえます。そして、ときどき、ゴハッって感じで音が大きくなります。まるで溺れかけの人のように。おおお、いい感じでビーコンの声が聞こえてますね。

まとめ

もともとビーコンの電波がどれくらい不安定なのか知りたく思い、音で体感できるようにしたかっただけなのですが、なかなかいい感じで確認できることがわかりました。例えるなら、トンネルに入ったときのラジオの音でしょうか?でも、ビーコンに近いときは、安定して聴けます。

応用として、ある範囲では、クラシック、ある範囲では、ジャズなど、特定の範囲でだけ特定の音楽が聴けるとかのサービスができそうですね。

(おわり)

ビーコンの声を聞いてみよう!


ビーコンって何を考えてるんでしょうね?聞いてみたいと思いませんか?

と、唐突に書き始めてしまいました。開発のやりすぎで頭がおかしくなったのでしょうか? いえ、そうではなくて、今回は、ビーコンの近さに応じて、再生する音の大きさを変えてみようというお話です。でも、それはまるで、ビーコンが「近づいたよ〜」「遠のいたよ〜」と言っているように聞こえるので、結構、たのしいのです。(実際には、電波が強くなったよ〜、ですが。。。)

では、さっそく作って行きます。

1.ボタンを押したら、曲を再生する、というところまでを作ります。xcodeのプロジェクト(BeaconVoiceという名前にしました)を作成し、AVFoundation.frameworkを追加します。また、"sounds"というフォルダを作成し、そこに用意したMP3ファイルをおきます(図参照)。


画面はこんな感じ(図参照)。

しょぼいですね〜。音量と電波受信強度のラベルだけはつけときました。

ソースコードは、こんな感じです。(STARTボタンを押すと、曲が再生されて、もう一度押すと、停止する、という動きにしてます。)

ViewController.m


はい、では、次行きましょう。

2.CoreLocation.frameworkをセットして、ビーコンを受信できるようにします。この辺りは、このブログで何回か紹介してますので、コードだけ載っけます。

ViewController.hのプロパティ

ViewController.mのViewDidLoadの中

ViewController.mの中のLocationManagerのデリゲート処理

はい、できました!

では、実行の様子をお聴きください...。


ああ、残念です。音声がお伝えできない。

音量は、0.0〜1.0までの値です。RSSIの値は、-90〜-58にしています。つまり、この画像では、最大値になっています。iPhoneもビーコンもスクリーンショットを撮った開発環境のPCに接続しているので無理ないですね。では、ちょっとビーコンを遠くへ離してみます。

か、かすかに音が聞こえます。そして、ときどき、ゴハッって感じで音が大きくなります。まるで溺れかけの人のように。おおお、いい感じでビーコンの声が聞こえてますね。

まとめ

もともとビーコンの電波がどれくらい不安定なのか知りたく思い、音で体感できるようにしたかっただけなのですが、なかなかいい感じで確認できることがわかりました。例えるなら、トンネルに入ったときのラジオの音でしょうか?でも、ビーコンに近いときは、安定して聴けます。

応用として、ある範囲では、クラシック、ある範囲では、ジャズなど、特定の範囲でだけ特定の音楽が聴けるとかのサービスができそうですね。

(おわり)

2013年12月16日月曜日



f:id:bs-android:20131215082308j:image

はじめに

GoogleGlassの新型(V2)の目玉の一つにイヤホン(Earbud)のサポートがあります。

このイヤホン、実は両耳タイプも存在しているのですが、Explore招待プログラムの時期には発売されておらず、なんとか新型の入手に成功できたものの、同時購入することができずに悔しい思いをされている方も多いのではないかと思います。また標準添付のイヤホンもGlassのロゴをあしらったお洒落なデザインで見た目はかなりクールなのですが、実際に使ってみると装着感がいまひとつで常時着けて使うのには残念な品物でした。

f:id:bs-android:20131215081637j:image:w360

f:id:bs-android:20131215081446j:image:w360

そこでGlassに自分好みのイヤホンを付けられるようにしてみましたので、その方法についてレポートいたします。


Google Glassの新機能をハックする



f:id:bs-android:20131215082308j:image

はじめに

GoogleGlassの新型(V2)の目玉の一つにイヤホン(Earbud)のサポートがあります。

このイヤホン、実は両耳タイプも存在しているのですが、Explore招待プログラムの時期には発売されておらず、なんとか新型の入手に成功できたものの、同時購入することができずに悔しい思いをされている方も多いのではないかと思います。また標準添付のイヤホンもGlassのロゴをあしらったお洒落なデザインで見た目はかなりクールなのですが、実際に使ってみると装着感がいまひとつで常時着けて使うのには残念な品物でした。

f:id:bs-android:20131215081637j:image:w360

f:id:bs-android:20131215081446j:image:w360

そこでGlassに自分好みのイヤホンを付けられるようにしてみましたので、その方法についてレポートいたします。




はじめに

飛行機を使った移動で一番困るのが到着時の荷物受け取り
いつまで待っても預けた荷物が出てこない、いやとっくの昔に出てしまったかも?、もしかしたらロストバゲット!?
流れるベルトコンベアを眺め続けながら、いつもこのような不安がよぎります・・・
今回はそんな悩みをiBeaconで解決してみたいと思います。

iBeaconで海外渡航を楽しく



はじめに

飛行機を使った移動で一番困るのが到着時の荷物受け取り
いつまで待っても預けた荷物が出てこない、いやとっくの昔に出てしまったかも?、もしかしたらロストバゲット!?
流れるベルトコンベアを眺め続けながら、いつもこのような不安がよぎります・・・
今回はそんな悩みをiBeaconで解決してみたいと思います。

2013年12月6日金曜日


※今回の記事は「〔番外編〕 電力測定ツールも自作してみよう」の続編です

今回は測定ツールの第2弾としてアプリケーション編を紹介いたします。


免責事項

この記事に書かれている内容は技術的な参考資料として記載しています
端末等の破損や作業上の事故について弊社および記事作成者は責任を持ちません
また設計上の品質についても保証を行っていませんので、作成時は各自で性能確認等を行うようにしてください。


1. 測定ツールの構成について

前回の記事である測定ツール自作編で作成したハードウェアは次のような構成になっていました。


今回の記事ではArduiono MEGA ADK側で動くスケッチとAndroidタブレットで動作するアプリを作成し、測定ツールで検出した電力値をAndroidタブレットに表示できるようにします。
・Arduino
 測定冶具で検出された電流信号をA/D変換しUSB-HOSTからAndroidタブレットにデータを送信
・Androidタブレット
 ADKプロトコルを使用して取得した測定値を画面に数値およびグラフ化して表示する

2.測定アプリ

今回作成したアプリは弊社内のニーズに基づき次のような機能を実装しました。
・ダミーバッテリの供給電圧
・現在の消費電流
・積算電力(積算電流)
・消費電流のグラフ

実際の表示画面はこのようになっています。


2-1. Arduinoのスケッチ

ADK2011(2012)のサンプルコードをベースに独自の機能を追加しました。
実際のコードについてはこちらを参照下さい スケッチ

・タイマー割り込みを使って1msecごとに電圧と電流のA/D変換
・取得した電流値を積算
・ADK経由でデータを送信

なおArduino上で実際の電圧/電流値に計算しようとすると処理時間が間に合わなくなることからAdruino側ではA/D変換とデータ保持のみを行い、実数化はAndroidアプリで行うようにしています。
被検対象となるAndroid端末のカーネルタイマーが1msecなので10倍の0.1msecごとに電流値を取ることができれば、より高精度な測定が可能となりますがアプリ動作の測定に絞るだけなら1msecでも十分評価できると思います。

<Tips> Android 4.1以降の端末でサンプルコードを使うには
公開されている初期のADKのソースコードはADK2011のみしか対応していないことからADK2012をサポートするAndroid4.1以降の端末ではADKを認識することができなくなりました。
その場合、次のようなパッチを当てると動作させることができます。
AndroidAccessory.cpp
bool AndroidAccessory::switchDevice(byte addr)
{
..
-    if (protocol == 1) {
+    if (protocol >= 1) {
        Serial.print("device supports protcol 1\n");
..
ただし今後のバージョンアップにてプロトコルの互換性が失われる場合がありますので使用にあたってはGoogleの動向をチェックするようにしてください

2-2. Androidアプリ

ADK2011のAPIを使い簡単なアプリケーションを作ってみました。
ADK経由でAdruionoからA/D変換値を取得し、アプリ側で電圧/電流/積算(Sum)に変換して表示します。また電流値をグラフ化して表示も行っています。
サンプルとしてアプリのソースコード添付しました ソースコード

Sum値は取得した電流値を積算したもので累積電力の目安として表示しています。
これがあると長時間に渡る消費電力を知ることができスリープ時の省電力を見るのに便利です。この値に電圧値を掛ければ電力値になりますが、今回アプリでは電圧を一定で測定しているので電流のみとしています。またもし表示を時間単位としたい場合はサンプリング時間を測りながら計算するように書き換えるととよいでしょう。

3.使用方法

・測定ツールと被検対象となる端末を接続してからACアダプタを接続します。
・ACアダプタからの給電が始まるとAndroidタブレットにADKのダイアログが表示されますのでOKボタンを押します。
・次にOFFボタンを押すとボタン表示がONに変わり測定が始まります。
・再度ONボタンを押すとOFFに戻り測定が中断します。スクリーンショットを取る場合に利用してください。
・Clearボタンは測定結果をクリアするときに使います、押すと積算値とグラフ時間軸がゼロに戻ります。

4. 少し特殊な使いかた

測定冶具基板に付いている半固定抵抗を回すとダミーバッテリの供給電圧を変えることができます。これによりバッテリ残量が少ないとき特有の挙動も見ることも可能です。電圧を可変させる際は Androidアプリ画面で表示している電圧値を見ながらバッテリ電圧範囲内でゆっくり可変させるようにして下さい。半固定抵抗は機械的接点で抵抗値を変動させているもののため、乱暴に回すと急激に電圧が変動し端末が破損する危険性があります。なお端末側で統計的に残量計算している機種が多いので反映するまでしばらく掛かる場合があります、その場合は一度再起動するとよいでしょう。

5. 今後の展開 -- 高機能版への進化

弊社ではこの測定ツールを進化させた商用版を準備しております。
本ブログで公開したものに比べてさらに次のような機能がパワーアップしています。
1. サンプリングの高速化
2. 取得データを収集サーバーへ転送
 サーバー側にデータを逐次送信することにより長期間の測定が可能になりました
3. 複数端末のデータ取得
 複数の測定ツールを同時使用することにより多くのデータを蓄積することができます
4. データの分析
 サーバー側で蓄積したデータを用いて統計的なデータ評価が可能となりました
 1台だけの評価に比べて試験環境による誤差が少なくなります

まとめ

今回で測定ツール自作編は終了となります。
ツールを自作することにより本ブログ開始時に使っていた機材に比べて小型軽量化され安価に消費電力が測れるようになりました。

蛇足ではありますが「あのスマホ」もダミーバッテリの作成を行い、端末の電力測定できるようにしました。弊社端末アプリ開発チームのところで重宝しております。



目的を絞ったツールを自作すれば測定器を揃えるよりも小型で安上がりに消費電力を確認することができることがご理解頂けたかと思います。
これで読者の方々のところでもツールを自作してみようという気風が高まれば幸いです。

ブランド戦略部 - 中村和貴

〔番外編〕 電力測定ツールも自作してみよう - アプリ編


※今回の記事は「〔番外編〕 電力測定ツールも自作してみよう」の続編です

今回は測定ツールの第2弾としてアプリケーション編を紹介いたします。


免責事項

この記事に書かれている内容は技術的な参考資料として記載しています
端末等の破損や作業上の事故について弊社および記事作成者は責任を持ちません
また設計上の品質についても保証を行っていませんので、作成時は各自で性能確認等を行うようにしてください。


1. 測定ツールの構成について

前回の記事である測定ツール自作編で作成したハードウェアは次のような構成になっていました。


今回の記事ではArduiono MEGA ADK側で動くスケッチとAndroidタブレットで動作するアプリを作成し、測定ツールで検出した電力値をAndroidタブレットに表示できるようにします。
・Arduino
 測定冶具で検出された電流信号をA/D変換しUSB-HOSTからAndroidタブレットにデータを送信
・Androidタブレット
 ADKプロトコルを使用して取得した測定値を画面に数値およびグラフ化して表示する

2.測定アプリ

今回作成したアプリは弊社内のニーズに基づき次のような機能を実装しました。
・ダミーバッテリの供給電圧
・現在の消費電流
・積算電力(積算電流)
・消費電流のグラフ

実際の表示画面はこのようになっています。


2-1. Arduinoのスケッチ

ADK2011(2012)のサンプルコードをベースに独自の機能を追加しました。
実際のコードについてはこちらを参照下さい スケッチ

・タイマー割り込みを使って1msecごとに電圧と電流のA/D変換
・取得した電流値を積算
・ADK経由でデータを送信

なおArduino上で実際の電圧/電流値に計算しようとすると処理時間が間に合わなくなることからAdruino側ではA/D変換とデータ保持のみを行い、実数化はAndroidアプリで行うようにしています。
被検対象となるAndroid端末のカーネルタイマーが1msecなので10倍の0.1msecごとに電流値を取ることができれば、より高精度な測定が可能となりますがアプリ動作の測定に絞るだけなら1msecでも十分評価できると思います。

<Tips> Android 4.1以降の端末でサンプルコードを使うには
公開されている初期のADKのソースコードはADK2011のみしか対応していないことからADK2012をサポートするAndroid4.1以降の端末ではADKを認識することができなくなりました。
その場合、次のようなパッチを当てると動作させることができます。
AndroidAccessory.cpp
bool AndroidAccessory::switchDevice(byte addr)
{
..
-    if (protocol == 1) {
+    if (protocol >= 1) {
        Serial.print("device supports protcol 1\n");
..
ただし今後のバージョンアップにてプロトコルの互換性が失われる場合がありますので使用にあたってはGoogleの動向をチェックするようにしてください

2-2. Androidアプリ

ADK2011のAPIを使い簡単なアプリケーションを作ってみました。
ADK経由でAdruionoからA/D変換値を取得し、アプリ側で電圧/電流/積算(Sum)に変換して表示します。また電流値をグラフ化して表示も行っています。
サンプルとしてアプリのソースコード添付しました ソースコード

Sum値は取得した電流値を積算したもので累積電力の目安として表示しています。
これがあると長時間に渡る消費電力を知ることができスリープ時の省電力を見るのに便利です。この値に電圧値を掛ければ電力値になりますが、今回アプリでは電圧を一定で測定しているので電流のみとしています。またもし表示を時間単位としたい場合はサンプリング時間を測りながら計算するように書き換えるととよいでしょう。

3.使用方法

・測定ツールと被検対象となる端末を接続してからACアダプタを接続します。
・ACアダプタからの給電が始まるとAndroidタブレットにADKのダイアログが表示されますのでOKボタンを押します。
・次にOFFボタンを押すとボタン表示がONに変わり測定が始まります。
・再度ONボタンを押すとOFFに戻り測定が中断します。スクリーンショットを取る場合に利用してください。
・Clearボタンは測定結果をクリアするときに使います、押すと積算値とグラフ時間軸がゼロに戻ります。

4. 少し特殊な使いかた

測定冶具基板に付いている半固定抵抗を回すとダミーバッテリの供給電圧を変えることができます。これによりバッテリ残量が少ないとき特有の挙動も見ることも可能です。電圧を可変させる際は Androidアプリ画面で表示している電圧値を見ながらバッテリ電圧範囲内でゆっくり可変させるようにして下さい。半固定抵抗は機械的接点で抵抗値を変動させているもののため、乱暴に回すと急激に電圧が変動し端末が破損する危険性があります。なお端末側で統計的に残量計算している機種が多いので反映するまでしばらく掛かる場合があります、その場合は一度再起動するとよいでしょう。

5. 今後の展開 -- 高機能版への進化

弊社ではこの測定ツールを進化させた商用版を準備しております。
本ブログで公開したものに比べてさらに次のような機能がパワーアップしています。
1. サンプリングの高速化
2. 取得データを収集サーバーへ転送
 サーバー側にデータを逐次送信することにより長期間の測定が可能になりました
3. 複数端末のデータ取得
 複数の測定ツールを同時使用することにより多くのデータを蓄積することができます
4. データの分析
 サーバー側で蓄積したデータを用いて統計的なデータ評価が可能となりました
 1台だけの評価に比べて試験環境による誤差が少なくなります

まとめ

今回で測定ツール自作編は終了となります。
ツールを自作することにより本ブログ開始時に使っていた機材に比べて小型軽量化され安価に消費電力が測れるようになりました。

蛇足ではありますが「あのスマホ」もダミーバッテリの作成を行い、端末の電力測定できるようにしました。弊社端末アプリ開発チームのところで重宝しております。



目的を絞ったツールを自作すれば測定器を揃えるよりも小型で安上がりに消費電力を確認することができることがご理解頂けたかと思います。
これで読者の方々のところでもツールを自作してみようという気風が高まれば幸いです。

ブランド戦略部 - 中村和貴
Related Posts Plugin for WordPress, Blogger...