2015年11月4日水曜日


▲[外部] appium_logo_final.eps より引用

■はじめに

自動化テストツールAppium、テストコードの記述言語としてRubyを用いたAndroidアプリケーションの自動テスト実施についての説明を行います。
Appiumはテスト対象アプリのapkファイルがあればソースコードが無くともテストスクリプトを書いてテストを実施することができるため、アプリケーションの受け入れテストに向いているとい。
この記事ではWindowsに環境を構築してサンプルコードを実行するまでを紹介します。


■環境構築前の事前準備

Appiumを起動しRubyで書いたテストコードを実行するためには、AppiumとRubyの他にインストールしなければいけないソフトウェアやその設定があります。Androidアプリケーションの開発を行っているのであれば必須と言えるものばかりのため、既に開発環境を構築出済みであれば不要です。


■Android SDK

▲[外部] Android Developers より引用

Appiumでは、テスト対象アプリケーションや補助アプリケーションのインストールやAppium Client LibrariesのAPIでADBコマンドを用いたり、補助アプリケーションをソースコードからビルドしたりします。このため、Android SDKを構成するいくつかのコンポーネントをインストールする必要があります。最低限必要なものは以下の2つです。
  • Android SDK Platform-tools
  • Android SDK Build-tools

Emulatorでの実行を考えているのであれば、ターゲットバージョンのSystem Imageも必要になります。

■Android SDKの環境変数

AppiumではAndroid SDKのインストール先を特定するためにAndroid SDK側の環境変数を参照しています。Android SDKのインストールする方法によっては自動的にセットされる場合もありますが、そうでない場合は別途セットするようにして下さい。
  • 変数名: ANDROID_HOME
  • 値: Android SDKのルートディレクトリのパス

■Java Development Kit 7/8

JavaはAppiumの実行の他、Android SDKに含まれるツールの実行にも必要です。WindowsであればJava Runtime Environment (JRE)のみでも動作するようですが、Android SDKのシステム要件であるJava Development Kit (JDK)をインストールしておくのが良いでしょう。


■環境構築

まずはWindowsにAppiumとRubyをインストールする方法を記載します。スクリーンショットはWindows 10のものを用いていますが、Windows 7でも同様の手順で構築可能です。


■Appiumのインストール

Appiumのインストールは、公式サイトからインストーラーをダウンロードし実行することで行います。

▲[外部] Android Developers より引用

ダウンロードしたzipファイルを展開しappium-installer.exeを実行、セットアップウィザードを起動します。あとは画面の指示に従い必要であれば設定を変更しインストールを行って下さい。

インストール完了後Appiumが起動すれば完了です。

■Rubyのインストール

WindowsでRubyの実行環境を構築する場合、Rubyの公式サイトでも紹介されているRubyInstaller for Windowsというサードパーティ製のインストーラーを用いるのが簡単です。

▲[外部] RubyInstaller for Windows より引用

RubyInstallerのサイトのダウンロードページからダウンロードを行うのですが、選択するバージョンには注意が必要です。
最新のRuby 2.2.x(執筆時点ではRuby 2.2.3)ではなく、その下にあるRuby 2.1.x(執筆時点ではRuby 2.1.7)をダウンロードして下さい。これは、Ruby 2.2.xだとテストコード実行時にエラーが発生してしまうためです。

▲[外部] RubyInstaller for Windows より引用

ダウンロードされた実行形式ファイルを実行しセットアップウィザード起動、画面の指示に従ってインストールを行います。

基本的にデフォルトの設定で問題ありませんが、[インストール先とオプションの指定]では[Ruby の実行ファイルへ環境変数 PATH を設定する]にチェックを入れておくと環境変数をセットする手間が省けるため便利です。

コマンドプロンプトで"ruby -v"と実行し、バージョンが表示されればOKです。

>ruby -v
ruby 2.1.7p400 (2015-08-18 revision 51632) [x64-mingw32]

■Rubyのライブラリ(gem)のインストール

Rubyではサードパーティ製のライブラリが"gem"という形式で公開されており、gemコマンドを使用してインストールすることができます。gemコマンドはRubyInstallerでRubyをインストールした際に組み込まれていますので、特にすることはありません。ここではRubyからAppiumを使用するためのライブラリ"appium_lib"をインストールします。
gemのインストールは簡単で、以下のように"gem install <gem名>"と実行するだけです。これによってappium_libと依存するgemがインストールされます。

>gem install appium_lib

これで環境構築は完了です。


■サンプルコードの実行

AppiumのサンプルコードはGitHubのappium/sample-codeリポジトリで公開されていますが、rubyのものはxUnitやRSpecといったテスティングフレームワークの利用が前提となっているようです。今回は最小限の環境構築に留めるためそれらは使用しません。apkファイルのみでもテストが可能な事を示すため、公開されているapkファイルを利用させてもらうようにします。

■準備

前述のリポジトリにある sample-code/apps/selendroid-test-app.apk をダウンロードし任意のパスにコピーします。
次にテキストエディタを用いて以下のコードを記述し、先ほどのapkファイルと同じ場所にsample.rbとして保存します。

# encoding: utf-8
require "appium_lib"

desired_caps = {
  caps: {
    platformName:  "Android",
    deviceName:    "Android Device",
    app:           "#{Dir.pwd}/selendroid-test-app.apk",
  }
}

driver = Appium::Driver.new(desired_caps).start_driver
Appium.promote_appium_methods Object

button_element = find_element(:id, "io.selendroid.testapp:id/visibleButtonTest")
button_element.click
sleep 3
text_element = find_element(:id, "io.selendroid.testapp:id/visibleTextView")
displayed_text = text_element.text
button_element.click
sleep 3
puts displayed_text

driver.quit

■実行

Appiumを起動し右上にある右向き三角ボタン(いわゆる再生ボタン)をクリックし、以下のような表示になるまで少し待ちます。

コマンドプロンプトから以下のようにしてサンプルコードを実行します。

>ruby sample.rb

テスト対象アプリケーションとAppiumがテストで使用するアプリケーションのインストール、テスト対象アプリケーションの起動が行われテストが実行されます。最終的にコマンドプロンプトに"Text is sometimes displayed"が表示されれば成功です。

■解説

Appium側の操作によってサーバープログラムが起動しています。PCに接続したデバイスに対して直接操作を行うのがこのサーバーで、テストスクリプトからはサーバーを介して画面の操作や情報の取得を行うことになります。
スクリプトの12行目でサーバーへの接続を行い、Appium::Driverクラスのインスタンスを取得しています。4〜9行目のdesired_capsはそのためのパラメーターです。
15〜22行目がテストの本体となっている部分で、詳細な説明は省きますが、テストアプリケーションの画面に表示されている[Display text view]ボタンをクリックし、表示されたテキスト"Text is sometimes displayed"を変数に保存、それをコマンドプロンプトへ出力する、といった事をしています。

Appium+RubyによるAndroidアプリの受け入れテスト(環境構築)


▲[外部] appium_logo_final.eps より引用

■はじめに

自動化テストツールAppium、テストコードの記述言語としてRubyを用いたAndroidアプリケーションの自動テスト実施についての説明を行います。
Appiumはテスト対象アプリのapkファイルがあればソースコードが無くともテストスクリプトを書いてテストを実施することができるため、アプリケーションの受け入れテストに向いているとい。
この記事ではWindowsに環境を構築してサンプルコードを実行するまでを紹介します。


■環境構築前の事前準備

Appiumを起動しRubyで書いたテストコードを実行するためには、AppiumとRubyの他にインストールしなければいけないソフトウェアやその設定があります。Androidアプリケーションの開発を行っているのであれば必須と言えるものばかりのため、既に開発環境を構築出済みであれば不要です。


■Android SDK

▲[外部] Android Developers より引用

Appiumでは、テスト対象アプリケーションや補助アプリケーションのインストールやAppium Client LibrariesのAPIでADBコマンドを用いたり、補助アプリケーションをソースコードからビルドしたりします。このため、Android SDKを構成するいくつかのコンポーネントをインストールする必要があります。最低限必要なものは以下の2つです。
  • Android SDK Platform-tools
  • Android SDK Build-tools

Emulatorでの実行を考えているのであれば、ターゲットバージョンのSystem Imageも必要になります。

■Android SDKの環境変数

AppiumではAndroid SDKのインストール先を特定するためにAndroid SDK側の環境変数を参照しています。Android SDKのインストールする方法によっては自動的にセットされる場合もありますが、そうでない場合は別途セットするようにして下さい。
  • 変数名: ANDROID_HOME
  • 値: Android SDKのルートディレクトリのパス

■Java Development Kit 7/8

JavaはAppiumの実行の他、Android SDKに含まれるツールの実行にも必要です。WindowsであればJava Runtime Environment (JRE)のみでも動作するようですが、Android SDKのシステム要件であるJava Development Kit (JDK)をインストールしておくのが良いでしょう。


■環境構築

まずはWindowsにAppiumとRubyをインストールする方法を記載します。スクリーンショットはWindows 10のものを用いていますが、Windows 7でも同様の手順で構築可能です。


■Appiumのインストール

Appiumのインストールは、公式サイトからインストーラーをダウンロードし実行することで行います。

▲[外部] Android Developers より引用

ダウンロードしたzipファイルを展開しappium-installer.exeを実行、セットアップウィザードを起動します。あとは画面の指示に従い必要であれば設定を変更しインストールを行って下さい。

インストール完了後Appiumが起動すれば完了です。

■Rubyのインストール

WindowsでRubyの実行環境を構築する場合、Rubyの公式サイトでも紹介されているRubyInstaller for Windowsというサードパーティ製のインストーラーを用いるのが簡単です。

▲[外部] RubyInstaller for Windows より引用

RubyInstallerのサイトのダウンロードページからダウンロードを行うのですが、選択するバージョンには注意が必要です。
最新のRuby 2.2.x(執筆時点ではRuby 2.2.3)ではなく、その下にあるRuby 2.1.x(執筆時点ではRuby 2.1.7)をダウンロードして下さい。これは、Ruby 2.2.xだとテストコード実行時にエラーが発生してしまうためです。

▲[外部] RubyInstaller for Windows より引用

ダウンロードされた実行形式ファイルを実行しセットアップウィザード起動、画面の指示に従ってインストールを行います。

基本的にデフォルトの設定で問題ありませんが、[インストール先とオプションの指定]では[Ruby の実行ファイルへ環境変数 PATH を設定する]にチェックを入れておくと環境変数をセットする手間が省けるため便利です。

コマンドプロンプトで"ruby -v"と実行し、バージョンが表示されればOKです。

>ruby -v
ruby 2.1.7p400 (2015-08-18 revision 51632) [x64-mingw32]

■Rubyのライブラリ(gem)のインストール

Rubyではサードパーティ製のライブラリが"gem"という形式で公開されており、gemコマンドを使用してインストールすることができます。gemコマンドはRubyInstallerでRubyをインストールした際に組み込まれていますので、特にすることはありません。ここではRubyからAppiumを使用するためのライブラリ"appium_lib"をインストールします。
gemのインストールは簡単で、以下のように"gem install <gem名>"と実行するだけです。これによってappium_libと依存するgemがインストールされます。

>gem install appium_lib

これで環境構築は完了です。


■サンプルコードの実行

AppiumのサンプルコードはGitHubのappium/sample-codeリポジトリで公開されていますが、rubyのものはxUnitやRSpecといったテスティングフレームワークの利用が前提となっているようです。今回は最小限の環境構築に留めるためそれらは使用しません。apkファイルのみでもテストが可能な事を示すため、公開されているapkファイルを利用させてもらうようにします。

■準備

前述のリポジトリにある sample-code/apps/selendroid-test-app.apk をダウンロードし任意のパスにコピーします。
次にテキストエディタを用いて以下のコードを記述し、先ほどのapkファイルと同じ場所にsample.rbとして保存します。

# encoding: utf-8
require "appium_lib"

desired_caps = {
  caps: {
    platformName:  "Android",
    deviceName:    "Android Device",
    app:           "#{Dir.pwd}/selendroid-test-app.apk",
  }
}

driver = Appium::Driver.new(desired_caps).start_driver
Appium.promote_appium_methods Object

button_element = find_element(:id, "io.selendroid.testapp:id/visibleButtonTest")
button_element.click
sleep 3
text_element = find_element(:id, "io.selendroid.testapp:id/visibleTextView")
displayed_text = text_element.text
button_element.click
sleep 3
puts displayed_text

driver.quit

■実行

Appiumを起動し右上にある右向き三角ボタン(いわゆる再生ボタン)をクリックし、以下のような表示になるまで少し待ちます。

コマンドプロンプトから以下のようにしてサンプルコードを実行します。

>ruby sample.rb

テスト対象アプリケーションとAppiumがテストで使用するアプリケーションのインストール、テスト対象アプリケーションの起動が行われテストが実行されます。最終的にコマンドプロンプトに"Text is sometimes displayed"が表示されれば成功です。

■解説

Appium側の操作によってサーバープログラムが起動しています。PCに接続したデバイスに対して直接操作を行うのがこのサーバーで、テストスクリプトからはサーバーを介して画面の操作や情報の取得を行うことになります。
スクリプトの12行目でサーバーへの接続を行い、Appium::Driverクラスのインスタンスを取得しています。4〜9行目のdesired_capsはそのためのパラメーターです。
15〜22行目がテストの本体となっている部分で、詳細な説明は省きますが、テストアプリケーションの画面に表示されている[Display text view]ボタンをクリックし、表示されたテキスト"Text is sometimes displayed"を変数に保存、それをコマンドプロンプトへ出力する、といった事をしています。

2015年10月28日水曜日


http://googledevelopers.blogspot.jp/2015/07/lighting-way-with-ble-beacons.html から引用

はじめに

弊社のブログでは様々なiOS + BLEやBLEデバイスの開発の取り組みを紹介してきました。

ということで!

Android Marshmallowの公開もされましたので、これを機にAndroid 6.0 + BLEに関しての記事を掲載していきたいと思います。

今回は第一回目として、BluetoothとBLEのおさらいをしていきながら、今後作るアプリやサービスのイメージを膨らませていきましょう。

Bluetooth

Bluetoothの特徴

  • 無線通信(数mから数十m程度の距離間での通信が可能)
  • 小型で低消費電力
  • 暗号化通信される
  • 混信する可能性がとても低い
Bluetoothは無線接続の状態を意識せずに常時接続したままでの使用状況に適しているので、日常的に身につけるものなどとの相性がとても良いです。
また、近距離で少し大き目のデータでも機器間で通信を行うことも出来ます。

特にPCのマウスやキーボード、ワイヤレスイヤホン、ヘッドフォンなどにも使用されています。
煩わしいケーブルを排除出来るので、作業スペース等がスッキリしてとても使いやすいです。

使用例:
  • マウスやキーボードのパソコン周辺機器
  • オーディオ機器
  • スキャナ/プリンタ

BLE(Bluetooth Low Energy)の特徴

  • 小型で電池消費量が極少(ボタン電池で1年以上) 
  • ペアリングを行わなくても他デバイスに通知が可能(ブロードキャスト通信) 
  • 通信速度は低い
Bluetooth4.0はBluetooth3.0にBLEの技術を統合したもので、BLEとはBluetooth 4.0以降の機能の一部を指します。筆者自身勘違いをしていたのですが、Bluetooth4.0 = BLEというわけではありません。
Bluetooth3.0規格の拡張版がBluetooth4.0であり、その機能の一部がBLEです。

ただし、BLE機能は過去バージョンとの下方互換がまったくない為、BLEのみに対応したデバイスと3.0までのBluetoothデバイスとは接続を行うことが出来ない点に注意が必要です。

BLEデバイスは以下の2種類に分類されます。

Bluetooth Smart

 BLEでのみ通信を行う。従来のBluetooth機器との接続不可。

Bluetooth Smart Ready

 BLEで通信をする子機との通信に対応し、従来のBluetooth機器との接続可。

※ロゴマークに関してはこちらを参照してください。

※動画も公開しています。

BLEは常時データをやり取りする必要がなく、1回のデータ量も少ない用途に向いています。
超低消費電力なので、配置してからしばらく電池交換をする手間が必要ありません。
また、ペアリングを行わなくても他デバイスへの通知が可能なことから、通りがかっただけの人などを集客する効果も見込まれています。

使用例:
  • ライフログリストバンド
  • 運動用センサー(スピード/ケイデンス/心拍センサー)
  • 忘れ物防止タグ
  • 降水確立を知らせる傘立て(※)
  • ごみの収集日を知らせるごみ箱(※)
  • スマートウォッチ
※こちらを参照

その他にも生活で使用するもの以外でもユニークなものがこちらで紹介されています。

さて、特徴や使用例をいくつか挙げていきました。

ここまででおさらいしてきたBluetoothの特徴や既に販売されているものや実施されているサービスを踏まえつつ、次はAndroidへと目を向けていきましょう。

Android & Bluetooth

ではAndroidではどのようにBluetoothの制御を行っているのでしょうか。
ここではAndroidのBluetoothアーキテクチャと、Bluetoothのプロファイルについて触れたいと思います。
※アプリケーション側の実装方法などは次回以降紹介します。


Bluetoothアーキテクチャ

アプリケーションは、android.bluetoothのAPIを使いBluetoothハードウェアとの総合通信を行います。
内部的に、Binder IPCメカニズムを介してBluetooth processをコールします。
Bluetooth system serviceはJNIを介してBluetooth stackと通信を行います。
また、Binder IPCを介してアプリと通信を行います。
system serviceにより、開発者は様々なBluetooth profileへのアクセスが可能となります。

下図が、Bluetooth stackの一般的な構造となります。


      
https://source.android.com/devices/bluetooth.html より引用

Bluetooth system service
packages/apps/BluetoothにあるBluetooth system serviceは、Android appとしてパッケージされ、Bluetooth serviceおよびprofileをAndroid framework layerに実装します。このアプリはJNI経由でHAL layerをコールします。

JNI
android.bluetoothと連携しているJNIは、packages/apps/Bluetooth/jniにあります。JNIコードは、HAL layerにコールし、端末が発見された時などのように、特定のBluetoothオペレーションが発生した際にHALからコールバックを受信します。

このような構造で、AndroidはアプリケーションからBluetoothの機能を使用することが出来ます。

アプリケーション開発においては特に、Application Framework部とBluetooth Process部を意識することになりますが、このような構造を知っておくことで、不具合などが発生した場合のデバッグなどにも役立つと思います。

そして、次にBluetooth Process部にあるプロファイルに関して簡単に説明します。

プロファイル

プロファイルというのは簡単に言うと、Bluetooth機器が何を出来るかを定義したものです。
様々な機器と無線通信を行う性質上、どのような順番・タイミングで、どんな種類の情報を転送すべきか、という機器の「使い方」にあたる手順を共通化しておく必要がある。
この手順を機器の特性ごとに標準化したものが、プロファイルです。

参考:
Bluetoothプロファイル 【 Bluetooth Profile 】

接続するBluetooth機器同士が同じプロファイルに対応していることで、その機能が利用できますが、定義されていないと使用することが出来ません。
実際に使用する際にはプロファイルをよく理解し、適切なものを使用しましょう。

・主なBluetoothプロファイル(一部)
HID(Human Interface Device Profile) 入力機器を扱うためのプロファイル
HSP(Headset Profile) ヘッドセットと通信するためのプロファイル
HFP(Hands-Free Profile) ハンズフリー通話をするためのプロファイル
A2DP(Advanced Audio Distribution Profile) 高音質のステレオ音声を伝送するためのプロファイル
AVRCP(Audio/Video Remote Control Profile) AV機器のコントロール(再生、早送り等)を行うためのプロファル
FTP(File Transfer Profile) ファイル転送プロファイル

・4.0から使用出来るBluetoothプロファイル
ANP(Alert Notification Profile) 電話やメールなどの着信を通知するプロファイル
BLP(Blood Pressure Profile) 血圧計から血圧情報を伝送するためのプロファイル
CPP(Cycling Power Profile) サイクリング時の力などを情報を伝送するためのプロファイル
CSCP(Cycling Speed and Cadence Profile) サイクリング時のスピードや回転数などの情報を伝送するためのプロファイル
FMP(Find Me Profile) 遠隔からアラームやバイブレーションを鳴動させ、装置の場所を調べるためのプロファイル
GLP(Glucose Profile) 血糖値の情報を伝送するためのプロファイル
HOGP(HID over GATT Profile) マウスやキーボードなどを接続するためのプロファイル
HTP(Health Thermometer Profile) 体温計の情報を伝送するためのプロファイル
HRP(Heart Rate Profile) 心拍計の情報を伝送するためのプロファイル
IPSP (Internet Protocol Support Profile) IPv6/6LoWPAN経由でインターネットに接続するプロファイル
PASP(Phone Alert Status Profile) 電話着信時の鳴動などを他の機器から止めるためのプロファイル
PXP(Proximity Profile) 互いの機器間の距離をモニタリングするためのプロファイル
RSCP(Running Speed and Cadence Profile) ランニング時のスピードや歩幅などの情報を伝送するためのプロファイル
ScPP(Scan Parameters Profile) 装置のスキャンをするためのプロファイル
TIP(Time Profile) 時刻情報を通知するためのプロフィール
プロファイルの参考:

さいごに

今回はBluetoothやBLEに関してのおさらいを行いましたがいかがだったでしょうか。
BluetoothやBLEを使用したアプリやサービスのイメージは膨らみましたか?

次回からは実際にAndroidアプリケーションでBLEの検知、ペアリング方法を紹介したいと思います。

[第一回] 生活で使えるBLEデバイス


http://googledevelopers.blogspot.jp/2015/07/lighting-way-with-ble-beacons.html から引用

はじめに

弊社のブログでは様々なiOS + BLEやBLEデバイスの開発の取り組みを紹介してきました。

ということで!

Android Marshmallowの公開もされましたので、これを機にAndroid 6.0 + BLEに関しての記事を掲載していきたいと思います。

今回は第一回目として、BluetoothとBLEのおさらいをしていきながら、今後作るアプリやサービスのイメージを膨らませていきましょう。

Bluetooth

Bluetoothの特徴

  • 無線通信(数mから数十m程度の距離間での通信が可能)
  • 小型で低消費電力
  • 暗号化通信される
  • 混信する可能性がとても低い
Bluetoothは無線接続の状態を意識せずに常時接続したままでの使用状況に適しているので、日常的に身につけるものなどとの相性がとても良いです。
また、近距離で少し大き目のデータでも機器間で通信を行うことも出来ます。

特にPCのマウスやキーボード、ワイヤレスイヤホン、ヘッドフォンなどにも使用されています。
煩わしいケーブルを排除出来るので、作業スペース等がスッキリしてとても使いやすいです。

使用例:
  • マウスやキーボードのパソコン周辺機器
  • オーディオ機器
  • スキャナ/プリンタ

BLE(Bluetooth Low Energy)の特徴

  • 小型で電池消費量が極少(ボタン電池で1年以上) 
  • ペアリングを行わなくても他デバイスに通知が可能(ブロードキャスト通信) 
  • 通信速度は低い
Bluetooth4.0はBluetooth3.0にBLEの技術を統合したもので、BLEとはBluetooth 4.0以降の機能の一部を指します。筆者自身勘違いをしていたのですが、Bluetooth4.0 = BLEというわけではありません。
Bluetooth3.0規格の拡張版がBluetooth4.0であり、その機能の一部がBLEです。

ただし、BLE機能は過去バージョンとの下方互換がまったくない為、BLEのみに対応したデバイスと3.0までのBluetoothデバイスとは接続を行うことが出来ない点に注意が必要です。

BLEデバイスは以下の2種類に分類されます。

Bluetooth Smart

 BLEでのみ通信を行う。従来のBluetooth機器との接続不可。

Bluetooth Smart Ready

 BLEで通信をする子機との通信に対応し、従来のBluetooth機器との接続可。

※ロゴマークに関してはこちらを参照してください。

※動画も公開しています。

BLEは常時データをやり取りする必要がなく、1回のデータ量も少ない用途に向いています。
超低消費電力なので、配置してからしばらく電池交換をする手間が必要ありません。
また、ペアリングを行わなくても他デバイスへの通知が可能なことから、通りがかっただけの人などを集客する効果も見込まれています。

使用例:
  • ライフログリストバンド
  • 運動用センサー(スピード/ケイデンス/心拍センサー)
  • 忘れ物防止タグ
  • 降水確立を知らせる傘立て(※)
  • ごみの収集日を知らせるごみ箱(※)
  • スマートウォッチ
※こちらを参照

その他にも生活で使用するもの以外でもユニークなものがこちらで紹介されています。

さて、特徴や使用例をいくつか挙げていきました。

ここまででおさらいしてきたBluetoothの特徴や既に販売されているものや実施されているサービスを踏まえつつ、次はAndroidへと目を向けていきましょう。

Android & Bluetooth

ではAndroidではどのようにBluetoothの制御を行っているのでしょうか。
ここではAndroidのBluetoothアーキテクチャと、Bluetoothのプロファイルについて触れたいと思います。
※アプリケーション側の実装方法などは次回以降紹介します。


Bluetoothアーキテクチャ

アプリケーションは、android.bluetoothのAPIを使いBluetoothハードウェアとの総合通信を行います。
内部的に、Binder IPCメカニズムを介してBluetooth processをコールします。
Bluetooth system serviceはJNIを介してBluetooth stackと通信を行います。
また、Binder IPCを介してアプリと通信を行います。
system serviceにより、開発者は様々なBluetooth profileへのアクセスが可能となります。

下図が、Bluetooth stackの一般的な構造となります。


      
https://source.android.com/devices/bluetooth.html より引用

Bluetooth system service
packages/apps/BluetoothにあるBluetooth system serviceは、Android appとしてパッケージされ、Bluetooth serviceおよびprofileをAndroid framework layerに実装します。このアプリはJNI経由でHAL layerをコールします。

JNI
android.bluetoothと連携しているJNIは、packages/apps/Bluetooth/jniにあります。JNIコードは、HAL layerにコールし、端末が発見された時などのように、特定のBluetoothオペレーションが発生した際にHALからコールバックを受信します。

このような構造で、AndroidはアプリケーションからBluetoothの機能を使用することが出来ます。

アプリケーション開発においては特に、Application Framework部とBluetooth Process部を意識することになりますが、このような構造を知っておくことで、不具合などが発生した場合のデバッグなどにも役立つと思います。

そして、次にBluetooth Process部にあるプロファイルに関して簡単に説明します。

プロファイル

プロファイルというのは簡単に言うと、Bluetooth機器が何を出来るかを定義したものです。
様々な機器と無線通信を行う性質上、どのような順番・タイミングで、どんな種類の情報を転送すべきか、という機器の「使い方」にあたる手順を共通化しておく必要がある。
この手順を機器の特性ごとに標準化したものが、プロファイルです。

参考:
Bluetoothプロファイル 【 Bluetooth Profile 】

接続するBluetooth機器同士が同じプロファイルに対応していることで、その機能が利用できますが、定義されていないと使用することが出来ません。
実際に使用する際にはプロファイルをよく理解し、適切なものを使用しましょう。

・主なBluetoothプロファイル(一部)
HID(Human Interface Device Profile) 入力機器を扱うためのプロファイル
HSP(Headset Profile) ヘッドセットと通信するためのプロファイル
HFP(Hands-Free Profile) ハンズフリー通話をするためのプロファイル
A2DP(Advanced Audio Distribution Profile) 高音質のステレオ音声を伝送するためのプロファイル
AVRCP(Audio/Video Remote Control Profile) AV機器のコントロール(再生、早送り等)を行うためのプロファル
FTP(File Transfer Profile) ファイル転送プロファイル

・4.0から使用出来るBluetoothプロファイル
ANP(Alert Notification Profile) 電話やメールなどの着信を通知するプロファイル
BLP(Blood Pressure Profile) 血圧計から血圧情報を伝送するためのプロファイル
CPP(Cycling Power Profile) サイクリング時の力などを情報を伝送するためのプロファイル
CSCP(Cycling Speed and Cadence Profile) サイクリング時のスピードや回転数などの情報を伝送するためのプロファイル
FMP(Find Me Profile) 遠隔からアラームやバイブレーションを鳴動させ、装置の場所を調べるためのプロファイル
GLP(Glucose Profile) 血糖値の情報を伝送するためのプロファイル
HOGP(HID over GATT Profile) マウスやキーボードなどを接続するためのプロファイル
HTP(Health Thermometer Profile) 体温計の情報を伝送するためのプロファイル
HRP(Heart Rate Profile) 心拍計の情報を伝送するためのプロファイル
IPSP (Internet Protocol Support Profile) IPv6/6LoWPAN経由でインターネットに接続するプロファイル
PASP(Phone Alert Status Profile) 電話着信時の鳴動などを他の機器から止めるためのプロファイル
PXP(Proximity Profile) 互いの機器間の距離をモニタリングするためのプロファイル
RSCP(Running Speed and Cadence Profile) ランニング時のスピードや歩幅などの情報を伝送するためのプロファイル
ScPP(Scan Parameters Profile) 装置のスキャンをするためのプロファイル
TIP(Time Profile) 時刻情報を通知するためのプロフィール
プロファイルの参考:

さいごに

今回はBluetoothやBLEに関してのおさらいを行いましたがいかがだったでしょうか。
BluetoothやBLEを使用したアプリやサービスのイメージは膨らみましたか?

次回からは実際にAndroidアプリケーションでBLEの検知、ペアリング方法を紹介したいと思います。


Android 5.0 Lollipopで追加されたandroid.hardware.camera2を使うことで、
JPEG画像だけでなく、RAW画像も撮影できるようになりました。

普段はJPEGで撮影しているけど、失敗できない"とっておきの時"はRAWで撮影する。
一眼レフカメラをお使いの方はそんな使い分けをされているかもしれません。

今回は、その撮影方法をご紹介したいと思います。

※Camera2Rawをベースに撮影に必要な部分を引用して説明いたします。


■RAW画像とは


デジタルカメラでは一般的に「写真」としてJPEG画像を生成するが、RAW画像は
JPEG画像を生成する元となる「生」の画像データである。

非可逆圧縮されたJPEG画像と比べて、RAW画像は無圧縮(可逆圧縮)であるため
サイズが非常に大きくなっています。

しかし、RAW画像は撮影後に専用の現像ソフトによって露出やホワイトバランスを
思い通りに変更することができるため、「現像」工程を自身で行うことができます。


■撮影の流れ


下記の手順でカメラを制御することで撮影画像を取得することができます。
  • カメラをセットアップする
  • カメラを開く
  • プレビューを表示する
  • 撮影する
  • 画像を保存する

それでは早速内容を見ていきます。


■カメラをセットアップする


カメラを使用して画像をSTORAGEへ保存するために下記パーミッションを追加します。

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

※注意※
 Android 6.0 (API Level 23)より上記パーミッションのプロテクションレベルが
 Dangerousとなります。
 そのため、そのまま使用すると実行時にSecurity Exceptionが発生します。

 上記の環境でプログラムを実行する際にはContextCompat.checkSelfPermissionを
 用いて、ユーザの許可を得る必要があります。


次に下記featureを定義することでRAW画像の撮影が可能になります。

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.raw" />


アプリが起動するとonResume→openCameraと呼ばれ、setUpCameraOutputs
の中でgetCameraCharacteristicsを呼び出すことでカメラデバイスが
有する機能を取得することができます。

CameraCharacteristics characteristics
    = manager.getCameraCharacteristics(cameraId);

// We only use a camera that supports RAW in this sample.
if (!contains(characteristics.get(
        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES),
   CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
        continue;
}

上記では、取得した機能を用いてRAW撮影に対応している場合のみ撮影可能と判定しています。

また、ImageReaderへsetOnImageAvailableListenerでCallbackを設定することで
画像が保存可能になった際にCallbackを受けることができます。
第2引数へHandlerを渡すことで非同期に画像の取得処理を行います。

if (mRawImageReader == null || mRawImageReader.getAndRetain() == null) {
    mRawImageReader = new RefCountedAutoCloseable<>(<
            ImageReader.newInstance(largestRaw.getWidth(),
                    largestRaw.getHeight(), ImageFormat.RAW_SENSOR, /*maxImages*/ 5));
}
mRawImageReader.get().setOnImageAvailableListener(
        mOnRawImageAvailableListener, mBackgroundHandler);
}

■カメラを開く


次にopenCameraに戻り、CameraManagerのopenCameraを呼び出します。
これにより、カメラを開き、処理が完了した際のCallbackを受けることができます。

private void openCamera() {

    CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
        manager.openCamera(cameraId, mStateCallback, backgroundHandler);
}

カメラOpenのCallback処理にてプレビューを開始します。

private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice cameraDevice) {
    synchronized (mCameraStateLock) {
        // Start the preview session if the TextureView has been set up already.
        if (mPreviewSize != null && mTextureView.isAvailable()) {
                createCameraPreviewSessionLocked();
        }
    }
}

■プレビューを表示する


createCaptureSessionにてCameraCaptureSessionを生成します。
生成が正常に完了すると、CameraCaptureSession.StateCallbackの
onConfiguredが呼び出されます。

setup3AControlsLockedでは、3A(auto-focus, auto-exposure, auto-white-balance)
の設定を行いRequestへ設定します。

Sessionに対して上記で設定したRequestを発行することでプレビュー用フレームデータを
取得することができます。

最後にsetRepeatingRequestを呼び出すと表示用のSurfaceTextureへプレビューが表示されます。
また、RepeatingRequestを設定することで、captureを繰り返し行う必要がなく、
プレビュー用フレームを継続的に取得することができます。

private void createCameraPreviewSessionLocked() {
    try {
        SurfaceTexture texture = mTextureView.getSurfaceTexture();

        // Here, we create a CameraCaptureSession for camera preview.
        mCameraDevice.createCaptureSession(Arrays.asList(surface,
           mJpegImageReader.get().getSurface(),
           mRawImageReader.get().getSurface()), new CameraCaptureSession.StateCallback() {
           @Override
           public void onConfigured(CameraCaptureSession cameraCaptureSession) {
               synchronized (mCameraStateLock) {

                  setup3AControlsLocked(mPreviewRequestBuilder);
                  // Finally, we start displaying the camera preview.
                  cameraCaptureSession.setRepeatingRequest(
                     mPreviewRequestBuilder.build(),
                     mPreCaptureCallback, mBackgroundHandler);
                  mState = STATE_PREVIEW;
 
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

■撮影する

CameraCaptureSessionのcaptureにより撮影を開始します。
フレームのキャプチャが開始されるとCaptureCallbackが呼び出されます。

private void takePicture() {
    // Replace the existing repeating request with one with updated 3A triggers.
    mCaptureSession.capture(mPreviewRequestBuilder.build(), mPreCaptureCallback,
        mBackgroundHandler);
}

CaptureCallbackではPre-capture処理としてcaptureStillPictureLockedを呼び出し、
キャプチャするフレームの設定を行います。
最後にもう一度CameraCaptureSessionのcaptureを呼び出すことで
カメラデバイスに対して撮影処理のRequestを発行します。

private void captureStillPictureLocked() {
    // Use the same AE and AF modes as the preview.
    setup3AControlsLocked(captureBuilder);

    // Create an ImageSaverBuilder in which to collect results, and add it to the queue
    // of active requests.
    ImageSaver.ImageSaverBuilder rawBuilder = new ImageSaver.ImageSaverBuilder(activity)
        .setCharacteristics(mCharacteristics);

    mRawResultQueue.put((int) request.getTag(), rawBuilder);
    mCaptureSession.capture(request, mCaptureCallback, mBackgroundHandler);
}

撮影が完了するとCameraCaptureSession.CaptureCallbackの
onCaptureCompletedが呼び出されます。

@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
    TotalCaptureResult result) {
        synchronized (mCameraStateLock) {
        rawBuilder = mRawResultQueue.get(requestId);

        handleCompletionLocked(requestId, rawBuilder, mRawResultQueue);

        if (rawBuilder != null) {
            rawBuilder.setResult(result);
            if (jpegBuilder != null) sb.append(", ");
            sb.append("Saving RAW as: ");
            sb.append(rawBuilder.getSaveLocation());
        }
        finishedCaptureLocked();
    }
}

handleCompletionLockedでImageSaverを生成し、
バックグラウンドのスレッドとして実行します。
ImageSaverでは、画像の保存処理を行います。

private void handleCompletionLocked(int requestId, ImageSaver.ImageSaverBuilder builder,
    TreeMap<Integer, ImageSaver.ImageSaverBuilder> queue) {

    ImageSaver saver = builder.buildIfComplete();
    if (saver != null) {
        queue.remove(requestId);
        AsyncTask.THREAD_POOL_EXECUTOR.execute(saver);
    }
}

■画像を保存する


ImageSaverでは、RAW画像の保存を行います。
DngCreator classを使って取得したデータをDNGファイル形式へ変換します。

※DNGファイルとは米アドビシステムズが開発したファイル形式です。詳細は、リンク先の「Adobe DNG ~ specification」を参照ください


    switch (format) {
        case ImageFormat.RAW_SENSOR: {
            DngCreator dngCreator = new DngCreator(mCharacteristics, mCaptureResult);
            FileOutputStream output = null;
            try {
                output = new FileOutputStream(mFile);
                dngCreator.writeImage(output, mImage);
                success = true;
            } finally {
                mImage.close();
                closeOutput(output);
            }
        }
    }

最後にMediaScannerConnection classのscanFileを使って、
画像をContentProviderへ登録します。
これにより、撮影した画像をギャラリーへ反映させることができます。

    if (success) {
        MediaScannerConnection.scanFile(mContext, new String[]{mFile.getPath()},
        /*mimeTypes*/null, new MediaScannerConnection.MediaScannerConnectionClient() {

        @Override
        public void onScanCompleted(String path, Uri uri) {
            Log.i(TAG, "Scanned " + path + ":");
            Log.i(TAG, "-> uri=" + uri);
        }
    });

■撮影を終えて


Nexus6で撮影したところ、24MB程度のRAW画像が取得できました。
同じサイズで撮影したJPEGファイルは、1.5MB程度であるため、
比較すると非常に大きなサイズであることがわかります。

近年、スマホに搭載されるカメラの性能が上がったため、子供の運動会や
結婚式でもスマホで撮影しているシーンをよく見かけます。

大事なシーンの撮影は一眼レフカメラで撮影するイメージが強かったのですが、
スマホがどんどんその性能に近づいてきているんだなと実感しました。


[コラム]Android camera2を使ってRAW画像を撮影する



Android 5.0 Lollipopで追加されたandroid.hardware.camera2を使うことで、
JPEG画像だけでなく、RAW画像も撮影できるようになりました。

普段はJPEGで撮影しているけど、失敗できない"とっておきの時"はRAWで撮影する。
一眼レフカメラをお使いの方はそんな使い分けをされているかもしれません。

今回は、その撮影方法をご紹介したいと思います。

※Camera2Rawをベースに撮影に必要な部分を引用して説明いたします。


■RAW画像とは


デジタルカメラでは一般的に「写真」としてJPEG画像を生成するが、RAW画像は
JPEG画像を生成する元となる「生」の画像データである。

非可逆圧縮されたJPEG画像と比べて、RAW画像は無圧縮(可逆圧縮)であるため
サイズが非常に大きくなっています。

しかし、RAW画像は撮影後に専用の現像ソフトによって露出やホワイトバランスを
思い通りに変更することができるため、「現像」工程を自身で行うことができます。


■撮影の流れ


下記の手順でカメラを制御することで撮影画像を取得することができます。
  • カメラをセットアップする
  • カメラを開く
  • プレビューを表示する
  • 撮影する
  • 画像を保存する

それでは早速内容を見ていきます。


■カメラをセットアップする


カメラを使用して画像をSTORAGEへ保存するために下記パーミッションを追加します。

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

※注意※
 Android 6.0 (API Level 23)より上記パーミッションのプロテクションレベルが
 Dangerousとなります。
 そのため、そのまま使用すると実行時にSecurity Exceptionが発生します。

 上記の環境でプログラムを実行する際にはContextCompat.checkSelfPermissionを
 用いて、ユーザの許可を得る必要があります。


次に下記featureを定義することでRAW画像の撮影が可能になります。

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.raw" />


アプリが起動するとonResume→openCameraと呼ばれ、setUpCameraOutputs
の中でgetCameraCharacteristicsを呼び出すことでカメラデバイスが
有する機能を取得することができます。

CameraCharacteristics characteristics
    = manager.getCameraCharacteristics(cameraId);

// We only use a camera that supports RAW in this sample.
if (!contains(characteristics.get(
        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES),
   CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
        continue;
}

上記では、取得した機能を用いてRAW撮影に対応している場合のみ撮影可能と判定しています。

また、ImageReaderへsetOnImageAvailableListenerでCallbackを設定することで
画像が保存可能になった際にCallbackを受けることができます。
第2引数へHandlerを渡すことで非同期に画像の取得処理を行います。

if (mRawImageReader == null || mRawImageReader.getAndRetain() == null) {
    mRawImageReader = new RefCountedAutoCloseable<>(<
            ImageReader.newInstance(largestRaw.getWidth(),
                    largestRaw.getHeight(), ImageFormat.RAW_SENSOR, /*maxImages*/ 5));
}
mRawImageReader.get().setOnImageAvailableListener(
        mOnRawImageAvailableListener, mBackgroundHandler);
}

■カメラを開く


次にopenCameraに戻り、CameraManagerのopenCameraを呼び出します。
これにより、カメラを開き、処理が完了した際のCallbackを受けることができます。

private void openCamera() {

    CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
        manager.openCamera(cameraId, mStateCallback, backgroundHandler);
}

カメラOpenのCallback処理にてプレビューを開始します。

private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice cameraDevice) {
    synchronized (mCameraStateLock) {
        // Start the preview session if the TextureView has been set up already.
        if (mPreviewSize != null && mTextureView.isAvailable()) {
                createCameraPreviewSessionLocked();
        }
    }
}

■プレビューを表示する


createCaptureSessionにてCameraCaptureSessionを生成します。
生成が正常に完了すると、CameraCaptureSession.StateCallbackの
onConfiguredが呼び出されます。

setup3AControlsLockedでは、3A(auto-focus, auto-exposure, auto-white-balance)
の設定を行いRequestへ設定します。

Sessionに対して上記で設定したRequestを発行することでプレビュー用フレームデータを
取得することができます。

最後にsetRepeatingRequestを呼び出すと表示用のSurfaceTextureへプレビューが表示されます。
また、RepeatingRequestを設定することで、captureを繰り返し行う必要がなく、
プレビュー用フレームを継続的に取得することができます。

private void createCameraPreviewSessionLocked() {
    try {
        SurfaceTexture texture = mTextureView.getSurfaceTexture();

        // Here, we create a CameraCaptureSession for camera preview.
        mCameraDevice.createCaptureSession(Arrays.asList(surface,
           mJpegImageReader.get().getSurface(),
           mRawImageReader.get().getSurface()), new CameraCaptureSession.StateCallback() {
           @Override
           public void onConfigured(CameraCaptureSession cameraCaptureSession) {
               synchronized (mCameraStateLock) {

                  setup3AControlsLocked(mPreviewRequestBuilder);
                  // Finally, we start displaying the camera preview.
                  cameraCaptureSession.setRepeatingRequest(
                     mPreviewRequestBuilder.build(),
                     mPreCaptureCallback, mBackgroundHandler);
                  mState = STATE_PREVIEW;
 
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

■撮影する

CameraCaptureSessionのcaptureにより撮影を開始します。
フレームのキャプチャが開始されるとCaptureCallbackが呼び出されます。

private void takePicture() {
    // Replace the existing repeating request with one with updated 3A triggers.
    mCaptureSession.capture(mPreviewRequestBuilder.build(), mPreCaptureCallback,
        mBackgroundHandler);
}

CaptureCallbackではPre-capture処理としてcaptureStillPictureLockedを呼び出し、
キャプチャするフレームの設定を行います。
最後にもう一度CameraCaptureSessionのcaptureを呼び出すことで
カメラデバイスに対して撮影処理のRequestを発行します。

private void captureStillPictureLocked() {
    // Use the same AE and AF modes as the preview.
    setup3AControlsLocked(captureBuilder);

    // Create an ImageSaverBuilder in which to collect results, and add it to the queue
    // of active requests.
    ImageSaver.ImageSaverBuilder rawBuilder = new ImageSaver.ImageSaverBuilder(activity)
        .setCharacteristics(mCharacteristics);

    mRawResultQueue.put((int) request.getTag(), rawBuilder);
    mCaptureSession.capture(request, mCaptureCallback, mBackgroundHandler);
}

撮影が完了するとCameraCaptureSession.CaptureCallbackの
onCaptureCompletedが呼び出されます。

@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
    TotalCaptureResult result) {
        synchronized (mCameraStateLock) {
        rawBuilder = mRawResultQueue.get(requestId);

        handleCompletionLocked(requestId, rawBuilder, mRawResultQueue);

        if (rawBuilder != null) {
            rawBuilder.setResult(result);
            if (jpegBuilder != null) sb.append(", ");
            sb.append("Saving RAW as: ");
            sb.append(rawBuilder.getSaveLocation());
        }
        finishedCaptureLocked();
    }
}

handleCompletionLockedでImageSaverを生成し、
バックグラウンドのスレッドとして実行します。
ImageSaverでは、画像の保存処理を行います。

private void handleCompletionLocked(int requestId, ImageSaver.ImageSaverBuilder builder,
    TreeMap<Integer, ImageSaver.ImageSaverBuilder> queue) {

    ImageSaver saver = builder.buildIfComplete();
    if (saver != null) {
        queue.remove(requestId);
        AsyncTask.THREAD_POOL_EXECUTOR.execute(saver);
    }
}

■画像を保存する


ImageSaverでは、RAW画像の保存を行います。
DngCreator classを使って取得したデータをDNGファイル形式へ変換します。

※DNGファイルとは米アドビシステムズが開発したファイル形式です。詳細は、リンク先の「Adobe DNG ~ specification」を参照ください


    switch (format) {
        case ImageFormat.RAW_SENSOR: {
            DngCreator dngCreator = new DngCreator(mCharacteristics, mCaptureResult);
            FileOutputStream output = null;
            try {
                output = new FileOutputStream(mFile);
                dngCreator.writeImage(output, mImage);
                success = true;
            } finally {
                mImage.close();
                closeOutput(output);
            }
        }
    }

最後にMediaScannerConnection classのscanFileを使って、
画像をContentProviderへ登録します。
これにより、撮影した画像をギャラリーへ反映させることができます。

    if (success) {
        MediaScannerConnection.scanFile(mContext, new String[]{mFile.getPath()},
        /*mimeTypes*/null, new MediaScannerConnection.MediaScannerConnectionClient() {

        @Override
        public void onScanCompleted(String path, Uri uri) {
            Log.i(TAG, "Scanned " + path + ":");
            Log.i(TAG, "-> uri=" + uri);
        }
    });

■撮影を終えて


Nexus6で撮影したところ、24MB程度のRAW画像が取得できました。
同じサイズで撮影したJPEGファイルは、1.5MB程度であるため、
比較すると非常に大きなサイズであることがわかります。

近年、スマホに搭載されるカメラの性能が上がったため、子供の運動会や
結婚式でもスマホで撮影しているシーンをよく見かけます。

大事なシーンの撮影は一眼レフカメラで撮影するイメージが強かったのですが、
スマホがどんどんその性能に近づいてきているんだなと実感しました。


2015年10月23日金曜日


Android6.0 Marshmallow (マシュマロ)では、テキスト選択(Text Selection)の動作が仕様変更となりました。これまでは、テキスト選択時に画面上部のアクションバー(Action Bar)という部分に、コピー、貼り付け、切り取り、などのメニューが表示されていましたが、今回の仕様変更によってアクションバーへの表示はなくなり、選択した文字列のすぐ近くにメニューバーが表示されるようになりました。これによって、ユーザーはテキスト選択時に、選んだ文字列からあまり視線を離すことなく、メニューを選ぶことができるようになります。今回は、そのテキストビューの変更とバックグラウンド機能として導入されたフローティングアクションバー(Floating Action Bar)について簡単に紹介したいと思います。


■仕様変更となったテキスト選択時のアクションバー


以前のテキスト選択時の動作は、画像1のように、画面上部に「Text selection」というタイトルが表示され、その横にメニューのアイコンが並ぶという形でした。

画像1 [テキスト選択時(Android API Lv 22)]

Android 6.0(API LV 23)では、画像2のような動きに変わりました。

画像2 [テキスト選択時(Android API Lv 23)]

プログラムの方ですが、開発者は何もしなくても、テキストビューを画面に配置しただけで、デフォルトでフローティングアクションモードとしてテキスト選択時の動きをしてくれます。実際、画像1と2のプログラムは、図1のように同じコードで、コンパイルするAPIレベルを22と23に変えただけです。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView textView = (TextView) findViewById(R.id.sample_text);
        textView.setText(R.string.sample_text);
        textView.setTextIsSelectable(true);

    }

もちろん、図2のようにレイアウトXMLに記載してもOKです。

    <TextView
        android:id="@+id/sample_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textIsSelectable="true"
        android:text="@string/sample_text"
        />

この背後にある仕組みについて言います。

アクションバーへのメニューの表示やメニュー選択時の動きは、アクションモード(Action Mode)という仕組みで実現されています。テキストが選択された場合、テキストビューは、アクションバーにメニューを表示するようアクションモードに処理を依頼します(図3)。

図3 [アクションモード]

 このようにして、テキスト選択時の動作は実現されていますが、テキスト選択時のメニューバーの表示位置の変更にあたって、このアクションモードという仕組みに手が入りました。具体的には、アクションモードにフローティング(浮かんでいる)という新たな種別が追加になりました。このフローティングタイプのアクションモードを動かすと、対象となる部品のすぐそばにメニューバーを表示することになります。一方、これまでのアクションバーへの表示は、プライマリ(基本的な、主な)という種別として新たに呼ばれるようになり、アクションモードを利用する場合には、この2種類を選べるようになったというわけです。

いろいろ試してみましたが、テキストビューをプライマリのアクションモードとして簡単に設定しなおす方法はなさそうです。プロジェクトによっては、これまでアクションバー(画面上部)に表示されていたメニューが、アンドロイドのバージョンを6.0にあげたことにより、テキストのそばに表示されるようになってしまい、仕様と違う動きになって困るところも出てくるかもしれません。将来的にはどちらも選べるようになってほしいですね。

■Floating Action Mode を使ってみる


実際に、フローティングアクションモード(Floating Action Mode)を使って何か作ってみます。

例えば、テキストを並べたリストに対して、フローティングアクションモードを使ってみましょう。
メニューバーに並べる項目は、追加、削除、共有の三つにしておきます。

[実行の様子1]

サンプルプログラムは、複数選択のリストビューに対して、アイテムをクリックしたときにフローティングアクションバーを表示するようにしています。そのとき、アクションバーを表示する場所が、選択したアイテムに被らないように、選択したアイテムをちょうど覆う矩形領域を計算してアクションモードに渡しています。[実行の様子1]の青い部分が、その矩形領域です。

では、コードの要点の説明です。

アクションモードを使用する場合は、ユーザーの何らかのアクションに対して、アクションされたViewのstartActionModeメソッドを呼ぶ必要があります。


    private class CustomItemClickedListener implements AdapterView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView parent, View view, int position, long id) {
            ListView listView = (ListView)parent;
            boolean hasChecked = false;
            Rect rect = new Rect();
            Rect sumRect = null;
            int firstVisiblePosition = listView.getFirstVisiblePosition();
            for (int i = 0; i < listView.getChildCount(); i++) {
                TextView textView = (TextView) listView.getChildAt(i);
                if (listView.isItemChecked(firstVisiblePosition + i)) {
                    hasChecked = true;
                    textView.getGlobalVisibleRect(rect);
                    if (sumRect != null) {
                        sumRect.union(rect);
                    }
                    else {
                        sumRect = new Rect(rect);
                    }
                }
            }

            mSumRect = getRectRelTo(sumRect, listView);

            if (hasChecked) {
                showSelectRegion(mSumRect);
                // MEMO: startActionModeは、呼び出しスレッドとは別のスレッドでActionModeのコールバックを呼び出す
                mActionMode = listView.startActionMode(new CustomActionModeCallback(), ActionMode.TYPE_FLOATING);
            }
            else {
                showSelectRegion(null);
                if (mActionMode != null) {
                    mActionMode.finish();
                }
            }
        }
    }
[コード1]は、リストのアイテムをクリックしたときの処理です。

74行目~91行目で表示されている選択項目を覆う矩形領域を求めています。ついでに、選択項目があるかどうかもここでチェックしています。ここで求めた矩形領域は、コード2の方で使用します。

93行目から103行目では、項目が選択されている場合は、上で求めた矩形領域を表示し、リストビューに対して、startActionModeメソッドをTYPE_FLOATINGで呼び出しています。アクションモードのタイプを指定しないタイプのstartActionModeメソッドは、APIレベル11のときから存在していましたが、タイプを指定するstartActionModeメソッドは、APIレベル23から追加されました。startActionModeは、ActionModeオブジェクトを返します。クリックした結果、選択項目がなくなった場合に、このActionModeのfinish()メソッドを呼び出して、フローティングアクションバーを消しています。矩形領域もついでに消しています。showSelectionRegionメソッドは、筆者が作ったプライベートメソッドで、計算でもとめた矩形領域を青い透過色で可視化するためにあります。実際には必要ではありません。

次のコードは、ActionModeのコールバックの実装です。

    private class CustomActionModeCallback extends ActionMode.Callback2 {

        @Override
        public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
            outRect.set(mSumRect);
            mSumRect = null;
        }

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            menu.add(INSERT);
            menu.add(DELETE);
            menu.add(SHARE);
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            if (item.getTitle().equals(INSERT)) {
                insertNewItem();
            }
            else if (item.getTitle().equals(DELETE)) {
                deleteSelection();
            }
            else if (item.getTitle().equals(SHARE)) {
                shareSelections();
            }
            mode.finish();
            showSelectRegion(null);
            return true;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
        }
    }
[コード2]で実装しているのは、startActionModeメソッドの引数に渡しているActionModeのコールバッククラスです。以前のActionModeのコールバックであるActionMode.Callbackは、インターフェースクラスでしたが、APIレベル23で追加されたこのActionMode.Callback2は、ActionMode.Callbackを実装するクラスとなっています。Callback2クラスは、

public void onGetContentRect(ActionMode mode, View view, Rect outRect)

というメソッドが実装されています。第一引数は、表示しているアクションモードが渡ってきます。第2引数のviewは、startActionModeが呼ばれたViewです。このプログラムの場合は、ListViewがわたってきます。第3引数は、アウト引数で、ここには領域を設定して返してあげます。この領域というのは、フローティングアクションバーがその周りに表示される領域のことです。ここはプログラマーが任意に指定することができます。ActionMode.Callback2のデフォルトの実装では、outRectには、viewの表示領域がそのまま渡されます。今回のプログラムの場合は、アイテムクリック時に計算した矩形領域をここで渡しています(111行目)。

ActionMode.Callback2のその他のメソッドは、ActionMode.Callbackから受け継いだもので、APIレベル23で追加されたメソッドではないので、ここでの説明は省きます。

細かい説明をだいぶ省きましたが、フローティングアクションモードは、矩形領域を計算して、onGetContentRectでアクションモードへ渡してやることがポイントとなります。どんな実装でもこの矩形領域を計算する部分が面倒になりそうです。

■まとめ


簡単ではありますが、Android 6.0 で導入されたテキスト選択の新仕様と、フローティングアクションモードの使い方をご紹介しました。まとめるとこんな感じです:

  • テキストビューは、テキストのそばにメニューが表示され便利になりましたが、以前のように画面上部には表示できなくなりました。
  • 開発者は、アクションバーを使う場合、画面上部のプライマリーにするのか、フローティングにするのかを考えないといけなくなりました。
  • フローティングアクションバーを使う場合は、矩形領域の計算で苦労すると思われます。
冒頭の写真は、いま流行のマシュマロコーヒーです。
今回のマシュマロ・アンドロイドでは、コーヒーに浮かぶマシュマロのような機能が一つ追加されたというわけです。

[コラム] Android6.0「テキスト選択」の新仕様とFloating Action Mode


Android6.0 Marshmallow (マシュマロ)では、テキスト選択(Text Selection)の動作が仕様変更となりました。これまでは、テキスト選択時に画面上部のアクションバー(Action Bar)という部分に、コピー、貼り付け、切り取り、などのメニューが表示されていましたが、今回の仕様変更によってアクションバーへの表示はなくなり、選択した文字列のすぐ近くにメニューバーが表示されるようになりました。これによって、ユーザーはテキスト選択時に、選んだ文字列からあまり視線を離すことなく、メニューを選ぶことができるようになります。今回は、そのテキストビューの変更とバックグラウンド機能として導入されたフローティングアクションバー(Floating Action Bar)について簡単に紹介したいと思います。


■仕様変更となったテキスト選択時のアクションバー


以前のテキスト選択時の動作は、画像1のように、画面上部に「Text selection」というタイトルが表示され、その横にメニューのアイコンが並ぶという形でした。

画像1 [テキスト選択時(Android API Lv 22)]

Android 6.0(API LV 23)では、画像2のような動きに変わりました。

画像2 [テキスト選択時(Android API Lv 23)]

プログラムの方ですが、開発者は何もしなくても、テキストビューを画面に配置しただけで、デフォルトでフローティングアクションモードとしてテキスト選択時の動きをしてくれます。実際、画像1と2のプログラムは、図1のように同じコードで、コンパイルするAPIレベルを22と23に変えただけです。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView textView = (TextView) findViewById(R.id.sample_text);
        textView.setText(R.string.sample_text);
        textView.setTextIsSelectable(true);

    }

もちろん、図2のようにレイアウトXMLに記載してもOKです。

    <TextView
        android:id="@+id/sample_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textIsSelectable="true"
        android:text="@string/sample_text"
        />

この背後にある仕組みについて言います。

アクションバーへのメニューの表示やメニュー選択時の動きは、アクションモード(Action Mode)という仕組みで実現されています。テキストが選択された場合、テキストビューは、アクションバーにメニューを表示するようアクションモードに処理を依頼します(図3)。

図3 [アクションモード]

 このようにして、テキスト選択時の動作は実現されていますが、テキスト選択時のメニューバーの表示位置の変更にあたって、このアクションモードという仕組みに手が入りました。具体的には、アクションモードにフローティング(浮かんでいる)という新たな種別が追加になりました。このフローティングタイプのアクションモードを動かすと、対象となる部品のすぐそばにメニューバーを表示することになります。一方、これまでのアクションバーへの表示は、プライマリ(基本的な、主な)という種別として新たに呼ばれるようになり、アクションモードを利用する場合には、この2種類を選べるようになったというわけです。

いろいろ試してみましたが、テキストビューをプライマリのアクションモードとして簡単に設定しなおす方法はなさそうです。プロジェクトによっては、これまでアクションバー(画面上部)に表示されていたメニューが、アンドロイドのバージョンを6.0にあげたことにより、テキストのそばに表示されるようになってしまい、仕様と違う動きになって困るところも出てくるかもしれません。将来的にはどちらも選べるようになってほしいですね。

■Floating Action Mode を使ってみる


実際に、フローティングアクションモード(Floating Action Mode)を使って何か作ってみます。

例えば、テキストを並べたリストに対して、フローティングアクションモードを使ってみましょう。
メニューバーに並べる項目は、追加、削除、共有の三つにしておきます。

[実行の様子1]

サンプルプログラムは、複数選択のリストビューに対して、アイテムをクリックしたときにフローティングアクションバーを表示するようにしています。そのとき、アクションバーを表示する場所が、選択したアイテムに被らないように、選択したアイテムをちょうど覆う矩形領域を計算してアクションモードに渡しています。[実行の様子1]の青い部分が、その矩形領域です。

では、コードの要点の説明です。

アクションモードを使用する場合は、ユーザーの何らかのアクションに対して、アクションされたViewのstartActionModeメソッドを呼ぶ必要があります。


    private class CustomItemClickedListener implements AdapterView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView parent, View view, int position, long id) {
            ListView listView = (ListView)parent;
            boolean hasChecked = false;
            Rect rect = new Rect();
            Rect sumRect = null;
            int firstVisiblePosition = listView.getFirstVisiblePosition();
            for (int i = 0; i < listView.getChildCount(); i++) {
                TextView textView = (TextView) listView.getChildAt(i);
                if (listView.isItemChecked(firstVisiblePosition + i)) {
                    hasChecked = true;
                    textView.getGlobalVisibleRect(rect);
                    if (sumRect != null) {
                        sumRect.union(rect);
                    }
                    else {
                        sumRect = new Rect(rect);
                    }
                }
            }

            mSumRect = getRectRelTo(sumRect, listView);

            if (hasChecked) {
                showSelectRegion(mSumRect);
                // MEMO: startActionModeは、呼び出しスレッドとは別のスレッドでActionModeのコールバックを呼び出す
                mActionMode = listView.startActionMode(new CustomActionModeCallback(), ActionMode.TYPE_FLOATING);
            }
            else {
                showSelectRegion(null);
                if (mActionMode != null) {
                    mActionMode.finish();
                }
            }
        }
    }
[コード1]は、リストのアイテムをクリックしたときの処理です。

74行目~91行目で表示されている選択項目を覆う矩形領域を求めています。ついでに、選択項目があるかどうかもここでチェックしています。ここで求めた矩形領域は、コード2の方で使用します。

93行目から103行目では、項目が選択されている場合は、上で求めた矩形領域を表示し、リストビューに対して、startActionModeメソッドをTYPE_FLOATINGで呼び出しています。アクションモードのタイプを指定しないタイプのstartActionModeメソッドは、APIレベル11のときから存在していましたが、タイプを指定するstartActionModeメソッドは、APIレベル23から追加されました。startActionModeは、ActionModeオブジェクトを返します。クリックした結果、選択項目がなくなった場合に、このActionModeのfinish()メソッドを呼び出して、フローティングアクションバーを消しています。矩形領域もついでに消しています。showSelectionRegionメソッドは、筆者が作ったプライベートメソッドで、計算でもとめた矩形領域を青い透過色で可視化するためにあります。実際には必要ではありません。

次のコードは、ActionModeのコールバックの実装です。

    private class CustomActionModeCallback extends ActionMode.Callback2 {

        @Override
        public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
            outRect.set(mSumRect);
            mSumRect = null;
        }

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            menu.add(INSERT);
            menu.add(DELETE);
            menu.add(SHARE);
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            if (item.getTitle().equals(INSERT)) {
                insertNewItem();
            }
            else if (item.getTitle().equals(DELETE)) {
                deleteSelection();
            }
            else if (item.getTitle().equals(SHARE)) {
                shareSelections();
            }
            mode.finish();
            showSelectRegion(null);
            return true;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
        }
    }
[コード2]で実装しているのは、startActionModeメソッドの引数に渡しているActionModeのコールバッククラスです。以前のActionModeのコールバックであるActionMode.Callbackは、インターフェースクラスでしたが、APIレベル23で追加されたこのActionMode.Callback2は、ActionMode.Callbackを実装するクラスとなっています。Callback2クラスは、

public void onGetContentRect(ActionMode mode, View view, Rect outRect)

というメソッドが実装されています。第一引数は、表示しているアクションモードが渡ってきます。第2引数のviewは、startActionModeが呼ばれたViewです。このプログラムの場合は、ListViewがわたってきます。第3引数は、アウト引数で、ここには領域を設定して返してあげます。この領域というのは、フローティングアクションバーがその周りに表示される領域のことです。ここはプログラマーが任意に指定することができます。ActionMode.Callback2のデフォルトの実装では、outRectには、viewの表示領域がそのまま渡されます。今回のプログラムの場合は、アイテムクリック時に計算した矩形領域をここで渡しています(111行目)。

ActionMode.Callback2のその他のメソッドは、ActionMode.Callbackから受け継いだもので、APIレベル23で追加されたメソッドではないので、ここでの説明は省きます。

細かい説明をだいぶ省きましたが、フローティングアクションモードは、矩形領域を計算して、onGetContentRectでアクションモードへ渡してやることがポイントとなります。どんな実装でもこの矩形領域を計算する部分が面倒になりそうです。

■まとめ


簡単ではありますが、Android 6.0 で導入されたテキスト選択の新仕様と、フローティングアクションモードの使い方をご紹介しました。まとめるとこんな感じです:

  • テキストビューは、テキストのそばにメニューが表示され便利になりましたが、以前のように画面上部には表示できなくなりました。
  • 開発者は、アクションバーを使う場合、画面上部のプライマリーにするのか、フローティングにするのかを考えないといけなくなりました。
  • フローティングアクションバーを使う場合は、矩形領域の計算で苦労すると思われます。
冒頭の写真は、いま流行のマシュマロコーヒーです。
今回のマシュマロ・アンドロイドでは、コーヒーに浮かぶマシュマロのような機能が一つ追加されたというわけです。

2015年10月1日木曜日



EPSON MOVERIO BT-200をモニターとしてお借りしておりましたが、半年間のモニター期間が終了してBT-200の返却期限が迫ってきました。

モニター終了と同時に、最後に「MOVERIO座談会」が開かれるということでエプソン様にご招待頂きましたので参加してまりました。その様子をご紹介致します。

また、ショートプレゼンの時間も頂けるとのことで、私が半年間BT-200を使ってみて、業務での利用を想定して感じたことを喋ってきました。

まずは、一番見たかったのはこれ!



そう、MOBERIO Pro BT-2000です!展示がありましたのでしっかり触ってきました!
装着感は良好で、視界もくっきり、鼻が痛くならない跳ね上げ式が好感でした。


業務用の大本命ではないかと個人的には思っているMOBERIO Pro BT-2000です。
屋外でも見やすくなっている、解像度も上がっているとのこと。
実際に掛けてみると、とにかく楽です。画面が大きいのに、頭で固定するから装着性が非常に高い!長時間かけていられるウェアラブルの形とは、これだ!という確信を得ましたね。

本当に、ウェアラブルを使った経験やBT-200を利用した経験がある方こそ、BT-2000の良さがわかるというものでしょう。

イベントではまずEPSON様から紹介がありました。3月からモニターとしてお借りしたBT-200のイベント振り返りと今後のイベントの紹介。
また6月に業務用モデルとしてBT-2000発表、お値段は30万円台で、9月17日に販売開始したとの事。
そしてBT-2000の開発で苦労した点として、
試作のコントローラーはバッテリーを大きくして長時間動作させ、さらに防塵防滴なので、「弁当箱か!」というぐらい大きくなってしまい、大きさと装着性のバランスをとるのに苦労した、といった話をお伺いできました。

さてBT-2000のポイントとして、私が気に入った点を列挙しておきます。

UIは、手袋をした状態でも操作しやすいようにボタンを作っている。大きめのボタンで設計されている。

バッテリーは2つ積んだ状態。だから電源を入れたまま1つずつ交換が可能!ホットスワップでバッテリー交換可能な訳です。この辺、業務利用をとことん考慮されていますね!

あとは、ディスプレイがフリップアップ機能(跳ね上げ式!)により、邪魔なときには跳ね上げて肉眼で見れる点!この機構はほんと素晴らしいと思います。

音声制御によるハンズフリー制御が可能。

なんと!ステレオカメラ!2台のカメラによりデプスセンシング(奥行きの取得)が出来るようになる。まだまだ精度は低いが、30cm、1mmの距離で。とのこと!

私のショートプレゼンでは業務利用でのウェアラブルの話をしてきました。内容は今まで単眼のウェアラブルディスプレイを業務に利用できないかといろいろ試してきましたが、技術的な問題ではなくて、単眼ウェアラブルの装着性はちょっと疑問視していました。
こんな小さなディスプレイで、本当に業務利用できるのか?
工場のおっちゃん、おばちゃんがつかってくれるのか?
で、行き着いたのが、BT-200や、もちろん弊社のMIRAMAもそうですが、両眼シースルータイプが、業務利用の可能性が一番高いと思う、その点、今回9月に発売とになったEPSON BT-2000はまさに理想の形、といった内容で話させて頂きました。30万円台で防水防滴。業務用としては良いところついてる気がします。












その後、モニター参加者からの色々な意見交換、ディスカッションを行い、発表をしました。内容は記載しませんが、BT-200を実際に半年間使ってみたからこその出た、次のウェアラブルデバイスへのアイディアが多く詰まっており、参加者である私としてもとても勉強になる内容となりました。



最後に、EPSON様からサプライズ。



なんと、返却予定だったMOVERIO BT-200ですが「モニター参加者の皆様に差し上げます」との事!EPSONさん太っ腹!ありがとうございます。

全体的に今回の座談会での収穫はBT-2000の出来がとても良い事を確認できたこと、ディスカッションで色々な意見を聞けたことですね。MOBERIO Pro BT-2000はウェアラブルを使った業務利用に活用できるものと期待しております。今後も研究開発を進めていきたいと思います。

[コラム]EPSON MOVERIO座談会に参加してショートプレゼンをしてきました



EPSON MOVERIO BT-200をモニターとしてお借りしておりましたが、半年間のモニター期間が終了してBT-200の返却期限が迫ってきました。

モニター終了と同時に、最後に「MOVERIO座談会」が開かれるということでエプソン様にご招待頂きましたので参加してまりました。その様子をご紹介致します。

また、ショートプレゼンの時間も頂けるとのことで、私が半年間BT-200を使ってみて、業務での利用を想定して感じたことを喋ってきました。

まずは、一番見たかったのはこれ!



そう、MOBERIO Pro BT-2000です!展示がありましたのでしっかり触ってきました!
装着感は良好で、視界もくっきり、鼻が痛くならない跳ね上げ式が好感でした。


業務用の大本命ではないかと個人的には思っているMOBERIO Pro BT-2000です。
屋外でも見やすくなっている、解像度も上がっているとのこと。
実際に掛けてみると、とにかく楽です。画面が大きいのに、頭で固定するから装着性が非常に高い!長時間かけていられるウェアラブルの形とは、これだ!という確信を得ましたね。

本当に、ウェアラブルを使った経験やBT-200を利用した経験がある方こそ、BT-2000の良さがわかるというものでしょう。

イベントではまずEPSON様から紹介がありました。3月からモニターとしてお借りしたBT-200のイベント振り返りと今後のイベントの紹介。
また6月に業務用モデルとしてBT-2000発表、お値段は30万円台で、9月17日に販売開始したとの事。
そしてBT-2000の開発で苦労した点として、
試作のコントローラーはバッテリーを大きくして長時間動作させ、さらに防塵防滴なので、「弁当箱か!」というぐらい大きくなってしまい、大きさと装着性のバランスをとるのに苦労した、といった話をお伺いできました。

さてBT-2000のポイントとして、私が気に入った点を列挙しておきます。

UIは、手袋をした状態でも操作しやすいようにボタンを作っている。大きめのボタンで設計されている。

バッテリーは2つ積んだ状態。だから電源を入れたまま1つずつ交換が可能!ホットスワップでバッテリー交換可能な訳です。この辺、業務利用をとことん考慮されていますね!

あとは、ディスプレイがフリップアップ機能(跳ね上げ式!)により、邪魔なときには跳ね上げて肉眼で見れる点!この機構はほんと素晴らしいと思います。

音声制御によるハンズフリー制御が可能。

なんと!ステレオカメラ!2台のカメラによりデプスセンシング(奥行きの取得)が出来るようになる。まだまだ精度は低いが、30cm、1mmの距離で。とのこと!

私のショートプレゼンでは業務利用でのウェアラブルの話をしてきました。内容は今まで単眼のウェアラブルディスプレイを業務に利用できないかといろいろ試してきましたが、技術的な問題ではなくて、単眼ウェアラブルの装着性はちょっと疑問視していました。
こんな小さなディスプレイで、本当に業務利用できるのか?
工場のおっちゃん、おばちゃんがつかってくれるのか?
で、行き着いたのが、BT-200や、もちろん弊社のMIRAMAもそうですが、両眼シースルータイプが、業務利用の可能性が一番高いと思う、その点、今回9月に発売とになったEPSON BT-2000はまさに理想の形、といった内容で話させて頂きました。30万円台で防水防滴。業務用としては良いところついてる気がします。












その後、モニター参加者からの色々な意見交換、ディスカッションを行い、発表をしました。内容は記載しませんが、BT-200を実際に半年間使ってみたからこその出た、次のウェアラブルデバイスへのアイディアが多く詰まっており、参加者である私としてもとても勉強になる内容となりました。



最後に、EPSON様からサプライズ。



なんと、返却予定だったMOVERIO BT-200ですが「モニター参加者の皆様に差し上げます」との事!EPSONさん太っ腹!ありがとうございます。

全体的に今回の座談会での収穫はBT-2000の出来がとても良い事を確認できたこと、ディスカッションで色々な意見を聞けたことですね。MOBERIO Pro BT-2000はウェアラブルを使った業務利用に活用できるものと期待しております。今後も研究開発を進めていきたいと思います。

2015年8月21日金曜日

[コラム]どうなった?Android Auto -アプリ公開編-

2015年8月7日金曜日


■はじめに

Android Wear5.0からWatch Faceの作成が可能になり、
なんと5.1.1からは、アンビエントモードが通常のアプリでも実装できるようになりました!!
この機能を使用するとアプリを終了することなく、情報を表示し続けることができます。
Apple WatchにはないAndroid Wear独特の機能。
これを利用すれば、面白いアプリが作れるかもしれません!
早速仕組みをご紹介します。

Android Wear アンビエントモードを実装する


■はじめに

Android Wear5.0からWatch Faceの作成が可能になり、
なんと5.1.1からは、アンビエントモードが通常のアプリでも実装できるようになりました!!
この機能を使用するとアプリを終了することなく、情報を表示し続けることができます。
Apple WatchにはないAndroid Wear独特の機能。
これを利用すれば、面白いアプリが作れるかもしれません!
早速仕組みをご紹介します。

2015年8月3日月曜日



MediaCodecクラスの登場などにより、AudioTrackクラスを使う機会が増えてきました。そこでAudioTrackクラスの使い方について、メディア用語の解説も交えて解説していきます。

[コラム]AndroidのAudioTrackを基礎から理解する



MediaCodecクラスの登場などにより、AudioTrackクラスを使う機会が増えてきました。そこでAudioTrackクラスの使い方について、メディア用語の解説も交えて解説していきます。

2015年7月17日金曜日


はじめに

今回は手頃な価格で人気上昇中の中華IoTモジュールについて
その開発方法や注意事項について紹介いたします。

技適OKな中華IoTモジュールを使いこなす


はじめに

今回は手頃な価格で人気上昇中の中華IoTモジュールについて
その開発方法や注意事項について紹介いたします。

2015年7月16日木曜日

※Android Auto公式サイトより引用 https://www.android.com/intl/ja_jp/auto/

このブログでも何回か触れているAndroid Autoですが、その後どうなっているのでしょうか。
現在のAndroid Autoについてまとめました。

2015/3/20にAndroid Auto公式アプリがリリースされ、
Android Auto対応カーナビも続々発売されています。
しかし、現在利用可能な国はアメリカ、イギリス、オーストラリアだけです。
日本では、以下の日本語公式サイトが存在するものの、まだ利用できません。
https://www.android.com/intl/ja_jp/auto/

Android Autoに対応したアプリも配信されており、Google Playでもまとめられているようですが、
こちらも日本からはアクセスできません。
http://g.co/androidauto

日本でまだ利用できないのは残念ですが、
正式なサービスが始まっているため、いくつかの新情報もあります。
今回は、以下のURLで解説されているAndroid Autoの使用方法についてまとめました。
https://support.google.com/androidauto


■環境

・Android Autoの動作環境

  • Android Autoに対応したAndroid端末(Lollipop)
    車載カーナビとはUSBケーブルで接続します。
    また、カーナビとAndroid端末間ではBluetooth通信も使用します。
  • Android Auto公式アプリ(上記Android端末にインストール必須)
  • Android Autoに対応した車

・Android Autoで未対応の動作

おそらく安全面の理由から、以下の動作は未対応とされています。
  • Android Auto対応アプリ以外の端末操作(車載カーナビとUSBケーブル接続中)
  • テレビ、youtubeなどの動画再生
  • 文字入力キーボードの使用

・その他

  • Android Autoで使用するデータ通信は、Android端末上で発生する量と同等。
    外部と通信するのはあくまでAndroid端末のみ、ということになります。
  • Android Auto使用中、Android端末はUSBケーブルを通じて給電される。
    極端にバッテリーを消耗するAndroid Autoアプリがない限り、バッテリーの心配はなさそうです。
  • GPSが内蔵されている車であれば、Android端末は車側のGPS信号を使用できる。
    仕組みは不明ですが、Android端末側のGPS精度は気にしなくて良いようです。

■画面構成

・ホーム画面

Android Auto開始後、カーナビのディスプレイにはAndroid Autoのホーム画面が表示されます。ホーム画面の構成は以下のようになっています。

※Android Auto公式サイトより引用 https://support.google.com/androidauto
  1. ナビゲーション通知
  2. リマインダー
  3. 音声コマンド
    マイクアイコンをタッチすることで、音声入力が可能になり、以下の操作が行えます。
    ・音楽再生(曲名)
    ・地図のルート検索
    ・電話発信
    ・スケジュールの取得

・アプリ選択

ホーム画面の下部にはアプリカテゴリのアイコンがあり、選択するとAndroid端末内にインストールされているAndroid Auto対応アプリのリストが表示されます。

※Android Auto公式サイトより引用 https://support.google.com/androidauto
  1. ナビゲーション
  2. 電話
  3. ホーム画面
  4. 音楽再生
  5. 車アプリ

■Android Autoの使い方

Android Autoでは音声入力による操作が前提です。
音声入力やその他の操作で以下の機能を使用できます。

・電話

  • 発信(音声入力)
    「Call Cody White」「Call XXX-XXX-XXX」のように、「Call」の後に名前(電話帳に登録されている)や電話番号を言うだけで発信が可能です。

  • 発信(番号入力)
    ホーム画面下部の電話アイコンを押し、表示されるダイヤル画面から発信可能です。

  • 着信応答
    着信を受けると、ホーム画面上にNotificationが表示されます。それをタッチすることで、着信応答できます。

  • 不在着信応答
    不在着信情報は、ホーム画面上のNotificationとして表示されます。それをタッチすることで、不在着信に応答できます。

  • 留守電や通話履歴の参照
    ホーム画面下部の電話アイコンを押し、メニューから選択します。

・テキストメッセージの送信

  • テキスト送信
    「Text Cody White」「Text XXX-XXX-XXX」のように、「Text」の後に名前(電話帳に登録されている)や電話番号を言うだけでテキスト送信機能が起動します。
    アプリの音声ガイダンスに従ってテキスト本文を音声入力し、最終的に「send」で送信、「cancel」で取り止めます。

  • テキスト受信
    受信すると、ホーム画面上にNotificationが表示されます。それをタッチすることで、受信したテキストが音声で読み上げられます。
  • テキスト返信
    「reply」と話すことで、最後に受信したテキストに対する返信を開始します。
    アプリの音声ガイダンスに従ってテキスト本文を音声入力し、最終的に「send」で送信、「cancel」で取り止めます。

・リマインダーの設定

  • 時間ベースのリマインダー
    「Remind me to call John at 7pm.」
    「Remind me to pick up the cake this afternoon.」
    上記のように、正確またはおおよその時刻と合わせて音声入力することで、リマインダーが登録され、その時間になるとHome画面にNotificationが表示されます。
  • 場所ベースのリマインダー
    「Remind me to buy coffee beans when I get to Starbucks.」
    「Remind me to bring in the groceries when I get to my destination.」
    「Remind me to call mom when I get home.」
    上記のように、正確またはおおよその場所と合わせて音声入力することでリマインダーが登録され、その場所に到着するとHome画面にNotificationが表示されます。

・目的地ナビゲーションの取得

  • 音声によるナビ検索
    「Navigate to Union Square, San Francisco」
    「Directions to Philz Coffee.」
    「Directions to 1600 Amphitheatre Parkway, Mountain View.」
    上記のように目的地を音声入力するだけで、ナビが開始されます。

  • 手操作によるナビ検索
    ホーム画面下部のナビゲーションアイコンを押し、操作します。

  • 交通情報の取得
    交通情報に合わせた表示更新はリアルタイムに行われます。メニューの設定から交通情報表示をオフにすることも可能です。

・Google Mapからの目的地候補取得

  • 目的地候補の取得
    ホーム画面下部のナビゲーションアイコンから、人気のスポットや過去に行ったことのある目的地候補を取得できます。

  • カテゴリ検索
    ホーム画面下部のナビゲーションアイコンから、目的地のカテゴリ検索が可能です。

・音楽再生

「play music.」と言うだけで、"I'm feeling lucky"プレイリストがデフォルトで再生されます。
特定の曲やアーティストを指定する場合は、「play」の後に続けて音声入力します。



----------

以上が、Android Autoの使用方法になります。
音声入力によるカーナビ操作は、運転中でもかなり便利そうです。
ただし、それだけ音声入力が肝になるため、
日本語対応には時間がかかっているのかもしれません。
近い将来、日本でもAndroid Autoを使用できるのが待ち遠しいですね。

[コラム]どうなった?Android Auto -使用方法編-

※Android Auto公式サイトより引用 https://www.android.com/intl/ja_jp/auto/

このブログでも何回か触れているAndroid Autoですが、その後どうなっているのでしょうか。
現在のAndroid Autoについてまとめました。

2015/3/20にAndroid Auto公式アプリがリリースされ、
Android Auto対応カーナビも続々発売されています。
しかし、現在利用可能な国はアメリカ、イギリス、オーストラリアだけです。
日本では、以下の日本語公式サイトが存在するものの、まだ利用できません。
https://www.android.com/intl/ja_jp/auto/

Android Autoに対応したアプリも配信されており、Google Playでもまとめられているようですが、
こちらも日本からはアクセスできません。
http://g.co/androidauto

日本でまだ利用できないのは残念ですが、
正式なサービスが始まっているため、いくつかの新情報もあります。
今回は、以下のURLで解説されているAndroid Autoの使用方法についてまとめました。
https://support.google.com/androidauto


■環境

・Android Autoの動作環境

  • Android Autoに対応したAndroid端末(Lollipop)
    車載カーナビとはUSBケーブルで接続します。
    また、カーナビとAndroid端末間ではBluetooth通信も使用します。
  • Android Auto公式アプリ(上記Android端末にインストール必須)
  • Android Autoに対応した車

・Android Autoで未対応の動作

おそらく安全面の理由から、以下の動作は未対応とされています。
  • Android Auto対応アプリ以外の端末操作(車載カーナビとUSBケーブル接続中)
  • テレビ、youtubeなどの動画再生
  • 文字入力キーボードの使用

・その他

  • Android Autoで使用するデータ通信は、Android端末上で発生する量と同等。
    外部と通信するのはあくまでAndroid端末のみ、ということになります。
  • Android Auto使用中、Android端末はUSBケーブルを通じて給電される。
    極端にバッテリーを消耗するAndroid Autoアプリがない限り、バッテリーの心配はなさそうです。
  • GPSが内蔵されている車であれば、Android端末は車側のGPS信号を使用できる。
    仕組みは不明ですが、Android端末側のGPS精度は気にしなくて良いようです。

■画面構成

・ホーム画面

Android Auto開始後、カーナビのディスプレイにはAndroid Autoのホーム画面が表示されます。ホーム画面の構成は以下のようになっています。

※Android Auto公式サイトより引用 https://support.google.com/androidauto
  1. ナビゲーション通知
  2. リマインダー
  3. 音声コマンド
    マイクアイコンをタッチすることで、音声入力が可能になり、以下の操作が行えます。
    ・音楽再生(曲名)
    ・地図のルート検索
    ・電話発信
    ・スケジュールの取得

・アプリ選択

ホーム画面の下部にはアプリカテゴリのアイコンがあり、選択するとAndroid端末内にインストールされているAndroid Auto対応アプリのリストが表示されます。

※Android Auto公式サイトより引用 https://support.google.com/androidauto
  1. ナビゲーション
  2. 電話
  3. ホーム画面
  4. 音楽再生
  5. 車アプリ

■Android Autoの使い方

Android Autoでは音声入力による操作が前提です。
音声入力やその他の操作で以下の機能を使用できます。

・電話

  • 発信(音声入力)
    「Call Cody White」「Call XXX-XXX-XXX」のように、「Call」の後に名前(電話帳に登録されている)や電話番号を言うだけで発信が可能です。

  • 発信(番号入力)
    ホーム画面下部の電話アイコンを押し、表示されるダイヤル画面から発信可能です。

  • 着信応答
    着信を受けると、ホーム画面上にNotificationが表示されます。それをタッチすることで、着信応答できます。

  • 不在着信応答
    不在着信情報は、ホーム画面上のNotificationとして表示されます。それをタッチすることで、不在着信に応答できます。

  • 留守電や通話履歴の参照
    ホーム画面下部の電話アイコンを押し、メニューから選択します。

・テキストメッセージの送信

  • テキスト送信
    「Text Cody White」「Text XXX-XXX-XXX」のように、「Text」の後に名前(電話帳に登録されている)や電話番号を言うだけでテキスト送信機能が起動します。
    アプリの音声ガイダンスに従ってテキスト本文を音声入力し、最終的に「send」で送信、「cancel」で取り止めます。

  • テキスト受信
    受信すると、ホーム画面上にNotificationが表示されます。それをタッチすることで、受信したテキストが音声で読み上げられます。
  • テキスト返信
    「reply」と話すことで、最後に受信したテキストに対する返信を開始します。
    アプリの音声ガイダンスに従ってテキスト本文を音声入力し、最終的に「send」で送信、「cancel」で取り止めます。

・リマインダーの設定

  • 時間ベースのリマインダー
    「Remind me to call John at 7pm.」
    「Remind me to pick up the cake this afternoon.」
    上記のように、正確またはおおよその時刻と合わせて音声入力することで、リマインダーが登録され、その時間になるとHome画面にNotificationが表示されます。
  • 場所ベースのリマインダー
    「Remind me to buy coffee beans when I get to Starbucks.」
    「Remind me to bring in the groceries when I get to my destination.」
    「Remind me to call mom when I get home.」
    上記のように、正確またはおおよその場所と合わせて音声入力することでリマインダーが登録され、その場所に到着するとHome画面にNotificationが表示されます。

・目的地ナビゲーションの取得

  • 音声によるナビ検索
    「Navigate to Union Square, San Francisco」
    「Directions to Philz Coffee.」
    「Directions to 1600 Amphitheatre Parkway, Mountain View.」
    上記のように目的地を音声入力するだけで、ナビが開始されます。

  • 手操作によるナビ検索
    ホーム画面下部のナビゲーションアイコンを押し、操作します。

  • 交通情報の取得
    交通情報に合わせた表示更新はリアルタイムに行われます。メニューの設定から交通情報表示をオフにすることも可能です。

・Google Mapからの目的地候補取得

  • 目的地候補の取得
    ホーム画面下部のナビゲーションアイコンから、人気のスポットや過去に行ったことのある目的地候補を取得できます。

  • カテゴリ検索
    ホーム画面下部のナビゲーションアイコンから、目的地のカテゴリ検索が可能です。

・音楽再生

「play music.」と言うだけで、"I'm feeling lucky"プレイリストがデフォルトで再生されます。
特定の曲やアーティストを指定する場合は、「play」の後に続けて音声入力します。



----------

以上が、Android Autoの使用方法になります。
音声入力によるカーナビ操作は、運転中でもかなり便利そうです。
ただし、それだけ音声入力が肝になるため、
日本語対応には時間がかかっているのかもしれません。
近い将来、日本でもAndroid Autoを使用できるのが待ち遠しいですね。

2015年7月10日金曜日

最近17歳の少年が逮捕されて※1、日本でもその脅威が認知されつつある「ランサムウェア」について調べてみたいと思います。

[コラム]ランサムウェアについて調べてみる

最近17歳の少年が逮捕されて※1、日本でもその脅威が認知されつつある「ランサムウェア」について調べてみたいと思います。

2015年7月9日木曜日


はじめに

mbed nRF51822 に新機能が追加されました。今回は 2015年5月に追加された新機能についてAPI仕様や使用方法について紹介いたします。



BluetoothSMARTデバイスをmbed で開発する(8)


はじめに

mbed nRF51822 に新機能が追加されました。今回は 2015年5月に追加された新機能についてAPI仕様や使用方法について紹介いたします。



2015年6月29日月曜日

腕、手首、指の動きで様々なデバイスをコントロールできるMyo。本記事ではこのMyoの特徴と、利用シーンを考えたいと思います。

▲[外部] Myo The Lab より抜粋


myoとは

myoは、 Thalmic Labs 社によって開発された、腕、手首、指の動きで様々なデバイスをコントロールできるアームバンドで、 手首や指の動きのトラッキングに筋電センサーが使われてるのが特徴です。

筋電センサーとは、筋肉を動かす時に発生する微小電圧を計測するセンサーのことで、この電圧で手首や指の動きを感知することができます。
またmyoは、加速度センサ、ジャイロスコープ、磁気センサも搭載しており、腕の向きや動きをトラッキングするのに使われます。
アウトプットとしては、充電や接続を知らせるLEDと、ジェスチャーが認識されたことを知らせるバイブレータを搭載。
端末との接続はBLEが使われています。

このmyoをパソコンやスマートフォンに接続しジェスチャーを行うことで、端末自体を動かしたり、さらに端末とつながっているデバイスなどをコントロールすることができるのです。

手のジェスチャーには下図のようなDoubleTap、FingerSpread、WaveOut、WaveIn、Fistといった5つのジェスチャーがプリセットで用意されています。

▲[外部] Myo Supportより抜粋

腕の動き(YAW)と、腕の回転(ROLL)、手首をそらす動き(PITCH)も取得できます。

▲[外部] Myo The Lab より抜粋

また開発者は、myoの生のEMGセンサデータを取得することができ、それを元にカスタムジェスチャーを創りだすこともできます。


myo SDKから取得できる情報

myo SDKが受け取れるイベントや、取れる値は下記の通り。

  • Myoが新しく加わった
  • Myoが切り離された
  • Myoと繋がった
  • Myoと切断された
  • Myoが腕につけられた
    • 使用者と腕の相対x軸
  • Myoが腕から外された
  • Myoがアンロックになった
  • Myoがロックされた
  • Myoがポーズを検出した
    • 通常のポーズ
    • こぶしのポーズ
    • 手首を内側に曲げたポーズ
    • 手首を外側に曲げたポーズ
    • 指を広げたポーズ
    • タブルタップ
    • 不明なポーズ
  • Myoが方向(回転)の変化を得た
    • 回転ベクトルのx成分
    • 回転ベクトルのy成分
    • 回転ベクトルのz成分
    • 回転のスカラー成分
  • Myoが加速度の変化を得た
    • ベクトルのx成分
    • ベクトルのy成分
    • ベクトルのz成分
    • ベクトルの長さ
  • Myoがジャイロスコープの変化を得た
    • ベクトルのx成分
    • ベクトルのy成分
    • ベクトルのz成分
    • ベクトルの長さ
  • MyoのRSSIを取得した

他のジェスチャーデバイスと比較して見えるMyoの特徴

Kinect、Leap Motionとの違い

▲[外部] Leap Motion より抜粋

KinectやLeap Motionといったデプスセンサーは、手の動きなどをセンシングすることができますが、センサーを机などに設置する必要があります。また、太陽の赤外線はセンシングにノイズを生むため、屋外での利用は厳しくなります。
Myoは腕に巻き付けるため、身につけたまま行動することができ、屋外でも利用ができるのが特徴です。

Ringとの違い

▲[外部] Ring ZERO Shiny White より抜粋

Ringは指先の動きを細かくトラッキングすることができますが、Ringをつけている指しかトラッキングできません。
Myoは着けている腕の方の指だけでなく手全体の動きをトラッキングすることができます。

Moffとの違い

▲[外部] Moff(モフ) より抜粋

Moffは腕をどの方向にどれくらいの早さで動かしたかをトラッキングすることができます。
Myoも同じことができますが、さらに手首の動きや、指のタップなどをトラッキングすることができます。
また、Moffは独自のアプリケーションを作ることができませんが、MyoはSDKが提供されており自由にアプリケーションを開発することができます。


Myoにしかできない使い方

他のジェスチャーデバイスと比べた場合、Myoの特徴は、動き回りながら利用できることと、手全体や手首を使ったジェスチャーができるところに長けていると言えます。
例えば野球、バスケットボールなど手首を使うスポーツのゲームコントローラーといった感じです。
投げるときの腕の振り、スナップの大きさ、指の本数、曲げ具合を認識し、本当に野球をするのと同じように変化球を投げることができます。


まとめ

Myoを実際に利用した感じでは、細かいアクションには向いていません。Moffのように元気に動きまわって使うシーンに向いている感じがしました。
Myoはすでに自由にアプリを作成できるSDKや、アプリを公開できるストアも用意されています。
みんながはしゃいで遊べて、新しい体験を与えるようなアプリを作ってみてはどうでしょうか。

[コラム] 筋電センサーアームバンド「myo」は、動き回りながらでも手の動きがトラッキングできるガジェット

腕、手首、指の動きで様々なデバイスをコントロールできるMyo。本記事ではこのMyoの特徴と、利用シーンを考えたいと思います。

▲[外部] Myo The Lab より抜粋


myoとは

myoは、 Thalmic Labs 社によって開発された、腕、手首、指の動きで様々なデバイスをコントロールできるアームバンドで、 手首や指の動きのトラッキングに筋電センサーが使われてるのが特徴です。

筋電センサーとは、筋肉を動かす時に発生する微小電圧を計測するセンサーのことで、この電圧で手首や指の動きを感知することができます。
またmyoは、加速度センサ、ジャイロスコープ、磁気センサも搭載しており、腕の向きや動きをトラッキングするのに使われます。
アウトプットとしては、充電や接続を知らせるLEDと、ジェスチャーが認識されたことを知らせるバイブレータを搭載。
端末との接続はBLEが使われています。

このmyoをパソコンやスマートフォンに接続しジェスチャーを行うことで、端末自体を動かしたり、さらに端末とつながっているデバイスなどをコントロールすることができるのです。

手のジェスチャーには下図のようなDoubleTap、FingerSpread、WaveOut、WaveIn、Fistといった5つのジェスチャーがプリセットで用意されています。

▲[外部] Myo Supportより抜粋

腕の動き(YAW)と、腕の回転(ROLL)、手首をそらす動き(PITCH)も取得できます。

▲[外部] Myo The Lab より抜粋

また開発者は、myoの生のEMGセンサデータを取得することができ、それを元にカスタムジェスチャーを創りだすこともできます。


myo SDKから取得できる情報

myo SDKが受け取れるイベントや、取れる値は下記の通り。

  • Myoが新しく加わった
  • Myoが切り離された
  • Myoと繋がった
  • Myoと切断された
  • Myoが腕につけられた
    • 使用者と腕の相対x軸
  • Myoが腕から外された
  • Myoがアンロックになった
  • Myoがロックされた
  • Myoがポーズを検出した
    • 通常のポーズ
    • こぶしのポーズ
    • 手首を内側に曲げたポーズ
    • 手首を外側に曲げたポーズ
    • 指を広げたポーズ
    • タブルタップ
    • 不明なポーズ
  • Myoが方向(回転)の変化を得た
    • 回転ベクトルのx成分
    • 回転ベクトルのy成分
    • 回転ベクトルのz成分
    • 回転のスカラー成分
  • Myoが加速度の変化を得た
    • ベクトルのx成分
    • ベクトルのy成分
    • ベクトルのz成分
    • ベクトルの長さ
  • Myoがジャイロスコープの変化を得た
    • ベクトルのx成分
    • ベクトルのy成分
    • ベクトルのz成分
    • ベクトルの長さ
  • MyoのRSSIを取得した

他のジェスチャーデバイスと比較して見えるMyoの特徴

Kinect、Leap Motionとの違い

▲[外部] Leap Motion より抜粋

KinectやLeap Motionといったデプスセンサーは、手の動きなどをセンシングすることができますが、センサーを机などに設置する必要があります。また、太陽の赤外線はセンシングにノイズを生むため、屋外での利用は厳しくなります。
Myoは腕に巻き付けるため、身につけたまま行動することができ、屋外でも利用ができるのが特徴です。

Ringとの違い

▲[外部] Ring ZERO Shiny White より抜粋

Ringは指先の動きを細かくトラッキングすることができますが、Ringをつけている指しかトラッキングできません。
Myoは着けている腕の方の指だけでなく手全体の動きをトラッキングすることができます。

Moffとの違い

▲[外部] Moff(モフ) より抜粋

Moffは腕をどの方向にどれくらいの早さで動かしたかをトラッキングすることができます。
Myoも同じことができますが、さらに手首の動きや、指のタップなどをトラッキングすることができます。
また、Moffは独自のアプリケーションを作ることができませんが、MyoはSDKが提供されており自由にアプリケーションを開発することができます。


Myoにしかできない使い方

他のジェスチャーデバイスと比べた場合、Myoの特徴は、動き回りながら利用できることと、手全体や手首を使ったジェスチャーができるところに長けていると言えます。
例えば野球、バスケットボールなど手首を使うスポーツのゲームコントローラーといった感じです。
投げるときの腕の振り、スナップの大きさ、指の本数、曲げ具合を認識し、本当に野球をするのと同じように変化球を投げることができます。


まとめ

Myoを実際に利用した感じでは、細かいアクションには向いていません。Moffのように元気に動きまわって使うシーンに向いている感じがしました。
Myoはすでに自由にアプリを作成できるSDKや、アプリを公開できるストアも用意されています。
みんながはしゃいで遊べて、新しい体験を与えるようなアプリを作ってみてはどうでしょうか。

2015年6月19日金曜日


Appleの開発者のイベント、WWDC2015に弊社からも参加いたしました。今回の勉強会ではWWDC2015の報告会とAppleWatchの新機能、そしてAutoLayoutの新機能やiOS9からiPadに搭載されるMultitaskingについて発表を行いました!


[コラム]WWDC2015報告会&iOS&AppleWatch勉強会を開催しました


Appleの開発者のイベント、WWDC2015に弊社からも参加いたしました。今回の勉強会ではWWDC2015の報告会とAppleWatchの新機能、そしてAutoLayoutの新機能やiOS9からiPadに搭載されるMultitaskingについて発表を行いました!


2015年6月9日火曜日


Appleが毎年開発しているWWDCが現地時間の6月9日から始まりました。
キーノートでは「Mac OS X」「iOS」「watchOS」のそれぞれのアップデート内容が発表されました。


引用(http://www.apple.com/live/2015-june-event/)

Mac OS X

次バージョンの名前はEl Capitanです。
余談ですが、El Capitanはヨセミテの中にあるようです。

メール

iOSのような操作でメールの削除などができるようになりました。
また、別窓(例えばウェブ画面)から作成中のメールに画像を添付することができるようになりました。

Safari

タブを左側に溜められるようになりました。
また、音声再生中ならば検索窓に音声を静音することができます。

検索

あいまい検索やスポーツ結果・天気なども検索できるようになりました。

2分割機能

文字通りウィンドウを2分割する機能です。
今まではサードパーティアプリを導入しなければならなかったので
個人的にはこの機能の追加は喜ばしいです。

メタル

昨年iOSに追加された機能がMacでも導入されます。

リリース時期

開発者版は本日から、一般向けベータ版は7月から、正式リリースは秋予定となっています。

引用(http://www.apple.com/live/2015-june-event/)

iOS

siri

あいまいな検索ワードでも結果が返ってくるようになりました。
デモでは去年撮った写真をsiriにお願いして表示していました。

プロアクティブアシスタント

登録していない番号からの着信でも着信相手を予測して表示するデモがありました。
こちらはAPIが用意されるようです。

ApplePay

導入店のカードの追加を発表し、来月からイギリスでも利用できるようです。
 

Wallet

Passbookアプリが廃止されて、Walletになります。

ノート

タイトルや本文、チャックボックスと写真、マップが追加できるようになりました。

マップ

公共機関が表示されるようになるようですがアップデート都市に日本の都市は見当たりませんでした。
 

ニュースアプリ

レイアウトなどが変更されましたがアメリカ、イギリス、オーストラリアから提供が開始されます。
 

iPad

キーボード

カット、ペースト、コピーがのショートカットが追加されました。

マルチタスク機能

1画面に2アプリが起動ができるようになりました。
また最大50:50のサイズで表示できます。
こちらはAPIが提供されて自動レイアウトで調整が必要なようです。
この発表を聞いてみんなオーという声を出していました。
世界中の人がマルチタスクで苦労しているということが分かった。


Swift2

機能強化が図られて今年中にオープンソースとして提供されます。
これを聞いて今日一番の盛り上がりでした。
 

リリース時期

開発者版は本日から、一般向けベータ版は7月から、正式リリースは秋予定となっています。


引用(http://www.apple.com/live/2015-june-event/)

watchOS

文字盤

写真やアルバムタイムラプスが表示できるようになりました。
   

タイムトラベル

デジタルクラウンを回して時計の時間を動かして予定を確認できます。

友達

グループ化が追加されました。
   

メール

返信ができるようになりました。
ただ返信方法は音声入力となっています。

通話

FaceTimeオーディオに対応されました。

API

WatchKit強化されました。
デジタルクラウン開放されました。
 

リリース時期

開発者版は本日から、正式リリースは秋予定となっています。  


One more thing...

内容はリーク通りの音楽配信サービスでした。
リークでみんな知っていたからか周りの反応は、はいはいという感じで早速片付けをして帰る人もいたぐらいでした。

まとめ

駆け足となりましたが、本日キーノートで発表された内容をお伝えさせていただきました。
例年のように新しいデバイスの発表はありませんでしたが、watchOS2は次のApple Watchへの期待が高まるアップデートだと思います。

現地速報 SwiftのOSS化を発表 in Apple WWDC 2015


Appleが毎年開発しているWWDCが現地時間の6月9日から始まりました。
キーノートでは「Mac OS X」「iOS」「watchOS」のそれぞれのアップデート内容が発表されました。


引用(http://www.apple.com/live/2015-june-event/)

Mac OS X

次バージョンの名前はEl Capitanです。
余談ですが、El Capitanはヨセミテの中にあるようです。

メール

iOSのような操作でメールの削除などができるようになりました。
また、別窓(例えばウェブ画面)から作成中のメールに画像を添付することができるようになりました。

Safari

タブを左側に溜められるようになりました。
また、音声再生中ならば検索窓に音声を静音することができます。

検索

あいまい検索やスポーツ結果・天気なども検索できるようになりました。

2分割機能

文字通りウィンドウを2分割する機能です。
今まではサードパーティアプリを導入しなければならなかったので
個人的にはこの機能の追加は喜ばしいです。

メタル

昨年iOSに追加された機能がMacでも導入されます。

リリース時期

開発者版は本日から、一般向けベータ版は7月から、正式リリースは秋予定となっています。

引用(http://www.apple.com/live/2015-june-event/)

iOS

siri

あいまいな検索ワードでも結果が返ってくるようになりました。
デモでは去年撮った写真をsiriにお願いして表示していました。

プロアクティブアシスタント

登録していない番号からの着信でも着信相手を予測して表示するデモがありました。
こちらはAPIが用意されるようです。

ApplePay

導入店のカードの追加を発表し、来月からイギリスでも利用できるようです。
 

Wallet

Passbookアプリが廃止されて、Walletになります。

ノート

タイトルや本文、チャックボックスと写真、マップが追加できるようになりました。

マップ

公共機関が表示されるようになるようですがアップデート都市に日本の都市は見当たりませんでした。
 

ニュースアプリ

レイアウトなどが変更されましたがアメリカ、イギリス、オーストラリアから提供が開始されます。
 

iPad

キーボード

カット、ペースト、コピーがのショートカットが追加されました。

マルチタスク機能

1画面に2アプリが起動ができるようになりました。
また最大50:50のサイズで表示できます。
こちらはAPIが提供されて自動レイアウトで調整が必要なようです。
この発表を聞いてみんなオーという声を出していました。
世界中の人がマルチタスクで苦労しているということが分かった。


Swift2

機能強化が図られて今年中にオープンソースとして提供されます。
これを聞いて今日一番の盛り上がりでした。
 

リリース時期

開発者版は本日から、一般向けベータ版は7月から、正式リリースは秋予定となっています。


引用(http://www.apple.com/live/2015-june-event/)

watchOS

文字盤

写真やアルバムタイムラプスが表示できるようになりました。
   

タイムトラベル

デジタルクラウンを回して時計の時間を動かして予定を確認できます。

友達

グループ化が追加されました。
   

メール

返信ができるようになりました。
ただ返信方法は音声入力となっています。

通話

FaceTimeオーディオに対応されました。

API

WatchKit強化されました。
デジタルクラウン開放されました。
 

リリース時期

開発者版は本日から、正式リリースは秋予定となっています。  


One more thing...

内容はリーク通りの音楽配信サービスでした。
リークでみんな知っていたからか周りの反応は、はいはいという感じで早速片付けをして帰る人もいたぐらいでした。

まとめ

駆け足となりましたが、本日キーノートで発表された内容をお伝えさせていただきました。
例年のように新しいデバイスの発表はありませんでしたが、watchOS2は次のApple Watchへの期待が高まるアップデートだと思います。

2015年6月5日金曜日

はじめに

BLEは省電力であることが最大の特徴ではありますが、使い方によっては電池の減りが早かったり
以外なな落とし穴に陥る場合があります。
今回は消費電力を下げるためのアプローチについて掲載いたします。

BluetoothSMARTデバイスをmbed で開発する(7)

はじめに

BLEは省電力であることが最大の特徴ではありますが、使い方によっては電池の減りが早かったり
以外なな落とし穴に陥る場合があります。
今回は消費電力を下げるためのアプローチについて掲載いたします。

Related Posts Plugin for WordPress, Blogger...