Windows 8 で Android Beam を受信する

SONY RC-S380

確定申告用にRC-S370を持っていましたが、どうやら、RC-S380がWindows 8対応なNFCリーダー・ライターなそうなので、試しに買ってみました。

f:id:espresso3389:20121012165046j:plain

まだ、Windows 8はリリースされていませんが、箱には、Windows 8 Compatibleのロゴがありました。

f:id:espresso3389:20121012165059j:plain

RC-S370から変わったところ

ハード的なアップデートは最小限みたいです。

f:id:espresso3389:20121012165206j:plain

RC-S380になっても依然として、miniUSB。もう、miniUSBのケーブルなんていらないし、microUSBに統一してくれても良さそうですが・・・。

f:id:espresso3389:20121012165220j:plain

ちゃんと総務省指定AC-12005になってます。

f:id:espresso3389:20121012185923j:plain

ドライバ

Windows 8で利用するには、FeliCa関係のいろいろがいらなければ、次のドライバをインストールするだけです。

NFCポートソフトウェア

Android Beam

なぜか、手持ちのNexus 7とGalaxy NoteではAndroid Beamできないのですけど、Windows 8とはちゃんとNFC通信できます。

確認した限りでは、Windows 8は、

・URLの受信
・メールの受信
・不明な通信に対するGoogle Playページへのナビゲーション

は標準で対応できている様ですが、それ以外は電話番号も、GPSも受け取ってくれません。それどころか、画像を送ろうとすると、それ以降、NFC通信が出来なくなってしまいます・・・。これはドライバの問題なんでしょうかね・・・。

nasne + Xperia acro HD (IS12S)

こっちについても書いておかねばなるまい。
発売延期になったのに、Amazon予約組だったので一度届いてしまったが、HDD不良で動作せず、交換処理で、昨日、やっと届いたnasne。

しかしながら、うちには、PS3/torneはありませんし、Sony Tablet Sは誰かさんのところにドナドナ状態なのでやっぱりありません。BRAVIAは寝室にありますが、奥様が就寝中なので、そこでテストするわけにもいきませぬ。

ということで、手元のXperia acro HD(IS12S)、ICSにアップデート済みでのテスト。

チャントル経由での録画はちゃんと動きます。まぁ、当たり前なんですけど。

Connected Devicesで、nasneを選択すると、ライブチューナでちゃんとリアルタイム視聴できます(本当は、30秒程度遅延がある)。

f:id:espresso3389:20120831045846p:plain

それで、じゃぁ、地デジのスクリーンショットが採れるのか?っていうことはなく、ちゃんと地デジのレイヤーはOSによってキャプチャ禁止に設定されています。

f:id:espresso3389:20120831045940p:plain

これじゃちゃんと動いているのかわからないでしょうから、カメラで撮影した地デジライブチューナの動作の様子:

f:id:espresso3389:20120831044937j:plain

ちなみに、動画を選択してから再生が始まるまでは、15秒ぐらい待たされる感じです。

Smart Wireless Headset pro

ソニエリというか、SonyのSmart Wireless Headset proExpansysで購入した。5/31の深夜に注文したら、6/1の昼過ぎには届くという、なんていうAmazon Prime状態。価格は、今のところ、¥10,390。これに、輸送費(今回は、FedEx Priority)で、合計、\12,339。思ったよりも安い。

当然、Xperia acro HDと連携させるのが目的なんだけど、別に今までもMW600使ってたし、ボリューム調整が面倒な以外は、別に困っているわけではなかった。

何を期待していたのかと言えば、Androidならではのアプリによる連携。Google Playに、Smart Wireless Headset proというまんまの名前のアプリがあって、これで、音楽を聴いたり、電話のヘッドセットとして利用したりする以上のことが出来るらしいという話。いろんな通知が来ると便利だよねぇと。

あとは、MW600よりもデザインが好みだなぁと。

FMラジオとか付いているけど、これは海外物のいつものパターンで、どうせ、TOKYO FM (80.0MHz)とかは聴けないのでどうでも良い。

パッケージ

f:id:espresso3389:20120601151753j:plain

音はドイツのwww.testfactory.deっていうところでテストされていて、Sound Quality: excellentなんだそうだ。ふーん。

f:id:espresso3389:20120601151852j:plain

で、英国仕様なので、ACアダプタがでかい奴なんですが、Expansysで買ったので、Expansysが英国仕様のアダプタを変換するプラグと、USB ACアダプタをオマケで付けてくれました。

f:id:espresso3389:20120601152151j:plain

付属品

ACアダプター、microSD 2GB、microSDカードリーダー、ヘッドフォン、クリップ、イヤーピース(予備、サイズ違い)、USB A -> micro A変換ケーブル。

f:id:espresso3389:20120601153026j:plain

本体

"Smart Wireless Headset pro User guide"には、ペアリングすると時計が表示されるとありますが、実際には、一度、Smart Wireless Headset pro側の電源を切って、再接続しないと、時計が出てきませんでした。最初、ペアリングの仕方がAndroid Phone用と、普通のPhone用の両方書かれていたので、時計が出ないのはペアリングがおかしいんだと思って、何度もリセットしたりしながら試行錯誤しました。

f:id:espresso3389:20120601182702j:plain

見て分かるとおり、文字化けしまくりです。これは、今後、日本語版が正式に発売開始された頃にファームウェアアップグレードがあるのか、それともこのまんまなのかは興味深いところです。

f:id:espresso3389:20120601182446j:plain
f:id:espresso3389:20120601182352j:plain

全体的にグロッシーブラックっていう感じではあるんですが、先っちょの色が変わっている部分は、帯で繋がっておりパカッと開きます。帯が一体成形じゃないので、強度的にはどうなんでしょうかとは思いますが、ここの中に、microSDスロットと、USB接続用のmicro USB Aコネクタがあります。

f:id:espresso3389:20120601153725j:plain

で、このUSBコネクタは、充電専用ではなく、microSDが刺さっていると、PC接続時にはマスストレージにもなります。

f:id:espresso3389:20120601153818j:plain

うれしいことに、充電中でも本体は動作するので、電池が足りなくなってきても、充電しながら音楽を聴くことは一応出来ます。そんなことをする必要があるシチュエーションは少ないでしょうが・・・。

付属ヘッドフォン

ちなみに、付属しているヘッドフォンは、普通の3極ステレオミニプラグです。僕は、愛用のBose® IE2があるのでそれで取り替えました。個人的に、オープンエアーじゃないものは疲れるので、音に関しては確認すらしていません。

f:id:espresso3389:20120601182727j:plain

f:id:espresso3389:20120601182747j:plain

いわゆるきしめんケーブルなので、束ねやすくて、絡まりにくいところは評価すべき部分だと思います。

f:id:espresso3389:20120601153338j:plain

付属microSDカードリーダー

SDカードリーダーは、ロゴがソニエリのまんまです。

f:id:espresso3389:20120601153234j:plain
f:id:espresso3389:20120601153310j:plain

ソフト面

ペアリング端末の表示

f:id:espresso3389:20120601175735j:plain

再生中楽曲の情報

<<後からいろいろ分かったので大幅に修正>>

Xperia acro HD(IS12S)に標準で入っている音楽プレイヤーとの連携では、アーティスト名、曲名共に、マルチバイト系の文字が一部というかほとんど表示できないことを除けば、表示できるようになりました。

ちなみに、これは、「松たか子」、「a piece of life」と表示されているところです。

f:id:espresso3389:20120602192044j:plain

ただし、僕はPlayerProという音楽プレイヤーを使っているのですが、これだと曲の情報は何にも表示できません。

f:id:espresso3389:20120601181049j:plain

また、試してみたところ、Galaxy Note SC-05Dでも、標準の音楽プレイヤーと連携できました。

f:id:espresso3389:20120602193212j:plain

AVRCP1.3? on Android

<<僕の勘違いで、標準プレイヤーでは一般的にAndroidの制限にかかわらず文字情報が表示されるそうです。教えてくれた人有り難うございます。>>

で、Xperiaじゃない機種に接続してみて分かったことですが、この連携にLiveWireマネージャは必須ではないようです。つまり、素のAndroidにそのままBluetoothで接続すれば曲名が出てきます。今まで、曲名表示は、ICSにならないと無理的にAVRCP1.3対応できないから無理っていう話だったのに、一体どんなテクノロジーを使っているのかさっぱり分かりません。

マルチポイント対応

すばらしいのが、二つのデバイスとペアリングして、好きなときに再生するデバイスを自由に切り替えることが出来ること。[|<<]、[>>|]で簡単に切り替えられるのは予想以上に便利です。

f:id:espresso3389:20120602193730j:plain
f:id:espresso3389:20120602193743j:plain

日本語対応状況・・・

どうも、フォントが足らないみたいですね。

一応、電話を検索(電話履歴を表示)と表示したいのだろうけど・・・。これは、この辺の表示情報は、Android側のアプリから転送されてくるようで、この機器の言語設定をEnglishにしたところで、問答無用に日本語になります(つまり、Android側の言語設定が反映される)。

f:id:espresso3389:20120601175106j:plain)

一方で、僕の名前はちゃんと表示される。

f:id:espresso3389:20120601175904j:plain

Twitterは、名前とつぶやきの時刻(?)が表示されて居るっぽいが・・・。

f:id:espresso3389:20120601180221j:plain

f:id:espresso3389:20120601182624j:plain

結論

音質に関しては、僕はそんなにこだわりがないので何ともな部分があるんですが、機能面、操作性どれをとっても、MW600引退確定っていう感じです。
これは日本で発売されたら、おそらくベストバイになるんではなかろうかというクオリティです。

その他

Expansysがオマケで付けてくれたUSB ACアダプターは、付属のUSB A -> micro A変換ケーブルに接続すれば使えます。

f:id:espresso3389:20120601153358j:plain

MapView用のAPI Keyを署名から自動判別したい

Android上で、MapViewを使おうとすると、API Keyをlayout.xmlに書き込まないといけない。
さらに、このAPI Keyはアプリの署名から生成されるので、デバッグ用の署名(debug.keystore)とリリース用の署名で別々のモノを使わないといけない。
そうすると、リリース時にAPI Keyを入れ替えるだけのためにコードを修正しないといけなくなるわけで、スゲーめんどくさいし、間違えて、リリース用のAPI Keyをリポジトリにcommitしちゃったりして周りに迷惑を掛けたりして・・・みたいな事になる。
これに関して、

Android ApiキーをRelease版とDebug版で切り替える方法

の様なことをやっている方もいるのだけども、正直、android:debuggableを見るのも微妙な気がする。というか、android:debuggable使ってない・・・。

ので、apkの署名で使うAPI Keyを切り替えようと考えました。

要は、アプリ上で、

MapView mapView = new MapView(this, getMapApiKey());

のような感じで署名に対応したAPI Keyを自動的に返してくれるといいなぁと。

元ネタは、たまたま、この記事を見つけたから。

「アプリケーション(.apk)の自己署名を検証する」

今回は、apkの署名がデバッグ用とリリース用で違うから問題なわけで、それを検出して、対応するAPI Keyを貰えれば良い。で、Google様から貰えるAPI Keyは、署名に対応しているので、署名を文字列化したものを直接コードに挿入したいところなんだけど、署名をそのまま書き込むのは気が引けるのと、そもそも、文字列としては極めてでかいことなど、どうなんだろうという感じなので、

Sign Up for the Android Maps API

にあるように署名のMD5で比較するようにする。

ということで、ほぼ丸ままコピペ出来るコード。例外処理はいい加減ですが。コード中の、XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XXの部分は、Google様からAPI Keyを貰うときに渡したフィンガープリントの文字列をそのまま書いて貰って、その下のAPI Keyの部分は対応するキーに。複数のプロジェクトで共有しているモジュールの場合は、全部のプロジェクト用の対応をここに追加してもいいかもしれない。

// パッケージ署名に対応するAPI Keyを返す
String getMapApiKey() {
  PackageManager pm = getPackageManager();
  try {
    PackageInfo pi = pm.getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
    for (Signature sig : pi.signatures) {
      String key = getMapApiKey(sig);
      if (key != null)
        return key;
    }
  } catch (NameNotFoundException e) {
    e.printStackTrace();
  }
  return null;
}

// 与えられた署名に対応するAPI Keyを返す
static String getMapApiKey(Signature sig) {
  String sigStr = getSignatureFingerPrint(sig);
  
  // デバッグ用署名(debug.keystore)に対応するAPI Key
  if (sigStr.equals("XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX"))
    return "<<デバッグ用署名用のAPI Keyをここに挿入>>";
  
  // リリース用署名に対応するAPI Key
  if (sigStr.equals("XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX"))
    return "<<リリース用署名用のAPI Keyをここに挿入>>";

  // その他の署名とAPI Keyの対応など
  // ...

  return null;
}

// 署名のMD5を文字列形式で返す
static String getSignatureFingerPrint(Signature sig) {
  try {
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(sig.toByteArray());
    return hex(md.digest());
  } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
    return null;
  }
}

// バイト列の16進文字列化
static String hex(byte[] bin) {
  StringBuilder sb = new StringBuilder(bin.length * 3 - 1);
  for (int i = 0; i < bin.length; i++) {
    sb.append(String.format("%02X", bin[i]));
    if (i + 1 < bin.length)
      sb.append(':');
  }
  return sb.toString();
}

ndk-buildを使わないでプログラムをビルドする

普段は、ndk-buildでビルドをしているのが楽だし、便利なんですが、時に、外部のライブラリがconfigureとか使ってて、自前でAndroid.mkとかを作るのが面倒なことがあります。というか、試しに自前で作ってみようとしたけど、新旧の情報が錯綜しており、また、C++を使った場合のリンク方法がさっぱりとか、とりあえず、root化した端末でコマンドラインベースのコードを動かしてみたいけど・・・な場合にどうやれば良いのか全く分かりませんでした。

結局、当たり前ながら、じゃぁ、ndk-buildは何をやってるんでございましょうということになるんですが、これを見てみるために凄く簡単なサンプルを作ってみます。


sample/
jni/
Application.mk
Android.mk
sample.cpp

というディレクトリ構造で、

# Application.mk
APP_ABI := armeabi-v7a

# RTTI、例外を使うためにstatic GNU STLを利用する
APP_STL := gnustl_static
# Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := sample
LOCAL_CFLAGS :=
LOCAL_SRC_FILES += sample.cpp
LOCAL_STATIC_LIBRARIES += gnustl_static

include $(BUILD_EXECUTABLE)
// sample.cpp
#include <iostream>
#include <vector>

int main(int argc, char* argv[])
{
  // 単にSTLが使えているかどうかをチェックしたい
  std::vector<int> v(256);
  std::cout << "Hello, world." << v.size() << std::endl;
}

っていうのを作って、jni/ディレクトリで

ndk-build -n

とやると(ちなみに、/opt/android-ndk-r7にAndroid NDK r7をインストールしている)、

rm -f /somewhere/sample/libs/armeabi/lib*.so /somewhere/sample/libs/armeabi-v7a/lib*.so /somewhere/sample/libs/x86/lib*.so
rm -f /somewhere/sample/libs/armeabi/gdbserver /somewhere/sample/libs/armeabi-v7a/gdbserver /somewhere/sample/libs/x86/gdbserver
rm -f /somewhere/sample/libs/armeabi/gdb.setup /somewhere/sample/libs/armeabi-v7a/gdb.setup /somewhere/sample/libs/x86/gdb.setup
mkdir -p /somewhere/sample/obj/local/armeabi-v7a/objs/helloworld/
echo """Compile++ thumb""  : helloworld <= sample.cpp"
ccache /opt/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-g++ -MMD -MP -MF /somewhere/sample/obj/local/armeabi-v7a/objs/helloworld/sample.o.d -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__  -Wno-psabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fno-exceptions -fno-rtti -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -I/opt/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include -I/opt/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include -I/somewhere/sample/jni -DANDROID  -Wa,--noexecstack -fexceptions -frtti -fexceptions -frtti  -O2 -DNDEBUG -g -fexceptions -frtti  -I/opt/android-ndk-r7/platforms/android-3/arch-arm/usr/include -c  /somewhere/sample/jni/sample.cpp -o /somewhere/sample/obj/local/armeabi-v7a/objs/helloworld/sample.o 
mkdir -p /somewhere/sample/obj/local/armeabi-v7a/
echo "Prebuilt       : libgnustl_static.a <= <NDK>/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/"
cp -f /opt/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/libgnustl_static.a /somewhere/sample/obj/local/armeabi-v7a/libgnustl_static.a
mkdir -p /somewhere/sample/obj/local/armeabi-v7a/
echo "Executable     : helloworld"
/opt/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-g++ -Wl,--gc-sections -Wl,-z,nocopyreloc --sysroot=/opt/android-ndk-r7/platforms/android-3/arch-arm  /somewhere/sample/obj/local/armeabi-v7a/objs/helloworld/sample.o   /somewhere/sample/obj/local/armeabi-v7a/libgnustl_static.a /somewhere/sample/obj/local/armeabi-v7a/libgnustl_static.a /opt/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a    -Wl,--fix-cortex-a8  -Wl,--no-undefined -Wl,-z,noexecstack  -lc -lm -o /somewhere/sample/obj/local/armeabi-v7a/helloworld
echo "Install        : helloworld => libs/armeabi-v7a/helloworld"
mkdir -p /somewhere/sample/libs/armeabi-v7a
install -p /somewhere/sample/obj/local/armeabi-v7a/helloworld /somewhere/sample/libs/armeabi-v7a/helloworld
/opt/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-strip --strip-unneeded  /somewhere/sample/libs/armeabi-v7a/helloworld

という感じのことをやっている事が分かる。

つまり、まとめると、コンパイル、リンク、リンク後処理として、

# コンパイル
/opt/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-g++ \
	-MMD -MP -MF \
	/somewhere/sample/obj/local/armeabi-v7a/objs/helloworld/sample.o.d \
	-fpic \
	-ffunction-sections -funwind-tables -fstack-protector \
	-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__  \
	-Wno-psabi \
	-march=armv7-a -mfloat-abi=softfp -mfpu=vfp \
	-fno-exceptions -fno-rtti \
	-mthumb \
	-Os \
	-fomit-frame-pointer \
	-fno-strict-aliasing \
	-finline-limit=64 \
	-I/opt/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/include \
	-I/opt/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include \
	-I/somewhere/sample/jni \
	-DANDROID \
	-Wa,--noexecstack \
	-O2 -DNDEBUG -g \
	-I/opt/android-ndk-r7/platforms/android-3/arch-arm/usr/include \
	-c  /somewhere/sample/jni/sample.cpp \
	-o /somewhere/sample/obj/local/armeabi-v7a/objs/helloworld/sample.o 
# リンク
/opt/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-g++ \
	-Wl,--gc-sections \
	-Wl,-z,nocopyreloc \
	--sysroot=/opt/android-ndk-r7/platforms/android-3/arch-arm \
	/somewhere/sample/obj/local/armeabi-v7a/objs/helloworld/sample.o \
	/somewhere/sample/obj/local/armeabi-v7a/libgnustl_static.a \
	/opt/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a \
	-Wl,--fix-cortex-a8 \
	-Wl,--no-undefined \
	-Wl,-z,noexecstack \
	-lc -lm \
	-o /somewhere/sample/obj/local/armeabi-v7a/helloworld
# デバッグ情報の除去
/opt/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-strip \
	--strip-unneeded \
	/somewhere/sample/libs/armeabi-v7a/helloworld

ということが分かる(一部、重複など簡略化済み)。
あとは、この辺を配慮した上でconfigure様に、CC/CXX/LD/CFLAGS/LDFLAGSなどを設定してあげれば良い感じみたいだ。