Windows 8 で Android Beam を受信する
nasne + Xperia acro HD (IS12S)
こっちについても書いておかねばなるまい。
発売延期になったのに、Amazon予約組だったので一度届いてしまったが、HDD不良で動作せず、交換処理で、昨日、やっと届いたnasne。
しかしながら、うちには、PS3/torneはありませんし、Sony Tablet Sは誰かさんのところにドナドナ状態なのでやっぱりありません。BRAVIAは寝室にありますが、奥様が就寝中なので、そこでテストするわけにもいきませぬ。
ということで、手元のXperia acro HD(IS12S)、ICSにアップデート済みでのテスト。
チャントル経由での録画はちゃんと動きます。まぁ、当たり前なんですけど。
Connected Devicesで、nasneを選択すると、ライブチューナでちゃんとリアルタイム視聴できます(本当は、30秒程度遅延がある)。
それで、じゃぁ、地デジのスクリーンショットが採れるのか?っていうことはなく、ちゃんと地デジのレイヤーはOSによってキャプチャ禁止に設定されています。
これじゃちゃんと動いているのかわからないでしょうから、カメラで撮影した地デジライブチューナの動作の様子:
ちなみに、動画を選択してから再生が始まるまでは、15秒ぐらい待たされる感じです。
Smart Wireless Headset pro
ソニエリというか、SonyのSmart Wireless Headset proをExpansysで購入した。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)とかは聴けないのでどうでも良い。
パッケージ
音はドイツのwww.testfactory.deっていうところでテストされていて、Sound Quality: excellentなんだそうだ。ふーん。
で、英国仕様なので、ACアダプタがでかい奴なんですが、Expansysで買ったので、Expansysが英国仕様のアダプタを変換するプラグと、USB ACアダプタをオマケで付けてくれました。
付属品
ACアダプター、microSD 2GB、microSDカードリーダー、ヘッドフォン、クリップ、イヤーピース(予備、サイズ違い)、USB A -> micro A変換ケーブル。
本体
"Smart Wireless Headset pro User guide"には、ペアリングすると時計が表示されるとありますが、実際には、一度、Smart Wireless Headset pro側の電源を切って、再接続しないと、時計が出てきませんでした。最初、ペアリングの仕方がAndroid Phone用と、普通のPhone用の両方書かれていたので、時計が出ないのはペアリングがおかしいんだと思って、何度もリセットしたりしながら試行錯誤しました。
見て分かるとおり、文字化けしまくりです。これは、今後、日本語版が正式に発売開始された頃にファームウェアアップグレードがあるのか、それともこのまんまなのかは興味深いところです。
蓋
全体的にグロッシーブラックっていう感じではあるんですが、先っちょの色が変わっている部分は、帯で繋がっておりパカッと開きます。帯が一体成形じゃないので、強度的にはどうなんでしょうかとは思いますが、ここの中に、microSDスロットと、USB接続用のmicro USB Aコネクタがあります。
で、このUSBコネクタは、充電専用ではなく、microSDが刺さっていると、PC接続時にはマスストレージにもなります。
うれしいことに、充電中でも本体は動作するので、電池が足りなくなってきても、充電しながら音楽を聴くことは一応出来ます。そんなことをする必要があるシチュエーションは少ないでしょうが・・・。
ソフト面
ペアリング端末の表示
再生中楽曲の情報
<<後からいろいろ分かったので大幅に修正>>
Xperia acro HD(IS12S)に標準で入っている音楽プレイヤーとの連携では、アーティスト名、曲名共に、マルチバイト系の文字が一部というかほとんど表示できないことを除けば、表示できるようになりました。
ちなみに、これは、「松たか子」、「a piece of life」と表示されているところです。
ただし、僕はPlayerProという音楽プレイヤーを使っているのですが、これだと曲の情報は何にも表示できません。
また、試してみたところ、Galaxy Note SC-05Dでも、標準の音楽プレイヤーと連携できました。
AVRCP1.3? on Android
<<僕の勘違いで、標準プレイヤーでは一般的にAndroidの制限にかかわらず文字情報が表示されるそうです。教えてくれた人有り難うございます。>>
で、Xperiaじゃない機種に接続してみて分かったことですが、この連携にLiveWireマネージャは必須ではないようです。つまり、素のAndroidにそのままBluetoothで接続すれば曲名が出てきます。今まで、曲名表示は、ICSにならないと無理的にAVRCP1.3対応できないから無理っていう話だったのに、一体どんなテクノロジーを使っているのかさっぱり分かりません。
マルチポイント対応
すばらしいのが、二つのデバイスとペアリングして、好きなときに再生するデバイスを自由に切り替えることが出来ること。[|<<]、[>>|]で簡単に切り替えられるのは予想以上に便利です。
結論
音質に関しては、僕はそんなにこだわりがないので何ともな部分があるんですが、機能面、操作性どれをとっても、MW600引退確定っていう感じです。
これは日本で発売されたら、おそらくベストバイになるんではなかろうかというクオリティです。
その他
Expansysがオマケで付けてくれたUSB ACアダプターは、付属のUSB A -> micro A変換ケーブルに接続すれば使えます。
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の署名がデバッグ用とリリース用で違うから問題なわけで、それを検出して、対応する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などを設定してあげれば良い感じみたいだ。