USB シリアル (mbed)


20140311usb_mbed

Android から USB シリアルで通信します。
USB シリアル機器には、 mbed を使います。

ソースコードは Google Code に置いています。

mbed の USB インタフェースは下記のとおりです。

VendorId : 3368
ProductId : 516

Interface 0
	Class : Mass Storage Devices Class
	Subclass : SCSI transparent command set
	Protocol : BBB Bulk-Only
Endpoint 130
	Direction : IN - device to host
	Transfer Type : Bulk
Endpoint 2
	Direction : OUT - host to device
	Transfer Type : Bulk

Interface 1
	Class : CDC (Communications Device Class)
	Subclass : ACM (Abstract Control Model)
	Protocol : AT Commands: V.250 etc
Endpoint 129
	Direction : IN - device to host
	Transfer Type : Interrupt

Interface 2
	Class : CDC (Communications Device Class) Data
	Subclass : Data Interface
Endpoint 133
	Direction : IN - device to host
	Transfer Type : Bulk
Endpoint 5
	Direction : OUT - host to device
	Transfer Type : Bulk

Arduino Uno と 同じコード では、うまくいかなった。
controlTransfer が失敗して、ボーレートの変更ができませんでした。
原因は、controlTransfer の index が 0 固定だったためです。
参考にしたコードは、どれもそうなっていたので。

Arduino Uno では、CDC ACM は、Interface 0 ですが。
mbed では、Interface 1 です。
そこで、CDC ACM の Interface 番号を取得して、controlTransfer の index に使用しました。

注記
index = Interface 番号というは、いまひとつ確信がないのですが。
USB の仕様には Interface を特定するものという記述があります。

参考
USB Control Transfers


USB シリアル (Arduino)


20140301usb_cdc_sample

Android から USB シリアルで通信します。
USB シリアル機器には、 Arduino Uno を使います。

ソースコードは Github に置いています。

Arduino Uno の USB インタフェースは下記のとおりです。

VendorId  : 9025
ProductId  : 67
Interface 0
  Class : CDC ( Communication Devices Class ) Interface
  Subclass : ACM ( Abstract Control Model )
  Protocol : AT Commands: V.250
Endpoint 0
  Direction : IN device to host
  Transfer Type : Interrupt
Interface 1
  Class : CDC ( Communication Devices Class ) Data
  Subclass : Data Interface
Endpoint 0
  Direction : OUT host to device
  Transfer Type : Bulk  
Endpoint 1
  Direction : IN device to host
  Transfer Type : Bulk

ソースコードの簡単な説明
(1) 送信
送信 UsbEndpoint を取得して、bulkTransfer で送信する
(2) 受信
受信 UsbEndpoint を取得して、bulkTransfer で受信する
受信はいつ来るのは分からないので、Thread でエンドレスループにする。
UIスレッドからは実行できないので、メッセージ・ハンドラーを介して、受け取る。
(3) ボーレートの設定
controlTransfer で設定する。
Request Code は SET_LINE_CODING ( 20h ) です。
Line Coding Format は7バイト構成です。
 0-3 バイト : ボーレート
 4 バイト : ストップビット長
 5 バイト : パリティ種別
 6 バイト : データ長

参考
Class definitions for Communication Devices
IMPLEMENTING USB COMMUNICATION DEVICE CLASS (CDC) ON SiM3U1XX MCUS
USB ホスト
Android USB Host + Arduino: How to communicate without rooting your Android Tablet or Phone
usb-serial-for-android
PhysicaloidLibrary


Android で NTP を使う (Apache)


20140207ntp_client

Android で NTP を使う方法を調べていたら、
Apache Commons Net を使う方法を見つけました。
試してみたところ、すんなり動きました。
ClockSync と比較してみたところ、2ms の違いがありますが、実用的な範囲です。

20140207clock_sync

ソースは code.google で公開しています。
なお、Apache Commons Net は含まれていませんので、別途ダウンロードしてください。

参考
Apache Commons Net
NTPSync


Android で NTP を使う (AOSP)


20140206ntp_client

Android で NTP を使う方法を調べていたら、
AOSP の中に SntpClient.java というコードを見つけました。
@hide なので、直接は利用できませんが。
コピーして使ってみたところ、すんなり動きました。

ClockSync と比較してみたところ、3ms の違いがありますが、実用的な範囲です。

20140206clock_sync

ソースは code.google で公開しています。

AOSP には、その他にも config.xml50-ntp.conf に NTP 関連の記述があります。


マウスの軌跡を表示する


20130703mouse_device20130703mouse_trace

マウスの移動した軌跡を表示するアプリを作ってみました。
左ボタンで開始、右ボタンで終了です。
ホイールで軌跡の色が変わります。
ホイールボタンで軌跡が消えます。

ソースコードは code.google にて公開しました。

以下、解説です。

デバイス属性
マウスのデバイス属性を見ると、下記の座標軸があります。
(1) AXIS_X min=0 max =719
(2) AXIS_Y min=0 max=1279
この2つは、マウスカーソルの表示されている画面上の座標です。

(3) AXIS_VSCROLL min=-1 max=1
マウスのホイールのイベント情報です。上に回すと1、下に回すと -1 になります。
実際には、4 や 5 まで取得できました。

(4) AXIS_PRESSURE min=0 max=1
マウスのボタンのイベント情報です。クリックすると 1 になります。

MotionEvent
MotionEvent を使って、実際に取得できるイベントは、下記の3つです。

(1) onHoverEvent
– ACTION_HOVER_ENTER:
– ACTION_HOVER_MOVE
– ACTION_HOVER_EXIT

マウスの移動を通知します。
getX と getY を使って、画面上の座標を取得できます。
なお、getX は getAxisValue( AXIS_X ) の別名です。

(2) onTouchEvent
(2-1)
– ACTION_DOWN
– ACTION_UP

getButtonState を使って、どのボタンが押されたかを取得できます。
– BUTTON_PRIMARY 左のボタン
– BUTTON_SECONDARY 右のボタン
– BUTTON_TERTIARY 真ん中(ホイール)のボタン

(2-2)
– ACTION_MOVE

onHoverEvent と同様に、マウスの移動を通知します。

(3) onGenericMotionEvent
– ACTION_SCROLL

マウスのホイールの変化を検出します。
getAxisValue( AXIS_VSCROLL ) を使って、変化量を取得できます。

注意
同時に検出できるボタンの数は1つです。
同時に複数のボタンを押しても、2つ目以降は無視されるようです。


UserManager – Android 4.2


20130603muti_user

Android 4.2 から、マルチユーザ用のライブラリとして、UserManagerUserHandle が追加されました。
これで取得できる情報は、SerialNumber だけです。
これは、owner が 0 (ゼロ)で、ユーザを増やす毎に、10, 20, 30 という番号が付与されます。

UserHandle handle = Process.myUserHandle();     
UserManager manager = (UserManager) getSystemService( USER_SERVICE );
int number = manager.getSerialNumberForUser( handle );

SerialNumber は、ローカル領域の識別などに使われます。
シングルユーザ・モードのとき
 /data/data/<プロジェクト名>/
マルチユーザ・モードのとき
 /data/user//<プロジェクト名>/
20130630multi_user_dir_single
20130630multi_user_dir_multi

なお、UserManagerのソース を見ると、getUsers という隠しメソッドが用意されています。
ユーザの一覧が取得できるようです。


日本語用のキーマップを追加する


20130611keymap_japanese_106

日本語用のキーマップ は Linux redhat から拝借します。
/lib/kbd/keymaps/i386/qwerty/jp106.map.gz
jp106.map と 英語用の keyboard_layout_english_us.kcm を元に、日本語用の kcm ファイルを作成します。

変更方法
(1) キーレイアウトを変更する
英語の LEFT_BRACKET の位置にあるキーは、日本語では AT になる。
LEFT_BRACKET のキー番号は 26番で、キーレイアウト・ファイル qwerty.kl に定義されている。
下記のように記述する

map key 26  AT

(2) キーを追加する
KeyEvent には日本語の YEN や RO が定義されています。
( それなら日本語キーマップも用意して欲しいものだ )
下記のように記述する

key YEN {
    label:                              '¥u00a5'
    base:                               '¥u00a5'
    shift:                              '|'
}

ソースコードは code.google にて公開しています。

補足
日本語用のキーマップは、Google Play で配布されています。
それらを使うほうが手っ取り早いです。
(1) KCM for 日本語106/109キーボード
(2) 日本語106/109キーボードレイアウト

参考
Key Character Map Files
Key Layout Files
Android4.1で日本語配列キーボード(USB/Bluetooth)を使えるようにする
KCM for Japanese 106/109 Keyboard


キーマップを追加する


20130610keymap_english_us

Android 4.1 (API 16) から、User-installable keymaps 機能が追加されました。
AOSP にソースコードが公開されています
platform/frameworks/base/packages/InputDevices/

少しだけ解説を。
src に、BroadcastReceiver を継承した InputDeviceReceiver.java を記述します。
res/row に、kcm 形式のキーマップを配置します。
res/xml に、名称と kcm の対応表 keyboard_layouts.xml を配置します。
AndroidManifest.xml の receiver に InputDeviceReceiver を記述します。
receiver の meta-data に keyboard_layout を記述します。

キーマップを追加する。
手抜きをして、既存の英語用キーマップを使います。
keyboard_layout_english_us.kcm
名称は区別がつくように変更します。
English (US) – ohwada

ソースコードは code.google にて公開しています。

参考
JBで日本語キーボードマップ


キーボードが接続されたことを検出する


0130606input_manager_sample_2

Android 4.1 (API 16) から InputDeviceListener が追加されました。
キーボードなどの入力デバイスが接続されると、InputDeviceListener#onInputDeviceAdded に デバイスID が通知されます。

留意点
キーボードが接続されると、Activity が再起動されます。
これを抑止するには、AndroidManifest.xml の activity に下記を追加します。

android:configChanges="keyboard|keyboardHidden" 

ソースコードは code.google にて公開しています。

参考
JBで追加されたFrameworkの機能InputManagerについて
AndroidManifest.xml − ソフトウェア技術ドキュメントを勝手に翻訳


入力デバイスの一覧を取得する


20130605input_manager_sample_1

Android 4.1 (API 16) から InputManager が追加されました。
入力デバイスの一覧を取得するには、InputManager#getInputDeviceIds を使用します。

ソースコードは code.google にて公開しています。

参考
JBで追加されたFrameworkの機能InputManagerについて