投稿

2010の投稿を表示しています

ラリー共有機能メモ

AWSのSimpleDBが簡単に扱えそうなのでSmartTrainingに組み込んで使ってみよう、と考えてみたのでメモ。 サーバアプリなんて書きたくないんだよね。 めんどい。 なので、可能なかぎりクライアントで何とかする。 以下、仕様案。 作っているうちに思いつきで変わっちゃうかもしれないけど。 ・ラリー登録のタイミングでラリー登録情報をSDBにアップロード。  ・アップする内容   ・Uid:ユーザID(アカウント)   ・Rallyid:ラリーID   ・Uname:ユーザ表示名   ・Distance:距離   ・Timestamp:タイムスタンプ   ・Duration:期間(開始日時とタイムスタンプとの差)  ・UidとRallyidがキー情報的な意味をもつ。 ・SDB設計  ・Domain:Rally(全ラリーのレコードがこのDomainに登録される)  ・Items   ・Uid:Gmail account   ・Rallyid:登録したRallyのID   ・Uname:任意(設定画面で指定)   ・Timestamp:登録したときのシステムタイム   ・Duration:開始日時とTimestampとの差 ・ラリー画面表示  ☆そのラリーに登録しているアカウント総数  ☆そのラリーをクリアしたアカウント数  ×自分の順位表示  ×そのラリーをクリアしたアカウントのリスト(適当にソート)  ・そのラリーをクリアしていないアカウントリスト(条件指定)   ・条件:☆自分の近く、×トップ5  ☆選択したアカウントのラリークリア状況  ☆競争するアカウントを覚えておく。そのアカウントと同時に並べて表示することで競争。  ☆Twitterアカウント名を登録しておき、他のユーザがそのTwitterアカウント情報を閲覧できる。  ・・・ ・懸念事項  ・アカウント偽装   →Googleアカウントによる認証を前提とする。  ・不正な値の登録   →諦める。クリアしたアカウントについては別途扱いにすることで、早くクリアしたことに意味を持たせない。  ・ ・どういう仕様だったら楽しいか?モチベーション維持に効果があるか?  ・スタート時期は一緒ではない。  ・登録インターバルも一緒ではない。   ・距離でソートをかけて自分の周囲を表示。   ・周囲で同じペースの人を

LiveViewの不可思議な動き

SmartTrainingをLiveView対応させるべくごにょごにょやってみました。 丸一日かかってだいたい期待する動きをするようになってきました。 が、ちょっとだけよくわからない動きをする(または、こう動いて欲しいのに期待通り動かない)などあったので雑にまとめてみます。 とりあえず、Sandboxタイプのプラグインの話。 以下のメソッドが動かない。サンプルのSandboxで確認したんだよ? ・LiveViewAdapter.ledControl()  →LEDが光るのかと思ったが光らないよぉ? ・LiveViewAdapter.vibrateControl()  →任意のタイミングでバイブレートさせることができるのかと思ったら振動しないよぉ? ・LiveViewAdapter.screenOnAuto();  →ドキュメントによるとパワーセーブモードをデバイスに任せる的な説明があったが、Sandboxだといつでもスクリーン付きっぱなしだよぉ? ・LiveViewAdapter.screenOn(); ・LiveViewAdapter.screenOff();  →任意のタイミングでスクリーンON/OFFできるのかと思いきや、とりあえず、スクリーンOFFにはならないよぉ?そもそも、Sandboxプラグイン表示中に電源ボタン押してもスクリーンOFFってならなくね?時刻と電池マーク見えとりますよ。 なんかさ、根本的に勘違いしているような気がするけど。 LiveViewの開発者向けのコミュニティ探してみたけど見つからないし。 「【初心者です。教えてください】LiveView APIが動きません」とかいうタイトルでメール投げさせてくれ。 がおー。

IS03とDesire比較

※はじめにお断り。  ここでの比較はベンチマークとしては非常にお粗末です。  計測条件が完全一致ではないので。  あまり深刻に受け取らないこと。  あくまでも参考程度に。 Desireを使って半年、IS03を使って1週間。やっと手に入れたauのAndroid。人情的にIS03がDesireに比べて性能が劣っているなどと考えたくはないわけです。 でも、実際使ってみるとなんかIS03モッサリしている気がする。それが気のせいなのかどうかモヤモヤしたので、比較してみました。 両端末で異なる条件といえば、 1.ハードウェア 2.OS(Froyo vs Eclair) 3.ネットワーク(SB vs au) 4.プリインストールアプリの作りの差 とかとかとか。 4.は例えばデフォルトの電話帳アプリとか電話アプリとかカメラアプリなんかの動作速度。そもそもアプリが違うんだから違ってて当たり前だけど、同じ目的を持っているなら動作速度が速くあって欲しいわけです。 ◆計測条件 インストールしているアプリはプレインストール以外のアプリはなるべく一緒にしとく。 計測前に一度reboot。 ◆計測方法 1.定量的比較  0xBenchを利用して比較。 2.定性的比較  個人的によく使うアプリを使って比較。  特定のアプリ起動または特定の操作を5回程度繰り返してその速度をざっくりと比較。 ◆結果 I:IS03 D:Desire を意味する。 1.定量的比較  ◇結果   圧倒的にDesire速い。   ※数値がデカイ方が速い。   ・Linpack(Mflops)    I:6.01    D:38.5   ・Composite    I:7.06    D:48.7   ・Fast Fourie Transform    I:4.97    D:30.5   ・Jacobi Successive Over-relaxation    I:13.3    D:107.8   ・Monte Carlo integration    I:1.53    D:8.43   ・Sparse matrix multiply    I:6.84    D:38.1   ・dense LU matrix factorization    I:8.67    D:58.7   ・Draw canvas    I:

Galaxy TABで画面に余白ができる

イメージ
何気に作ったアプリをGalaxy TABで動かすとアプリ画面が小さく表示され、画面周りに余白(余黒というのかな)ができることがあります。 なんか悲しい。。。 いまどきのアプリはAndroidManifest.xmlに <uses-sdk android:minSdkVersion="x" /> と書いてあると思いますが、 むかーし、むかしから動いているアプリにはこのタグがなかったり、 あったとしても <uses-sdk android:minSdkVersion="3" /> とかより小さい数字が書いてあると、この余白ができるようです。 最低でも、 <uses-sdk android:minSdkVersion="4" /> 使っといたほうがいいってことですね。 古いデバイスには引導を渡してやるってことで。。。 Excellent!!!

Androidのセンサー型番いろいろ

Androidのログをじーっと眺めていると各種センサーの型番が表示されることがあります。 タグ「SensorManager」で流れてくることが多いみたいです。 ※いや、機種によって全然表示のされ方が違います。確実なのは実機をバラしてチップを見る。ですかね。やんないけど。 収集できたものについてまとめてみます。 こういったセンサーによっても感度とか違うんですかね。 Dev phone 1 AK8976A 3-axis Accelerometer AK8976A 3-axis Magnetic field sensor AK8976A Orientation sensor AK8976A Temperature sensor Nexus One / Desire(X06HT) AK8973 T-01C ADXL345 Accelerometer MS-3C Magnetic Sensor MS-3C Orientation Sensor Galaxy Tab AK8973 Compass Accelerometer_AK Closed registerListener 1:BMA150 delay:xx ※電子コンパスはAK8793、加速度計はBMA150あたりを組み合わせて使っているのだろうか。謎。 HTC Desire HD AK8975 Compass Start AK8975の説明に三軸地磁気センサーとあるから、加速度計はまた別なんだろうか。 加速度計についてはよくわからず。 IS03 じーっと見てみましたが型番を示すログが見えない。 AK系じゃないのか、それとも、全く出していないのか。 不明。 L-04C AMI304 Orientation sensor AMI304 3-axis Magnetic Field sensor AMI304 3-axis Acceleration sensor AMI304 Proximity sensor N-04C(2011/2/24確認) AK8977 Compass AK8977 Accelerator AK8977 Magnetic Field GP2AP012A00 Light GP2AP012A00 Proximity SO-01C(2011/2/24確認) BMA150 Accelerometer AK897

MapActivityとClassNotFoundError

適当に作ったMapActivity継承のActivityを起動すると「ClassNotFoundError」というエラーが出て起動できない。こんなことありませんか? 適当に作るからイケナイのです。 私もその類です。 そんな人は、 Top / 勉強会 / GoogleMap をちゃんと読めばいいのです。 昔読んでちゃんとできたんだけど、すっかり忘れてた。反省。 要はAndroidManifest.xml内に <uses-library android:name="com.google.android.maps"/> の記述をすれば解決します。

skyhookのBulkデータアップロード

イメージ
前回の投稿、「 Skyhook試してみました 」でBulkデータのフォーマットについて問い合わせたけど回答がなかったと書きましたが、その後、回答があり、フォーマットが判明しました。 フォーマットが変更されるかもしれないので、最新版については「support@skyhookwireless.com」に問い合わせてくださいね。 ぴーでぃーえふをぶろぐに貼るには。。。えい!面倒だ!べたっ! Optionalとなっていますが、Building, Room, Floorとかいうデータがあるのは、より意味のある位置特定ができる可能性を示していて興味深いですね。 すみません、仕事が雑で。

万歩計の作り方(Ver.3.0.0)

イメージ
◇SmartTraining 3.0.0 Ver.3.0.0で万歩計ロジックを大幅に変更しました。 ザザっと解説。 ◇どうやって歩数を測るか SmartTrainingにおける万歩計は3次元の加速度データを利用します。 ◎加速度成分合成値の計算 携帯電話は本物の万歩計と違ってどうやって保持されるかわからないので、1次元の加速度だけでは、正確に計測できない可能性があります。このため、3次元の加速度(raw-x,raw-y,raw-z)を合成した値(raw-composit)を求めます。 ◎デジタルフィルタ raw-compositは基本的にセンサーから取得した生のデータです。生のデータには、歩数計算には邪魔な、様々な雑音が含まれます。歩行時の体の回転による加速度、ポケットの中での端末の振動などなど。余分な雑音は取り除いておいた方がより正確な歩数計測が行えるので、デジタルフィルタを適用して不要な成分を取り除きます。 今回は、 IIR によるLPFを作成し0.0030Hzより高い周波数成分を排除しています。デジタルフィルタを適用することでprocessed-compositを計算します。IIRのパラメータはフィルタ職人の腕の見せ所ということでうやむやにします。 ◎歩数のカウント processed-compositは、安静時の重力加速度(G)を中央値として、一定の振幅で振動しています。歩数計では、この加速度の振幅の山と谷を1サイクルとして認識してサイクルを検知することで歩数を数えることにします。サイクルの検知条件は下記のとおりです。 ・山の振幅が一定以上あること。 ・谷の振幅が一定以下あること。 ・山と谷の振幅が一定以上あること。 ・山と谷の時間差が一定時間内であること。 山の後でこれらの条件を満たさない場合、再び山の検知処理を続けます。 こうしてカウントをすると以下のグラフのshakeの値が歩数を表しています。 この方式に変更することで、以前の方式が20%程度の誤差だったのに対して、2%程度の誤差まで性能向上を図ることができました。 ◇注意事項 どんな方式で万歩計を作成するにしろ、計測条件は計測結果に大きく影響を与えます。 今回の方式では、どんな持ち方をしてもある程度計測できるように3次元の合成値を利用していますが、だからといって、端末が回転するような持ち方をするとノイ

Skyhook試してみました。

◇ Skyhook って? Google翻訳によると、 「スカイフックの場所の位置、コンテキストと知能の世界的リーダーです。スカイフックは、今日のWi - Fi測位システムの先駆けと場所を提供します。モバイルデバイスとアプリケーションの数千万します。」 だそうです。ふ~ん。 Android標準のLocationManagerと似たような機能を持つシステム、ということが言えるかと思います。 ◇特徴は? XPSと呼ばれる位置測位の仕組みが特徴です。 XPSはA-GPSとWPSを組み合わせた精度の高い位置測位を提供します。 A-GPSは屋外での精度の高い位置測位に有利です。 WPSはGPSが利用できない屋内・地下でWi-Fi APまたはCell towerの電波により位置測位を可能にします。 詳しくは コチラ 。 また、Tilingという仕組みを利用することによりあらかじめ一定の範囲のWi-Fi APデータベース情報を端末内にダウンロードしておくことで、Skyhookサーバと通信できない状況でも位置測位可能にすることができます。 ◇利用可能なエリアは? ヨーロッパ、アメリカ合衆国、韓国、日本などで 利用可能 です。 日本では、東京、大阪、名古屋とそれらを結ぶ東海道新幹線に沿った地域で利用可能です。 また、「 Submit a Wi-Fi Access Point 」することにより、対応可能地域を増やしてやることが可能です。 GoogleのNetwork Providerによる位置測位の対応エリアがどの程度なのかはよくわかりません。 ◇どうやって使うの? いろいろなプラットフォームをサポートしていますが、ここではAndroid版についてのみ説明します。 1.まず、Skyhook SDKを ダウンロード します。 2.SDKには、ライブラリ、ドキュメント、サンプルが含まれます。 3.自前のプロジェクトにライブラリ(wpsapi.jar)を含めることで利用可能になります。 4.詳しくはサンプル、ドキュメントを参照のこと。 ◇Android標準のLocationManagerとの違いは? LocationManagerもGPS_PROVIDERとNETWORK_PROVIDERを利用することで、XPSと全く同じようなことができます。 それじゃ、Skyhook使う意味ないじゃん、と

サイズの異なる文字列をボタン上に配置する

ヒントは ここ にあったけど、惜しい、XMLからstrings.xmlのリソースを指定したいのにこの方法だとダメ。あと一歩足りない。 というわけでやり方はこちら。 MultiTextViewというカスタムViewを作成します。 仕様的にはmainTextとsubTextを指定可能とし、それぞれ、テキスト、文字サイズ、文字色を指定可能とします。 まずは、XMLから指定可能な拡張attrを定義します。 valuesフォルダ配下にattrs.xmlファイルを配置して中身をこんな感じに。 -attrs.xml 次に、MultiTextButton.javaで実装。 -MultiTextButton.java public class MultiTextButton extends Button { public MultiTextButton(Context context, AttributeSet attrs) { super(context, attrs); initAttribute(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MultiTextButton); CharSequence mt = a.getText(R.styleable.MultiTextButton_mainText); CharSequence st = a.getText(R.styleable.MultiTextButton_subText); if ( mt != null ) mainText = mt.toString(); if ( st != null ) subText = st.toString(); mainTextSize = a.getDimension(R.styleable.MultiTextButton_mainTextSize, 10.0f); subTextSize = a.getDimensi

うちの子Ver.1.1

NewbornクラスにSensorListenerを追加しました。 眠い時はZ軸方向加速度を与えてやると寝ます。 値の絶対値が閾値より小さいと例外発生します。 @Override public void onSensorChanged(SensorEvent event) { // 眠い時のみ発動 if ( this.state == STATE_SLEEPY ) { // 加速度センサー if ( event.sensor.getType() == Sensor.TYPE_ACCELEROMETER ) { // Z軸方向のみ対象です float z = event.values[SensorManager.DATA_Z]; // 閾値を超えないとやり直し if ( Math.abs(z) < THRESHOLD ) { sleepy = 0; throw new HumanException(OUTPUT_CRY); } else { // 一定回数閾値を超え続けると寝ます sleepy++; if ( sleepy > SLEEPY_THRESHOLD ) { setState(STATE_SLEEPED); } } } 結構感度高いです。

うちの子

生後35日目です。 10分で実装したのでちょっと雑な動作をします。 未試験です。 package com.awwa.newborn; import Human; public class Newborn extends Human { public static final int OUTPUT_NO_CRY = 0; public static final int OUTPUT_CRY = 1; public static final int STATE_HUNGRY = 0; public static final int STATE_WET = 1; public static final int STATE_SLEEPY = 2; private int state = STATE_HUNGRY; private int outputState = OUTPUT_CRY; @Override private static void life() { while( true ) { try { switch(state) { case STATE_HUNGRY: throw new HumanException(OUTPUT_CRY); break; case STATE_WET: throw new HumanException(OUTPUT_CRY); break; case STATE_SLEEPY: throw new HumanException(OUTPUT_CRY); break; } Thread.Sleep(10800000); } catch (HumanException ex) { outputState = ex.getMessage(); publishState(outputState); } finally { continue; } } } }

ViewをTranslateして表示する

イメージ
Button01の背後からButton02をスライドアニメーションさせて表示する。 なんでこんなの実装しなきゃいけないんだろう、とか思いつつ。 個人的には趣味じゃないですが、やらなきゃいけない状況だったのでやってみました。 結構ハマりつつ。 ◇完成イメージ こんな感じでButton02がアニメーションする。 → → ◇やり方 「layout.xml」はこんな感じ。 ポイントはButton02を乗せたSlidingPanelクラスをButton01の下に配置します。 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <!-- 前面に表示されているボタン --> <Button android:id="@+id/Button01" android:text="Button01" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <!-- 下にスライドするLayout(初期状態はGONE) --> <com.awwa.animsample2.SlidingPanel android:id="@+id/panel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_below="@id/Button01" android:

EditTextPreferenceを拡張する

EditTextPreferenceをそのまま使いたくないこともあるわけです。 例えば、Preferenceに永続化させるときは文字列を暗号化さたい、とか。 そんな時はEditTextPreferenceをextendsしてonPrepareDialogBuilder()をオーバーライドしちゃえばいいわけです。 こんな感じ。 ※値は"CCC"として保存するけど、EditTextに表示する際には"CCC converted"と表示して、保存するときは再び"CCC"で保存。 これに暗号化と復号化を組み合わせればいいわけですね。 @Override protected void onPrepareDialogBuilder(Builder builder) { super.onPrepareDialogBuilder(builder); // get value from xml file String value = getText(); Log.d(TAG, "value : " + value); // convert value value = value + " converted"; // display converted value this.getEditText().setText(value); // event handler when select ok button builder.setPositiveButton( android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // re-convert value and save to xml setText("CCC

Viewを丸く切り取る

イメージ
Viewを丸く切り取るには、onDraw()をオーバーライドしてclipPath()してあげたクラスを作ってあげればOK。 こんな感じ。 public class ClipImageView extends ImageView { private static final String TAG = "ClipImageView"; public ClipImageView(Context context) { super(context); } public ClipImageView(Context context, AttributeSet attrs) { super(context, attrs); } public ClipImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } private Path pathCircle = new Path(); /** * Viewのサイズ確保 */ protected void onSizeChanged(int w, int h, int oldw, int oldh){ // 丸いパス pathCircle.addCircle(w/2, h/2, 24, Path.Direction.CW); } /** * 描画処理 */ protected void onDraw(Canvas canvas) { // パスに沿って切り取り canvas.clipPath(pathCircle); super.onDraw(canvas); } } あとは、これをLayoutにぺたっと貼り付け。 android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > android:layout_

Android2.1(X06HT/Desire)でハマったこと

SmartTraining 2.2.1にバージョンアップするにあたり、3点ハマりました。 いずれもAndroid2.1側の問題かと思います。 ムカついたのでメモメモ。 1.画面OFF時に加速度変化イベントが取れない。  あちこちで書いていますが、開発者の間では Issue3708 として認識されているAndroid側の不具合という認識の問題です。様々なアプリケーションもこれにより影響を受けており、Smart Alarm ClockやCardioTrainerなどの超有名どころアプリケーションもこの問題を解決できていません。この中の投稿でBrunoさんという方が、問題を回避する方法を提案しています。実際にX06HT(Desire)とNexus Oneで試してみましたが現象が改善されませんでした。やり方が悪いのか、何なのかわかりませんが、Brunoさんの方法を試しても改善されないという報告がいくつか見られたので、この方法は疑わしいと考えています。  Android側を弁護するとしたら、バックグラウンドでセンサーを不用意に扱うアプリケーションがバッテリーを大量消費してしまうことを回避する、という意味ではこの動作変更は成功しているかもしれません。しかし、バックグラウンドでの動作に制限をかけるのであれば、よりバッテリ喰いのGPSにはこういった制限がありません、これでは中途半端でしょう。明らかに旧バージョンからダウングレードしています。  回避方法としては、PowerManagerでSCREEN_DIM_WAKE_LOCK以上に設定します。SCREEN_DIM_WAKE_LOCKというのは、画面の液晶が暗くなっているが、OFFではない状態です。当たり前ですがバッテリかなり喰います。かつ、この状態でポケットに入れたりすると当然誤操作の元となります。SmartTraining的にはこの対応はありえないので、結局「残念なお知らせ」を表示してこの問題がAndroid側の問題であることをアピールするに留めました。 2.画面OFF時にTimerが動作しない(ことがある)。  上記問題と少し似ているのですが、画面OFF時にTimerが動作しません。「しないことがある」としているのには、いくつか条件が必要なためです。こちらで確認している条件としては、以下の条件でTimerが動作しません。 ・画

Google Maps Data APIの謎

SmartTraining 2.0.0のこと。 今回のバージョンアップは初期バージョンリリース以来ずっと実現したかったGoogle Mapsへのデータアップ機能実装がメイン。嬉しかったので自分へのご褒美という意味でメジャーバージョンをあげちゃいましたwバージョン管理なんてそんなもん。 Google Mapsへのデータアップロード、意外に手間取りました。つい最近までずっとMaps関連のAPIは Google Maps API だけだと思っていて、外部アプリからデータのアップロードなんてできないものだと思い込んでいました。 ところが先週、何気に情報探していたら Google Maps Data API なるものを発見。紛らわしー名前だなー。これ発見した時「勝てる!」思いましたよ。楽勝だってね。でもそこからが大変。 まずは、Androidアプリを開発してるわけなので、Javaライブラリを探す。 発見 。おおぉー、サンプルも載ってるし楽勝じゃねーか。と思いつつライブラリダウンロード。ダウンロードしたライブラリには普通のJava環境用のライブラリとandroid用のライブラリが格納されている。普通のJava環境用のものはjacksonやらkxmlやらcommons-loggingやらいろいろと依存ライブラリがあるらしく、Android上でそのまま動かすのはちょっとつらい。 そこでAndroid用ライブラリをためす。早速ライブラリを組み込み実験用アプリを作りマップのリストを取得してみる。が、なんかおかしい。Webサイト上のサンプルをそのまま書いてみてもEclipse上では赤い下線が出る。 「そんなメソッドねぇ」だと。そこでダウンロードしたJavaDocs見ると、Webサイト上のサンプルで使ってるメソッドなんてありません。Maps関連のクラスを見てもAUTH_TOKEN_TYPEとVERSIONのstaticなフィールドが定義されているだけ。んー、なんだこりゃ。ライブラリのソースをダウンロードしてみるがJavaDocs通りフィールドが2個定義されているだけ。。。オイw未実装かよwさんざん探したけどサンプルもありません。 一晩寝てわかりました。Webサイト上のサンプルはv1.4用のっぽいんですね。この当時のライブラリにAndroid版はない。ダウンロードしたのはv2.1。どおりでダ

HT-03AとXperiaの比較~加速度センサー&GPS編

イメージ
HT-03AとXperiaでSmartTrainingを動かして加速度センサーとGPSの計測結果を比較してみました。 ◆計測方法  ・2端末を縦向きにして同じ胸ポケットに入れる。  ・実測約1000歩の区間を普通の速度で歩く。 ◆結果 ↑Xperia画面 ↑HT-03A画面 ・Xperia  歩数:1178歩  距離:963m ・HT-03A  歩数:944歩  距離:921m 歩数が1000歩から±10%~20%誤差があります。 それぞれのセンサーの特性による違いなのか、それとも、端末自体の重量によりセンサーが受け取る衝撃の強さが違うのか、ちょっとよくわかりませんが、端末によってこの程度の誤差は付き物なのかもしれません。 距離も5%程度違っています。 これは、30秒おきに計測しているGPSのロケーション情報が取れるタイミングが微妙に異なるのが原因で、地図上の軌跡が異なっていることが原因です。 カロリーと継続時間が微妙に異なっているのは、計測停止時に同時に2端末をストップさせることができずに、もたもたしていたせいです。カロリーは継続時間に依存するのでここで端末の違いによる誤差がでることはありません。 ↑Xperia画面 ↑HT-03A画面 GPSから取得した時間-高度グラフをみても結構違いますね。 API経由で取れちゃうんだからアプリとしてはどうしようもないのですが、いろいろと内部での補正の方法が違ったりするのかな? いずれにしても精度としては数十mがいいところといった感じでしょうか。 ---- その後、同じコースでもう一度計測してみました。 今回は朝出勤の時に測ったので、ちょっとだけ急ぎ足なのかもしれませんね。 やっぱり、Xperiaの方が多くカウントされます。 同じような傾向がでました。 ・Xperia  継続時間:09:28  歩数:1120歩  距離:930m  カロリー:104kcal ・HT-03A  継続時間:9:22  歩数:926歩  距離:808m  カロリー:103kcal

SmartTraining 1.9.0 リリース

先日リリースしたSmartTraining1.9.0のこと。  今回のバージョンアップは、以前Andronaviさんで 紹介 していただいた時に低かった評価の改善、Marketでいただいたコメントに対する対応を行ってみました。  歩数については、あの当時から万歩計ロジックを2度修正して多少はマシになっていると思います。一応、個人的な計測では悪くても2割程度の誤差。ロジックについてはさらに見直して精度アップの余地はあると思っています。ただ、なかなか試験に時間がかかるので、引き続き実験と計測を繰り返しつつ徐々に改善していこうかと思っています。  一時停止中の距離カウントを止める機能は、途中でトレーニング種別を変える機能と絡めてみました。例えば、将来的にはトライアスロンや、スキーでの滑走&リフトなど、途中で実施する運動が変化するケースでも計測の継続を容易にすることを想定しています。現実的には今のハードウェアが耐水的にも耐寒冷的にも弱いのでこの機能が真価を発揮するのはまだまだ先のことになりそうです。あと、本当は人が操作しなくても自動的に状況を認識して記録してくれるというのが理想ですが、こちらはもう少し研究が必要ですね。  Twitterにつぶやく機能は1.8.5で適当に実装(といっても他アプリに送るだけですが)してみたのをもう少し拡張してみました。っていうか、誰もハッシュタグ使ってつぶやいてくれないので消そうかと思いましたがwちょっとだけ悪あがき。  最後は、ContentProviderによるデータの公開。どうやって公開するのが一般的なのかわからなかったので、 サポートサイト に利用側コードを貼ってあります。マッシュアップで運動の計測にはこのアプリを活用していただけるととても嬉しいです。データアクセス手段の公開と外部へのエクスポートによるアプリマッシュアップはAndroidならではの機能ではないかなと思っています。  あと、おまけ。機能的には地味なのでどこにもコメントありませんが、設定画面で使っているトレーニングタイプの選択時に表示しているリストダイアログ。以前は標準のListPreferenceを使っていたのですが、結構殺風景だったので、リスト上にアイコンを表示するように機能拡張してみました。 やり方は、DialogPreferenceを継承したオリジナルのクラスを作成

万歩計文化の謎

SmartTraining1.7.xでおかしかった万歩計の感度を修正するまでいろいろとコメントを頂きました。 その際、日本語圏とそれ以外の国での万歩計の地位が微妙に違うような気がしました。 これまで、ずっと日本語圏の方からのコメントは凄く少なかったんです。 逆にそれ以外の国(英語しか理解できませんが)からはいろんな意味で非常にアツいコメントをたくさんいただいていました。 1.7.xのリリース後は、逆に日本語圏の方からのコメントをたくさんいただきました。主に万歩計の感度に関して。英語圏の方からはそれほどコメントは頂きませんでした。 ひょっとして、万歩計って日本だけ? ちょっと謎です。 さて、今週末は志賀スタンプラリー、レッツリトライです。

万歩計ロジック

ここ何週間か、歩きまくりました。 万歩計の加速度データ取るために。 デバッグより何よりこれが時間かかりました。 ようやくSmartTraining 1.8.0リリースしました。 結局、現時点での歩数の測り方はこうなってます。 ①XYZ方向の加速度の絶対値を合計します。  →端末がどの角度でセットされるかわからないため。 ②前後5つの生データ(①)の平均をとって高周波成分をフィルタします。  →意外とこれは不要だったかも、と後になって思いました。歩く、走るだとそんなに悪影響を及ぼす高周波成分は多くない。 ③①から②を引いてハイパスフィルタかまします。 ④③で出た加速度を微分して加速度値の山を見つけます。また、山の値を確保Xします。山が来るたび、Xを確保しなおします。 ⑤加速度の山が来るたび、Xで割って正規化します。  →これにより運動強度が途中で変化しても固定の感度値に頼らず万歩計が追従できるようにします。  →今回のバージョンから万歩計感度が無くなったのはこのためです。  →ただし、急激な運動強度変化直後は反応できません。そんなの気にしない。 ⑥⑤の値が一定の割合以上であれば、振動とみなして歩数カウントします。  →歩数カウント後、一定時間不感タイムを設けます。   これにより加速度の山前後の微妙なブレの影響を回避します。 コードはまだまだ汚いので出すとしても整理して落ち着いてからかなぁ。 それにしても加速度の扱いは微妙すぎて自分には難しい。 もっとスキルある人だったら楽勝なんでしょうねぇ。 誰かもっといい方法教えてください。

スキーでも使ってみた

イメージ
スタンプラリー攻めてきました。 思ったよりちゃんととれてました。 スキーのカロリーは計算できないけど。 あと歩数も意味ないな。 標高2000mは白樺とダケカンバの混在する標高らしい(観光バスのおじさん情報)。 ま、どうでもいいけど。

auラインナップへのスマートフォン導入とAndroidスマートフォン向け...

実はもう4月に顧客(1回線)流出決定してましたが、このニュースで「お、どうすっかな」状態になりました。 auラインナップへのスマートフォン導入とAndroidスマートフォン向けアプリマーケットの提供について X10発売前にスペック発表してくれたら顧客流出するか考えます。 できればXPeria miniでお願いします! たぶんminiだったら流出しません!

晒し

イメージ
マイHT-03Aのメニュー晒し。 アイコン数で112か。 実験アプリ作るたびにわんさか増えていくのがダるいな。 フォルダ作ってほうりこんでおきたい 公序良俗に反するものにはモザイクかけてます。 特にお気に入りは ・渋滞状況 ・日本のお天気レーダー ・XGalaga ・QRコードスキャナ ・RemoteDroid ・Mind Map Memo ・Twicca ・AndExplorer あたりかな。

Webってむず

コードをきれいに表示してくれるらしい。 でもさ、サッパリ使い方がわからん。 一応、それっぽく出たけど、なんで1行おきに背景色が違わないの? むずーい。 最近の技術にはついていけないのぅ。 public class HelloWorld public static void main(String[] args) { System.out.println("Hello World"); } } おじさんのWebページの更新技術は、 vi→Emacs→秀丸 で止まっているのだ。 WebブラウザでWebページ更新すると意味分かんなくなるぞ。

NyARToolkit for Android事始め2

イメージ
昨日、重要なことをすっ飛ばしてました。 眠くて。 これじゃ、事始めになってない。 「JAG」カメラで写さなきゃダメじゃん! ってことで、早速やってみました。 おおお、椅子キター! ちなみに、「JAG」はじゃがポックルのJAG。 でもじゃがポックルじゃ椅子は見えないらしい。 明日は会社休もう。 いや、休んで勉強しよう。

コードからわかるAndroidプログラミングのしくみ

コードからわかるAndroidプログラミングのしくみ 読んでます。仕事もせずに。いや、これが仕事だ。 これまで何冊か他の入門書読んできましたが、入門書にはない一歩踏み込んだ記述が目から鱗が落ちることしばしば。 IntentFilterの仕組みとか、データの永続化に関する複数ある手段の違い、java.netとapache HttpClientの違いみたいなことが詳しく載っています。これは手放せない。 あと、以前読んだのでは、 Google Androidプログラミング入門 も入門書とは思えない範囲の広さとポイントを押さえた掘り下げもいい感じ。これも手放せない。

NyARToolkit事始め

イメージ
いろんな意味でチャレンジです。 NyARToolkit Android 1 NyARToolkit Android 2 何はともあれ環境を整えましょうってことで、 ・NyARToolkitのソースをダウンロード。  いきなりビルドができない。  android.jarへの参照設定がうまくいってなかったらしくテケテケっと(オリンピック見ながら2時間ほどなやんだけど)修正してビルド成功! ・JMFをインストール。 ・Webカメラを購入。(げ、実機持ってたらいらなかったりした?もう遅い) ・WebcamBroadcasterを起動!  動かん。 ・↓にJMFインストール前にWebカメラをインストールしておく必要があるとかなんとか。   JMFインストール(WindowsXP)   ・というわけで、Webカメラぶっ刺した状態でJMFを再インストール。 ・再びWebcamBroadcasterを起動!  って、suitable playerがないとかなんだとかで動かん。 ・↓にYUV Formatのカメラだとダメだよ~って。  ぐふっ。   Live camera preview in the Android emulator ・しょうがないので、WebcamBroadcaster.javaを修正。  YUVとかサッパリ意味分かりませんが、こんなのをごちゃごちゃっと追加。 } else if ((format instanceof YUVFormat)) {   YUVFormat yuv = (YUVFormat) format;   Dimension size = yuv.getSize();   if (size.width != width || size.height != height) continue;     MediaLocator locator = info.getLocator();     source = Manager.createDataSource(locator);     source.connect();     System.out.println("YUV Format Found");     ((CaptureDevice)source).getFormatControls()[0].setFormat

Xperia X10 mini

Xperia mini発表されましたね! やっぱこうじゃなきゃ、ソニエリ。 ソニエリ Xperia X10 mini &mini pro 発表、カードサイズAndroid携帯 今すぐauから出してくれたら機種変更します。 ドコモから出たらわかりません。 万歩計に最適なサイズですな。 そして防水処理されていたら、 ドーバー海峡泳いだ記録とか取れるのに。 F社くらいか、そんなの出すの。

だからなにさ

イメージ
QRコード作ってみました。 だから何さw http://chart.apis.google.com/chart?chs=150x150&cht=qr&chl=http%3A%2F%2Fawwa500.blogspot.com%2F

Gadget1いってきました

2/6 オラクル青山センター 行ってきましたGadget1。 Android関連で何か面白いものないかな、とか思って軽いノリで参加してみましたが、予想外に別次元の面白さに感激しました。 プログラム内容はこちらを見ていただくとして、 http://gadget1.jus.or.jp/ 個人的に非常に興味深かったのが、 ・オシロスコープではちゅねミクの絵を描いたぱお製作所さん ・CEREVOさんのCEREVO CAM ・2ちゃんの祭りを知らせる「赤色灯 for 2ちゃんねる」 ・チームラボのバルーンでライブ会場を演出するヤツ ・SDカード型Wi-FiのEye-Fi などなど。 あと、あんじょうさんのプレゼンはいつもながら楽しい。 特にぱおさん、質問に対する回答の切れ味が凄まじい。 濃いです。いや、雰囲気は全然その凄さを感じさせず、極めてゆるいんですが。 ゆるい雰囲気とは裏腹に様々な角度からの試行錯誤と考察と実験がなされていて会場からもどよめきと拍手が。 普段、ソフトのことばかりやってるので、ハードのことってあまり意識していないんですが、やっぱりハードも重要ですよね。 ここの所、スマートフォンがらみのことを中心にやっていますが、もっと広い視野をもたねば。 発想の転換次第でいろいろな見せ方ができるし、幅の広いモノが作れる、そんな気分になりました。 ジャパニーズモダンネットガジェットいいですね。 Nexus Oneもちょこっと触らせてもらえました。 さすがCPUが1GHzもあるとスカスカに速い。 残念ながらネットワークは接続できませんでしたが。 また次回も参加したいです。 やるのかな?やってほしい。

ActivityによらないKeyEventの取得

いくつか質問投げてみたけどまるで反応なし。 やっぱ難しいのかなぁ。 Androidならできると思ったんだけどなぁ。 BroadcastReceiverの拡張次第かな。

今度はBBか?

今度はBlackBerryやるらしい。 やったことないからわからんもーん。 DBは使えんわ、カメラも制御できんわ、何やらやっかいそう。 OS 5.0.0以降なら使えるらしい。 これでもワールドワイドじゃ売れてるってんだから、 プッシュメールのない世界のことは理解不能だのう。 やっぱ日本って特殊なんだな。少なくとも今は。 そのうち飲み込まれると面白いんだけど。

うれしいこと

最近、パラパラとSmartTrainingにコメントいただいています。 意図したことが気に入ってもらえているようで、うれしいものです。 あちらこちらで紹介されたり評価されたりと、ちとドキドキものですが、 作ったものの率直なご意見、感想をいただけるというのは興味深い経験です。 根がテキトーなので、難しいことはすぐに諦めるので、作りが粗い部分はありますが、 ネタはまだまだあります。 いや、基本機能をもっと揃えろって話もありますが。

カメラプレビュー

AR的な調べごと。 まずは基本のカメラプレビュー。 っておい、portrait対応してないの? http://groups.google.co.jp/group/android-developers/browse_thread/thread/e61ec1e8d88ea94d/ab3ff10fca1a930e?lnk=gst&q=PendingIntent+problem#ab3ff10fca1a930e draw()で回転させろだと?マンドクセー。 センサーと組み合わせるとやっかいそう。 http://d.hatena.ne.jp/yzk4/20090919/1253382550 こうやってみるとLayerって地味なところで苦労してるんだなぁ。

地味にバージョンアップ1.6.2

Ver.1.6.2アップしました。 GPSをOFFにしていると、GPS電源ONにせよ!ということで設定画面が開いちゃうのだとか。 直したもーん。ってコメント寄せてくださった方、こんな感じの修正でよかったですか?私、コメントの意味取り違えてないですか? Android Marketのコメントって、なんか作者が返信に使っちゃいけないような気がするのは私だけですか? コメント直接書き込んでもいいけど、、、皆さまからのコメントに対して無視してるように見えなくもない。うーん。 他の方どうしてるんだろ。 んで、1.6.x以降、目標設定できるようになってます(画面レイアウトがほとんど変わっていないので、気付きにくいかもしれませんが)一応ヘルプに載せてあります(つーか、安藤さんのブラウザからこのヘルプ見づら)。 計測制御画面で「継続時間」とかの行を選択すると目標設定のためのダイアログが開きます。 個人的には、カロリーの目標設定ダイアログのアイコンがお気に入り。 「かわいい感じでヨロ。」の発注でPipanがサクッと作ってくれました。 マインスイーパしかできないくせによく頑張った。

久々にSmartTrainingアップデート

久々にSmartTrainingアップデートしました。 Ver.1.5.0です。 今回は、、、苦労しました。 年末年始の時間を使ってアップデートできるかと思ったら、実家の挨拶回りで終わってしまうし。。。 それは置いといて。 画面を消しても計測を継続する。 サービス使えばかんたーんじゃーんとか思ってましたが、当初そんなことは微妙に30%くらいしか意識した設計になっていなかったため、やり出したらあちらこちらでうまく動かないことが判明しました。データの持ち方とか、画面が落ちている間に起きた出来事の整理とか。 なので、結局内部構造はほぼ全て作り直し。見た目は全く変わっていないのが悲しいですが。 ついでに前から実験していた地図のヘッドアップ機能も突っ込んでみました。 本当は、ヘッドアップ中でも地図をスクロールさせたかったのだけど、地図が回転すると画面上のスクロール方向とずれが生じるのでsinだのcosだの使って回転計算して云々。。。 ま、結局スクロールの回転方向はある程度うまく補正できるようになったんだけど、スクロールする指を離した後の惰性で動くスクロールがどうしてもうまく補正できず断念。 せっかくなので、Android-Users-Groupにでも質問してみようかな。 でも、個人的にはナビはノースアップ派です。 そしてGPSの電源制御。 LocationManagerにリスナ登録する際に最低限更新情報を受け取る更新間隔を指定できるんですが(requestLocationUpdates()のminTimeですね)、どんな値を指定してもうまくいくってわけじゃないんですね。あまりに長い時間を指定するとどうしてもうまく情報がとれず。 予想としては、 ・minTimeに長い時間間隔を設定する。 ・計測のためGPS電源をONにする。 ・実際に位置情報が取れるまでタイムラグがある(衛星電波をつかむまで) ・タイムラグ中にOS側が次の計測のためGPS電源をOFFにする。 ・しばらく時間経過後GPS電源がONされる。 ・実際に位置情報が取れるまでタイムラグがある(衛星電波をつかむまで) ・タイムラグ中にOS側が次の計測のためGPS電源をOFFにする。 ・・・ というわけで延々位置情報がとれていないのではないかと。 結局、位置情報とれたら自分でGPSリスナ登録解除して一定時間後に再登録するよう